2012-03-16 4 views
9

私は、CakePHP 2.1でビューキャッシュとブラウザキャッシングがどのように連携するかについて質問があります。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は関係なく、CakePHPがされているかどうかの、Last-Modifiedヘッダを返し、ブラウザのIf-Modified-Sinceリクエストヘッダに対応したいと思いますキャッシュされたページのコピーを返すかどうか)。

私は何か間違っているのかどうか、それが考慮されていない(または重要ではないと思われる)ものかどうか、これが期待される動作かどうか疑問に思っています。

答えて

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

それは(新しいCakeResponse付き)新しいControllerオブジェクトを作成し、ロードビューで使用することができるすべてのヘルパー、プラグインなどをキャッシュに書き込みます。

キャッシュアクション/ビューの応答にLast-Modifiedヘッダーを追加すると、コアのCakePHPライブラリに深刻な変更が必要になることがあります。

+1

はい、コントローラアクションによって行われたレスポンスオブジェクトの変更はキャッシュされません。これには、キャッシュコントロールヘッダーの設定も含まれます。これに関する公開チケットがあります(キャッシュ関連ではありません):http://cakephp.lighthouseapp.com/projects/42648/tickets/2358-cachehelper-defect-with-response 唯一の推奨される回避策は、レイアウトまたは 'Controller :: beforeFilter()'(コールバックが有効) – pixelistik

関連する問題