これは何か?
- 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">
'value'
</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を使わないのが良い模様。