2012-03-16 9 views
9

Tengo una pregunta sobre la forma en que el almacenamiento en caché y el almacenamiento en caché de los navegadores funcionan juntos en CakePHP 2.1.CakePHP 2.1: caché del navegador frente a la caché de la vista

Acabo de actualizar mi aplicación de CakePHP 2.1 y configurar el almacenamiento en caché HTTP utilizando el nuevo método $this->response->modified (que funciona bien):

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')); 
    } 
} 

También he establecido CakePHP vista almacenamiento en caché:

class ArticlesController extends AppController { 
    public $cacheAction = array(
     'view' => array('callbacks' => true, 'duration' => "1 week"), 
    } 
} 

Ambos funcionan bien cuando se usan de forma independiente. Sin embargo, cuando ambos están habilitados, el almacenamiento en caché de la vista de CakePHP parece anular el almacenamiento en caché del navegador (específicamente, no se envía el encabezado Last-Modified cuando las páginas se sirven desde el caché de vista de CakePHP). Esto impide que el navegador guarde en caché las páginas que están siendo servidas desde el caché de vista de CakePHP.

Idealmente, me gustaría que el navegador a páginas de caché, incluso si están siendo atendidas desde la caché de CakePHP (es decir, me gustaría CakePHP para devolver una cabecera Last-Modified y responder a la cabecera If-Modified-Since la petición del navegador, independientemente de si CakePHP tiene se devolver una copia en caché de la página o no).

Me pregunto si este es el comportamiento esperado, si estoy haciendo algo mal, o si es algo que no se ha considerado (o que no se considera importante).

Respuesta

2

Ver el almacenamiento en caché, por naturaleza, en realidad no ejecuta el método del controlador en cada solicitud. Supongo que ejecuta la acción una vez y luego almacena en caché la salida en el disco (o cualquier motor de caché que esté usando). Si look at the CacheHelper's _writeFile method, puede ver cómo se construye la vista en caché.

$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); 
    ?>'; 

Se crea un nuevo objeto Controller (con un nuevo CakeResponse) y carga todos los ayudantes, plugins, etc que se puede utilizar en la vista y lo escribe en la memoria caché.

Parece que agregar el encabezado Last-Modified a la respuesta de una acción/vista de caché podría requerir algunas modificaciones profundas en la biblioteca central de CakePHP.

+1

Sí, cualquier modificación del objeto Respuesta realizada por una acción del Controlador no se almacenará en caché, esto incluye la configuración de los encabezados de control de caché. Hay un ticket abierto sobre esto (aunque no relacionado con el almacenamiento en caché): http://cakephp.lighthouseapp.com/projects/42648/tickets/2358-cachehelper-defect-with-response La única solución sugerida es establecer encabezados manualmente en cualquiera el diseño o 'Controller :: beforeFilter()' (con devolución de llamada habilitada). – pixelistik

Cuestiones relacionadas