ReadHtmlCacheBehavior.class.php
6.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace Behavior;
use Think\Storage;
/**
* 系统行为扩展:静态缓存读取
*/
class ReadHtmlCacheBehavior
{
// 行为扩展的执行入口必须是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();
}
}
}
// 判断是否需要静态缓存
static private function requireHtmlCache()
{
// 分析当前的静态规则
$htmls = C('HTML_CACHE_RULES'); // 读取静态规则
if (! empty($htmls)) {
$htmls = array_change_key_case($htmls);
// 静态规则文件定义格式 actionName=>array('静态规则','缓存时间','附加规则')
// 'read'=>array('{id},{name}',60,'md5') 必须保证静态规则的唯一性 和 可判断性
// 检测静态规则
$controllerName = strtolower(CONTROLLER_NAME);
$actionName = strtolower(ACTION_NAME);
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['*']; // 全局静态规则
}
if (! empty($html)) {
// 解读静态规则
$rule = is_array($html) ? $html[0] : $html;
// 以$_开头的系统变量
$callback = function ($match)
{
switch ($match[1]) {
case '_GET':
$var = $_GET[$match[2]];
break;
case '_POST':
$var = $_POST[$match[2]];
break;
case '_REQUEST':
$var = $_REQUEST[$match[2]];
break;
case '_SERVER':
$var = $_SERVER[$match[2]];
break;
case '_SESSION':
$var = $_SESSION[$match[2]];
break;
case '_COOKIE':
$var = $_COOKIE[$match[2]];
break;
}
return (count($match) == 4) ? $match[3]($var) : $var;
};
$rule = preg_replace_callback('/{\$(_\w+)\.(\w+)(?:\|(\w+))?}/', $callback, $rule);
// {ID|FUN} GET变量的简写
$rule = preg_replace_callback('/{(\w+)\|(\w+)}/', function ($match)
{
return $match[2]($_GET[$match[1]]);
}, $rule);
$rule = preg_replace_callback('/{(\w+)}/', function ($match)
{
return $_GET[$match[1]];
}, $rule);
// 特殊系统变量
$rule = str_ireplace(array(
'{:controller}',
'{:action}',
'{:module}'
), array(
CONTROLLER_NAME,
ACTION_NAME,
MODULE_NAME
), $rule);
// {|FUN} 单独使用函数
$rule = preg_replace_callback('/{|(\w+)}/', function ($match)
{
return $match[1]();
}, $rule);
$cacheTime = C('HTML_CACHE_TIME', null, 60);
if (is_array($html)) {
if (! empty($html[2])) {
$rule = $html[2]($rule);
} // 应用附加函数
$cacheTime = isset($html[1]) ? $html[1] : $cacheTime; // 缓存有效期
} else {
$cacheTime = C('HTML_CACHE_TIME', null, 60);
}
// 当前缓存文件
define('HTML_FILE_NAME', HTML_PATH . $rule . C('HTML_FILE_SUFFIX', null, '.html'));
return $cacheTime;
}
}
// 无需缓存
return false;
}
/**
* 检查静态HTML文件是否有效
* 如果无效需要重新更新
*
* @access public
* @param string $cacheFile
* 静态文件名
* @param integer $cacheTime
* 缓存有效期
* @return boolean
*/
static public function checkHTMLCache($cacheFile = '', $cacheTime = '')
{
if (! is_file($cacheFile)) {
return false;
} elseif (filemtime(\Think\Think::instance('Think\View')->parseTemplate()) > Storage::get($cacheFile, 'mtime', 'html')) {
// 模板文件如果更新静态文件需要更新
return false;
} elseif (! is_numeric($cacheTime) && function_exists($cacheTime)) {
return $cacheTime($cacheFile);
} elseif ($cacheTime != 0 && NOW_TIME > Storage::get($cacheFile, 'mtime', 'html') + $cacheTime) {
// 文件是否在有效期
return false;
}
// 静态文件有效
return true;
}
}