Edited at

CakePHP v2.4.0: CookieComponentを利用しAppControllerでwriteした値をTestControllerでreadできない場合がある

More than 3 years have passed since last update.


これは何か?


  • CookieComponentを利用しCookieが無い状態でAppController::beforeFilter()でwriteした値をTestController::index()でread出来ない現象に遭遇した時のメモ。


次のコードはCookieが無い状態でhttp://{your domain}/testにアクセスしてreadした値が表示されます。


app/Controller/AppController.php

class AppController extends Controller {

public $components = array('Cookie');

public function beforeFilter($options = array()) {
$this->Cookie->write('test', 'value');
debug($this->Cookie->read('test'));
}
}



app/Controller/TestController.php

public function TestController extends AppController {

public function index() {

}
}



結果

<div class="cake-debug-output">

<span><strong>/app/Controller/AppController.php</strong> (line <strong>39</strong>)</span>
<pre class="cake-debug">
&#039;value&#039;
</pre>
</div>


次のコードはCookieが無い状態でhttp://{your domain}/testにアクセスするとreadできません。


app/Controller/AppController.php

class AppController extends Controller {

public $components = array('Cookie');

public function beforeFilter($options = array()) {
$this->Cookie->write('test', 'value');
}
}



app/Controller/TestController.php

public function TestController extends AppController {

public function index() {
debug($this->Cookie->read('test'));
}
}


結果

<div class="cake-debug-output">

<span><strong>/app/Controller/TestController.php</strong> (line <strong>5</strong>)</span>
<pre class="cake-debug">
null
</pre>
</div>


これは何故か???

TestController::index()が呼ばれるあたりでCookieComponent::startup()が呼ばれるようで、この際にCookieComponent内部で記録されているプロパティにカラの配列の代入が行われている。

そのためAppController::beforeFilter()でセットした'test'は、TestController::index()が呼ばれるときには既に無い様子。

※Cookieがセットされた2回目以降のアクセスならばCookieから読まれるため問題なく表示される。


実行順序を確認する

こちらが参考になりました。

http://qiita.com/ran/items/52a6060bcfbeec69dc34

各メソッドの呼び出しはこのあたりで行われている。

lib/Cake/Routing/Dispatcher.php#_invoke()

ControllerのbeforeFilter()の後に

Componentのstartup()が呼ばれているようなので

ControllerのbeforeFilter()でComponentを使わないのが良い模様。