無名関数とvar_export
有名な話なのかもしれませんが、メモ
設定配列などを読み込んでマージした後にキャッシュ目的でvar_exportする、といったことはあると思いますが、
<?php //設定ファイル $foo = array( 'test' => function(){return new StdClass;}, ); //エクスポートされた内容を確認 echo var_export($foo, true) . ';'; //---result--- array ( 'test' => Closure::__set_state(array( )), );
ところが、Closureには__set_stateは定義されていませんので、このままキャッシュしても正しく戻せません。
やってみます。
<?php //設定ファイル $foo = array( 'test' => function(){return new StdClass;}, ); $fp = fopen("php://memory", "r+"); fputs($fp, var_export($foo, true) . ';'); rewind($fp); eval(stream_get_contents($fp)); fclose($fp);
結果、
Fatal error: Call to undefined method Closure::__set_state()
となります。(php5.4.12で確認)
ファイルに書き出して、includeしても同じです。
そこで回避方法ですが、こういうのがありますね。serializableでクロージャーをラップする方法ですね。なるほど。
しかし、無名関数を宣言しているファイルを読み込んでコード行から判定しているようですが、書き方によってはハマリそうです。namespaceも反映されていない気がしますが、大丈夫なんでしょうか。
http://www.htmlist.com/development/extending-php-5-3-closures-with-serialization-and-reflection/
<?php $closure = new SuperClosure( function($num1, $num2) {return $num1 + $num2;} );