我对CakePHP 2.1中视图缓存和浏览器缓存的工作方式有疑问。
我刚刚将我的应用程序升级到CakePHP 2.1,并使用新的$this->response->modified
方法设置了HTTP缓存(效果很好):
class ArticlesController extends AppController {
public function view($id) {
$article = $this->Article->find(
'first',
array('conditions' => array('Article.id' => $id))
);
$this->response->modified($article['Article']['modified']);
$this->set(compact('article'));
}
}
我还设置了CakePHP视图缓存:
class ArticlesController extends AppController {
public $cacheAction = array(
'view' => array('callbacks' => true, 'duration' => "1 week"),
}
}
独立使用时效果都很好。但是,当两者都启用时,CakePHP视图缓存似乎会覆盖浏览器缓存(具体来说,当从CakePHP视图缓存提供页面时,不会发送Last-Modified
标头)。这会阻止浏览器缓存从CakePHP的视图缓存中提供的页面。
理想情况下,我希望浏览器缓存页面,即使它们是从CakePHP的缓存中提供的(即我希望CakePHP返回Last-Modified
标头,并响应浏览器的If-Modified-Since
请求标头,无论CakePHP是否返回页面的缓存副本)。
我只是想知道这是否是预期的行为,是否我做错了什么,或者是否是没有考虑过(或者认为不重要)的事情。
答案 0 :(得分:2)
查看缓存本质上并不是在每个请求上实际执行控制器的方法。我猜它会执行一次操作,然后将输出缓存到磁盘(或者,您正在使用的任何缓存引擎)。如果您look at the CacheHelper's _writeFile
method,您可以看到如何构建缓存视图。
$file = '<!--cachetime:' . $cacheTime . '--><?php';
if (empty($this->_View->plugin)) {
$file .= "
App::uses('{$this->_View->name}Controller', 'Controller');
";
} else {
$file .= "
App::uses('{$this->_View->plugin}AppController', '{$this->_View->plugin}.Controller');
App::uses('{$this->_View->name}Controller', '{$this->_View->plugin}.Controller');
";
}
$file .= '
$request = unserialize(\'' . str_replace("'", "\\'", serialize($this->request)) . '\');
$response = new CakeResponse(array("charset" => Configure::read("App.encoding")));
$controller = new ' . $this->_View->name . 'Controller($request, $response);
$controller->plugin = $this->plugin = \'' . $this->_View->plugin . '\';
$controller->helpers = $this->helpers = unserialize(base64_decode(\'' . base64_encode(serialize($this->_View->helpers)) . '\'));
$controller->layout = $this->layout = \'' . $this->_View->layout . '\';
$controller->theme = $this->theme = \'' . $this->_View->theme . '\';
$controller->viewVars = unserialize(base64_decode(\'' . base64_encode(serialize($this->_View->viewVars)) . '\'));
Router::setRequestInfo($controller->request);
$this->request = $request;';
if ($useCallbacks == true) {
$file .= '
$controller->constructClasses();
$controller->startupProcess();';
}
$file .= '
$this->viewVars = $controller->viewVars;
$this->loadHelpers();
extract($this->viewVars, EXTR_SKIP);
?>';
它创建一个新的Controller
对象(带有一个新的CakeResponse)并加载可能在视图中使用的所有帮助程序,插件等,并将其写入缓存。
似乎将Last-Modified
标头添加到缓存操作/视图的响应中可能需要对核心CakePHP库进行一些深层修改。