CakePHP 2.1: кеш браузера и просмотр кеша

У меня вопрос о том, как кеширование просмотра и кеширование браузера работают вместе в CakePHP 2.1.

Я только что обновил свое приложение до CakePHP 2.1 и настроил кеширование HTTP с помощью нового метода $this->response->modified (который работает хорошо):

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, похоже, переопределяет кеширование браузера (в частности, заголовок Last-Modified отправляется, когда страницы подаются из кеша представления CakePHP). Это останавливает браузер от кеширования страниц, которые подаются из кэша просмотров CakePHP.

В идеале я бы хотел, чтобы браузер кэшировал страницы, даже если они обслуживаются кешем CakePHP (т.е. я хотел бы, чтобы CakePHP возвращал заголовок Last-Modified и отвечал на заголовок запроса браузера If-Modified-Since, независимо от того, CakePHP возвращает кэшированную копию страницы или нет).

Мне просто интересно, будет ли это ожидаемым поведением, будет ли я делать что-то неправильно или что-то, что не было рассмотрено (или не считается важным).

1 ответ

Просмотр кэширования по своей природе фактически не выполняет метод контроллера по каждому запросу. Я предполагаю, что он выполняет одно действие, а затем кэширует вывод на диск (или любой другой механизм кэширования, который вы используете). Если вы посмотрите на метод CacheHelper _writeFile, вы увидите, как создается кешированный вид.

$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.

licensed under cc by-sa 3.0 with attribution.