CakePHPで$this->set()をしてもぜんぜんViewに反映されなくて2時間ぐらい悩んでてようやく「当たり前だ俺バカ」という理由にたどりつく

CakePHPおしごとをしていて、Controllerの中で$this->set(‘varname’, $value);みたいにViewに渡すパラメータを設定していたのだが、どうしても修正内容が反映されない。久しぶりのCakePHPで勘が鈍ってしまったのかと悩みつつも2時間ぐらい考えていたのだが、「おいそりゃ当たり前だろ俺バカすぎじゃない?」という不具合であった。実にくだらない理由であったが、フレームワークものは仕組みを忘れていると罠にハマるという必然も改めて体感した。

フレームワークは簡単にウェブ開発ができる便利さの裏に潜む罠が各所に仕掛けられていると思って使うべきなのだが、ふとした油断があると、そうした罠にはまってしばらく抜け出せなくなるということになる。

今回自分がはまったのは、Controllerで$this->set()を使ってパラメータを設定してもView側で一切反映されないという症状。

[php]
$value = ‘あいうえお’;
     :
$this->set(‘varname’, $value);
[/php]

CakePHPのController::set()メソッドについては過去に解説をしているので参考にして頂くとして、簡単にいうと、set()でセットされるパラメータは、Controller::viewVarsという配列に保存されていく。
つまり、set()の中でやっているのは、単に

$this->viewVars[‘varname’] = $value;

もしくは

array_merge($this->viewVars, array(‘varname’ => $value));

に相当する処理をしているわけだ。
最終的に、これをRender時にView::viewVarsに「コピー」し、View側ではControllerで設定された別のパラメータ配列を参照しながら使用している。

で、実は私の先ほどのコードは、もう少し上を見るとこのような感じになっている。

[php]
$value = ‘あいうえお’;
     :
$this->render(‘myviewfile’);
$this->set(‘varname’, $value);
[/php]

そう、$this->render()を呼び出している。
$this->set()より先に。

これはだめじゃん。

Controller::render()が呼ばれると、render()内ではViewのオブジェクトを取得することになるのだが、その処理をする_getViewObject()メソッドでは、new演算子でViewクラスのオブジェクトを生成し、それを返している。

つまり、Viewのコンストラクタが呼ばれていることになる。
私の過去記事にも書いたとおり、Viewクラスのコンストラクタ内ではviewVarsのコピー処理が行われる。
すなわち、$this->render()後に$this->set()を実行したところで何の意味もない。

ああ、アホだ俺…… orz

ということで、

[php]
$value = ‘あいうえお’;
     :
$this->set(‘varname’, $value);
$this->render(‘myviewfile’);
[/php]

のように処理を入れ替えて無事終了 orz

Webアプリ開発を加速する CakePHP2定番レシピ119CakePHP2 実践入門 (WEB+DB PRESS plus)はじめてのCakePHP (I・O BOOKS)詳解CakePHP辞典―2.0/2.1/2.2/2.3対応オープンソース徹底活用 CakePHP 2.1によるWebアプリケーション開発

“CakePHPで$this->set()をしてもぜんぜんViewに反映されなくて2時間ぐらい悩んでてようやく「当たり前だ俺バカ」という理由にたどりつく” への2件の返信

コメントを残す

メールアドレスが公開されることはありません。