我查看了框架的代码,ThinkPHP\Library\Behavior\ReadHtmlCacheBehavior.class.php,这个文件的最后一个函数,是检测缓存是否有效的,
/**
* 检查静态HTML文件是否有效
* 如果无效需要重新更新
* @access public
* @param string $cacheFile 静态文件名
* @param integer $cacheTime 缓存有效期
* @return boolean
*/
static public function checkHTMLCache($cacheFile='',$cacheTime='') {
if(!is_file($cacheFile) && 'sae' != APP_MODE ){
return false;
}elseif (filemtime(\Think\Think::instance('Think\View')->parseTemplate(false)) > 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;
}
问题就出在这一句上filemtime(\Think\Think::instance('Think\View')->parseTemplate(false)) > Storage::get($cacheFile,'mtime','html')
这句是为了测试模板文件是否有改动,正常情况下,没有主题是不会有问题的,可这里没有调用选择主题的函数,theme(),所以,一旦我们设定的不同的主题模板后,这个是得不到正确模板文件路径的,
parseTemplate这个函数内容是这样的
/**
* 自动定位模板文件
* @access protected
* @param string $template 模板文件规则
* @return string
*/
public function parseTemplate($template='') {
if(is_file($template)) {
return $template;
}
$depr = C('TMPL_FILE_DEPR');
$template = str_replace(':', $depr, $template);
// 获取当前模块
$module = MODULE_NAME;
if(strpos($template,'@')){ // 跨模块调用模版文件
list($module,$template) = explode('@',$template);
}
// 获取当前主题的模版路径
defined('THEME_PATH') or define('THEME_PATH', $this->getThemePath($module));
// 分析模板文件规则
if('' == $template) {
// 如果模板文件名为空 按照默认规则定位
$template = CONTROLLER_NAME . $depr . ACTION_NAME;
}elseif(false === strpos($template, $depr)){
$template = CONTROLLER_NAME . $depr . $template;
}
$file = THEME_PATH.$template.C('TMPL_TEMPLATE_SUFFIX');
if(C('TMPL_LOAD_DEFAULTTHEME') && THEME_NAME != C('DEFAULT_THEME') && !is_file($file)){
// 找不到当前主题模板的时候定位默认主题中的模板
$file = dirname(THEME_PATH).'/'.C('DEFAULT_THEME').'/'.$template.C('TMPL_TEMPLATE_SUFFIX');
}
return $file;
}
问题应该就是出在这句: defined('THEME_PATH') or define('THEME_PATH', $this->getThemePath($module));
THEME_PATH。这个常量上,
因为缓存失效后检测这个模板文件是否改动时,没有传入主题信息,所以不会找到正确的模板文件位置,但是这个错误的位置又被写放了THEME_PATH这个常量。
等到第二次去通过模板文件生成页面时,虽然入了主题信息,但是,无法重新定义这个常量,THEME_PATH的内容,还是上次保存的那个错误地址,所以肯定就是找不到模板文件了,
真是不喜欢用啥常量,你真不知道他到底内里保存的啥内容。
我的解决方案就是,注释了checkHTMLCache函数的两行代码
/**
* 检查静态HTML文件是否有效
* 如果无效需要重新更新
* @access public
* @param string $cacheFile 静态文件名
* @param integer $cacheTime 缓存有效期
* @return boolean
*/
static public function checkHTMLCache($cacheFile='',$cacheTime='') {
if(!is_file($cacheFile) && 'sae' != APP_MODE ){
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;
}
这样虽然,在模板改动时,不能及时更新缓存,但起码程序能跑吧,只能改模板后,手动请下缓存了
不知道各位有啥更好的解决方法,来分享一下。
最佳答案
