Hina-Mode

とある呑んだくれエンジニアの気が向いた時に書く戯言

【2015-07-04 修正有】FuelPHPのPresenter、ViewModelではクロージャを作成してはイケない。

これでちょっとハマりましたので注意喚起の意味も込めてエントリー生成します。
※注意喚起がメインなのでタイトルは若干あおり気味ですがご理解ください。

ビューモデル - 概要 - FuelPHP ドキュメント

class View_Index extends ViewModel
{

    public function view()
    {
        $this->echo_upper = function($string) { echo strtoupper($string); };
    }
}

$echo_upper('this string'); // 出力: "THIS STRING"

いわゆるViewModel、最近ではPresenterという形で実装されているコチラですが、
サンプルではクロージャを作成し、Viewに持っていけるような雰囲気で記載されています。

が、この記述、バージョン1.7.3以降では動作しません。

github.com

上記のコミットでクロージャをviewの変数として渡すとrender時に実行されて、render時の実行結果がviewの変数として格納されるように仕様が変更されています。
よって、View側でクロージャを実行しようとするとCall to undefined functionでFatal Errorが発生します

というわけで現状ではFuelPHPではviewへクロージャを引き渡す方法が公式では存在しないようなのでご注意下さい。

修正

github.com

github.com

id:Kenji_sさんが再度本家でissue発行して下さいました。ありがとうございます。
修正コミットも既に反映されているようです。
1.8/develop以降で改めてクロージャが利用できるようになっています
1.8以降でViewでクロージャを利用する方法は2通り存在するようです。

1つ目は下記のようにset_safeを用いる事でクロージャをその場で実行しないように回避する方法。

class View_Index extends ViewModel
{

    public function view()
    {
        $this->set_safe('echo_upper', function($string) { echo strtoupper($string); });
    }
}

$echo_upper('this string'); // 出力: "THIS STRING"

2つ目はconfig.php側でfilter_closuresをfalseに設定する方法のようです。

http://fuelphp.com/dev-docs/general/presenters.html#/functions


※1.7.3では相変わらずこの仕様は変わっていないため、引き続き利用にはご注意ください。
該当バージョンの利用時には該当コミットをパッチとして充てることを推奨します。