Application\Common\Conf\config.php
<?php return array( ‘HTML_CACHE_ON‘ => true, // 开启静态缓存 ‘HTML_CACHE_TIME‘ => 600, // 全局静态缓存有效期(秒) ‘HTML_FILE_SUFFIX‘ => ‘.shtml‘, // 设置静态缓存文件后缀 ‘HTML_CACHE_RULES‘ => array(// 定义静态缓存规则 // ‘静态地址‘ => array(‘静态规则‘, ‘有效期‘, ‘附加规则‘),// 定义格式1 数组方式 // ‘静态地址‘ => ‘静态规则‘,// 定义格式2 字符串方式 ‘*‘ => array(‘{$_SERVER.REQUEST_URI|md5}‘, 600) ), );
以上配置程序就会执行静态缓存了
程序会创建一个文件夹(Linux下记得注意要可写权限)Application\Html
下面就看下源码分析下
thinkphp默认启动了此行为扩展
ThinkPHP\Conf\Mode\common.php
‘app_begin‘=> array( ‘Behavior\ReadHtmlCache‘, // 读取静态缓存 ),
当执行app_begin这个动作时
程序会自动运行ReadHtmlCache 的 run 方法
ThinkPHP\Library\Think\App.class.php
// 应用开始标签 Hook::listen(‘app_begin‘); // Session初始化 if (!IS_CLI) { session(C(‘SESSION_OPTIONS‘)); } // 记录应用初始化时间 G(‘initTime‘); App::exec();
也就是Controller里面的方法(action)执行之前
会执行ReadHtmlCache 这样就不会再查数据库什么的了缓解服务器压力直接从静态页面读取
我们在看看ReadHtmlCache的run方法
// 行为扩展的执行入口必须是run public function run(&$params) { // 开启静态缓存 if (IS_GET && C(‘HTML_CACHE_ON‘)) { $cacheTime = $this->requireHtmlCache(); if (false !== $cacheTime && $this->checkHTMLCache(HTML_FILE_NAME, $cacheTime)) { //静态页面有效 // 读取静态页面输出 echo Storage::read(HTML_FILE_NAME, ‘html‘); exit(); } } }
1、是GET操作并查看配置文件HTML_CACHE_ON 是否开启
2、requireHtmlCache获取缓存时间也就是根据规则获取规则中定义的缓存时间 否则获取 HTML_CACHE_TIME
3、false !== $cacheTime 所以 HTML_CACHE_TIME或者规则时间设置为 -1、0 、false时都不会执行
4、checkHTMLCache 静态页面有效
5、Storage::read(HTML_FILE_NAME, ‘html‘) 读取静态页面输出
我们来研究下requireHtmlCache
$htmls = C(‘HTML_CACHE_RULES‘); // 读取静态规则 if (!empty($htmls)) {如果规则存在则执行
$htmls = array_change_key_case($htmls);规则中的key都转为小写 所以规则的key不区分大小写
if (isset($htmls[$controllerName . ‘:‘ . $actionName])) { $html = $htmls[$controllerName . ‘:‘ . $actionName]; // 某个控制器的操作的静态规则 } elseif (isset($htmls[$controllerName . ‘:‘])) {// 某个控制器的静态规则 $html = $htmls[$controllerName . ‘:‘]; } elseif (isset($htmls[$actionName])) { $html = $htmls[$actionName]; // 所有操作的静态规则 } elseif (isset($htmls[‘*‘])) { $html = $htmls[‘*‘]; // 全局静态规则 }
所以规则的key可以写成一下四种
$controllerName :$actionName
$controllerName :
$actionName
*
key之后我们在研究下规则
第一种 {$_SERVER.REQUEST_URI|md5}
$rule = preg_replace_callback(‘/{\$(_\w+)\.(\w+)(?:\|(\w+))?}/‘, $callback, $rule);根据$callback这个匿名函数可以看出
{\$(_\w+)\.(\w+)(?:\|(\w+))?}
$_字符串.字符串|字符串
我设置的规则是
{$_SERVER.REQUEST_URI|md5}
return (count($match) == 4) ? $match[3]($var) : $var;
最终会返回 md5($_SERVER[REQUEST_URI]) 或$_SERVER[REQUEST_URI]);
查看函数$callback = function($match)可以看出
{$_SERVER.REQUEST_URI|md5}
SERVER可以是GET、POST、REQUEST、SERVER、SESSION、COOKIE
md5可以是任意单参数函数 如 trim等
第二种 {id|md5}
$rule = preg_replace_callback(‘/{(\w+)\|(\w+)}/‘, function($match) { return $match[2]($_GET[$match[1]]); }, $rule);默认用了GET规则如下 返回 md5($_GET[id])
第三种 {id}
$rule = preg_replace_callback(‘/{(\w+)}/‘, function($match) { return $_GET[$match[1]]; }, $rule);默认用$_GET 返回 $_GET[id]
第四种 特殊系统变量
$rule = str_ireplace(array(‘{:controller}‘, ‘{:action}‘, ‘{:module}‘), array(CONTROLLER_NAME, ACTION_NAME, MODULE_NAME), $rule);
如 {:controller} 、{:action}、{:module}
第五种
$rule = preg_replace_callback(‘/{|(\w+)}/‘, function($match) { return $match[1](); }, $rule);如:|time、|md5 不过这样没有意义 这个地方应该是为特殊函数自定义用的
之后系统定义了一个HTML_FILE_NAME并返回缓存时间
define(‘HTML_FILE_NAME‘, HTML_PATH . $rule . C(‘HTML_FILE_SUFFIX‘)); return $cacheTime;