cache.php
来自「视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.」· PHP 代码 · 共 338 行
PHP
338 行
<?php//// +----------------------------------------------------------------------+// | PHP Version 4 |// +----------------------------------------------------------------------+// | Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003 The PHP Group |// +----------------------------------------------------------------------+// | This source file is subject to version 2.02 of the PHP license, |// | that is bundled with this package in the file LICENSE, and is |// | available at through the world-wide-web at |// | http://www.php.net/license/2_02.txt. |// | If you did not receive a copy of the PHP license and are unable to |// | obtain it through the world-wide-web, please send a note to |// | license@php.net so we can mail you a copy immediately. |// +----------------------------------------------------------------------+// | Authors: Wolfram Kriesing <wolfram@kriesing.de> |// +----------------------------------------------------------------------+// $Id: Cache.php,v 1.8 2003/03/04 18:52:33 cain Exp $//require_once 'HTML/Template/Xipe/XMLConfig.php';/*** this class does the caching of final pages in pure html (or anything you use it for)* ok first an apology to the PEAR::Cache-team :-) i tried to* use the PEAR::Cache and it worked fine (was easy to implement) until i got to the* point that i wanted to include the cached content,* since the philosophy of this template engine is still based* on including either the template or the cached output.* the PEAR::Cache has a wonderful Cache implementation but* what i need here is the final file and there are 2 things that* make it impossible (or would need a change in the concept of this template engine) to* use the PEAR::Cache* 1. PEAR::Cache saves the file encoded and adds extra stuff in the file not only* the actual result, the html page in the normal case* it always has the expiration data and extra user data saved in the* cached file, and additionally the real data are encoded either bbase64* or serialized, which means a simple include of the cached file is not possible* i would have to decode it first etc.* 2. PEAR::Cache doesnt provide a method to give back the full path and filename of the* cached file, it does always only return the content of it* which of course is right for the way PEAR::Cache works, since the* data have to be decoded* so i have to implement the caching my self :-/** to use the cache u have to set the option 'enable-Cache' to true* when making an instance of the template engine* and in the file that shall be cached do the following* (assuming $tpl is an instance of the template engine with the cache option on):** // before calling '$tpl->isCached()' be sure that all the variables* // that the cache-file depends on (see your xml config) are set to the proper values* // so the cahe methods can properly determine if the file is already cached* // BE WARNED: letting a cache-file depend on i.e. $_REQUEST makes it possible to* // run a DOS-attack, since a new cache file has to be created everytime any* // request parameter changes, i.e. http://your.site.com/index.php?whatever* // this might flood your webservers diskspace* $myTplFile = 'your/template/file.tpl';* if( !$tpl->isCached( $myTplFile ) )* {* do all the stuff needed to be done to build a cacheable page* all the time consuming stuff, like db-requests, or getting data* using a webservice (which was my actual need for caching)* }* // simply include the file as usual* $tpl->compile( $myTplFile );* include( $tpl->getCompiledTemplate() );*** @package HTML_Template_Xipe* @author Wolfram Kriesing <wolfram@kriesing.de>*/class HTML_Template_Xipe_Cache extends HTML_Template_Xipe_XMLConfig{ /** * @var string the complete filename including path to the cached file */ var $_cachedFile = ''; /** * @var string the global object reference name */ var $_cacheObjReference = ''; /** * this can be set to true using forceRecache() * and it will rebuild the cached file, no matter if it is already cached * @see forceRecache() */ var $_forceRecache = false; /** * checks if the file is cached * * @access public * @version 02/05/26 * @author Wolfram Kriesing <wolfram@kriesing.de> * @return boolean returns true if the output is cached, false otherwise */ function isCached() { if ($this->getOption('cache','time')===false) { return false; } // lets make sure that we define the object reference globally, which is called // from within the template // if we wouldnt do this here we would have a problem if a compiled template // would be included but the reference to $this is not defined, which is needed to call _cacheEnd() // at the end of the template $this->_createCacheObjRef(); // check the forceRecache after creating the cacheObjRef, so the // template can access it if ($this->_forceRecache) { // if _forceRecache is true we say the file is not cached return false; } $cacheFile = $this->_getCacheFileName(); if (!file_exists($cacheFile)) { // if the cached file doesnt exist $this->_log('CACHE: cached file doenst exist: '.$cacheFile); return false; } // has the cached file expired? // the filetime is the time when it expires, this way we dont have to save the // caching time anywhere if (time()>filemtime($cacheFile)) { // if the caching time is 0 it shall be cached forever, so set the expire time to one year ahead // again if ($this->getOption('cache','time')===0) { touch( $cacheFile , time()+60*60*24*365 ); return true; } $this->_log('CACHE: cached file has expired: '.$cacheFile); return false; } // if the template needs a recompile we dont cache if ($this->_needsRecompile()) { $this->_log('CACHE: template needs recompile'); // remove the cached file so we know that we will recreate it // i am doing this because getCompiledTemplate() would return the old cached filename // also if the tpl was recompiled, because after compilation, needsRecompile is false and the cached file // does also exists, only that the expiration time might have changed, which getCompileTemplate, which calls // isCached, has no chance to notice @unlink($cacheFile); return false; } return true; } /** * tell the engine to rebuild the cached file * * @access public * @version 03/03/04 * @author Wolfram Kriesing <wolfram@kriesing.de> */ function forceRecache() { $this->_forceRecache = true; } /** * get the filename of the destination file * * @access public * @version 02/05/26 * @author Wolfram Kriesing <wolfram@kriesing.de> * @return string returns the complete filename */ function _getCacheFileName() { if ($this->_cachedFile) { return $this->_cachedFile; } // add the hash which is calculated over the dependency data, like $_REQUEST, to have a unique filename // for the different dependency data $extension = ''; if (($depends = $this->getOption('cache','depends'))) {//print $depends; $depends = explode(' ',$depends); // init $vars with the names that shall be cached, to be sure that if the values dont change but the names // we have to create a new name $vars = $depends; foreach ($depends as $aDepend) { // if the variable name is like $var['varName'] do only globalize '$var' // even though things like _REQUEST,_SESSION, etc. dont need to be globalized - but it does no harm either // and if it is a $class-> globalize only $class $globalize = preg_replace('/\[.*\]/','',$aDepend); $globalize = preg_replace('/->.*/','',$globalize); // serilaize the var since it might also be an array or object, or whatever//print("global $globalize;\$var = serialize($aDepend);<br>"); eval("global $globalize;\$var = serialize($aDepend);");//print("$aDepend = $var<br>");//print $this->_templateFile." ... $var<br>"; $vars = md5("$vars:$var"); } $extension = md5($vars).'.'; }//print "extension=$extension<br>depends = ";print_r($depends); $cacheFileName = $this->_compiledFilePrefix.$extension.$this->getOption('cacheFileExtension'); $this->_cachedFile = $cacheFileName; return $this->_cachedFile; } /** * this is called from within the template to write the content that shall be cached * * @access public * @version 02/05/26 * @author Wolfram Kriesing <wolfram@kriesing.de> */ function _cacheEnd() { $content = ob_get_contents(); // get the destination filename $file = $this->_getCacheFileName();//print '_cacheEnd write into: '.$file.' <br><br>'; if (file_exists($file)) { unlink($file); } if (($cfp = fopen( $file , 'w' ))) { if ($this->getOption('debug')>0) { fwrite($cfp,'CACHED CONTENT<br>'.$content); } else { fwrite($cfp,$content); } fclose($cfp); chmod($file,0777); } // set file modification time to the time when it expires, // this saves us the checking of the config data, either in options array or the xml file $expires = time()+$this->getOption('cache','time'); if ($this->getOption('cache','time')===0) { // if the caching time is 0 set it to one year ahead $expires = time()+60*60*24*365; } touch($file,$expires); $this->_log('CACHE: caching file for '.$this->getOption('cache','time').' seconds (0 means forever), until: '. date( 'd.m.Y H:i:s' , $expires )); ob_end_flush(); } /** * this adds the calls to the template needed for caching this file * it is used as a filter by the parse method * * @see parse() * @access private * @version 02/05/26 * @author Wolfram Kriesing <wolfram@kriesing.de> * @param string the actual file content * @return string the modified file content */ function _makeCacheable( $input ) { $input = sprintf( '<'.'?php ob_start() ?'.'>%s<'.'?php $%s->_cacheEnd() ?'.'>' , $input , $this->_createCacheObjRef() ); return $input; } /** * * * @access private * @version 02/05/26 * @author Wolfram Kriesing <wolfram@kriesing.de> * @return string the name of the global object ref */ function _createCacheObjRef() { if ($this->_cacheObjReference) { return $this->_cacheObjReference; } // create global (!) object which can be called from within the template file // to call the cacheStart/cacheEnd-methods $this->_cacheObjReference = '_'.md5($this->_templateFile.'cache'); // has to start with a valid character for a varibale name, '_' // its a reference to this instance, so we can simply call the cache methods // we need to do it like this since we dont know the instance name of the template // engine and of this special instance neither, that's the easiest way to do it $GLOBALS[$this->_cacheObjReference] = &$this;//print "_createCacheObjRef = {$this->_cacheObjReference} for {$this->_templateFile}<br>"; return $this->_cacheObjReference; } // // overwritten methods // /** * return the cached file name if it is set, and it is only * set if the file is cached and valid, that means not expired etc. * * @access public * @version 02/05/26 * @author Wolfram Kriesing <wolfram@kriesing.de> * @return string the filename used to include */ function getCompiledTemplate() { if ($this->isCached()) { return $this->_cachedFile; } return parent::getCompiledTemplate(); } /** * do only really compile if the file is not cached * * @access public * @version 02/05/26 * @author Wolfram Kriesing <wolfram@kriesing.de> * @return boolean actually always true */ function compile() { if ($this->isCached()) { return true; } return parent::compile(); }}?>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?