PHP におけるクロージャの用途
PHPでクロージャ
作ってみたものの、実はあんまり用途が思い浮かんでない。
なんとなく、 array_walk がキーワードに浮かんでは来るけど。
てことで、とりあえず smarty で使ってみようと思う。
CakePHP を完全 smarty 化してみたものの、
smarty 内での配列の扱いが微妙だ。
↓事の顛末はこの辺に。
http://d.hatena.ne.jp/am11op/20070614/1181837256
要は、php ならこう書くべきところを
<?php echo $html->link('Edit', array('action'=>'edit', 2));?>
smarty では view に変なメソッド作った上でこう書く必要があった。
{$html->link('Edit', $view->_array('action=>edit', 2))}
まあ、これでもよいんだけど、せっかくなんで closure (的なもの)を使ってみる。
Closure はこんなの。
class Closure { var $_args; var $_func; /** * @private */ function Closure($func=null, $args=null) { if ($func) { $this->_args = $args; $func = ereg_replace("^function\([^\)]*\) *\{", "", $func); $func = ereg_replace("\}$", "", $func); $this->_func = $func; } } /** * @param $func string closure * @param $arg1 $mixed first object/var which is used in $func * @param $arg2 $mixed second object/var which is used in $func * ... */ function bind() { $args = func_get_args(); return new Closure(array_shift($args), $args); } /** * use this method to call closure */ function call() { $func = create_function('$args', $this->_func); return $func($this->_args); } function func() { $args = func_get_args(); $obj = new Closure(array_shift($args), $args); return $obj->call(); } }
無駄にインスタンス量産してるのは、書き直すのが面倒だったから。
このクラスを closure という名前で assign_by_ref してやって、
smarty 内からこう使う。
{*$html->link('Edit', $view->_array('action=>edit', 2))*} {$html->link('Edit', $closure->func("return array('action'=>'edit', 2);"))}
文字数増えてる!
ネタです!
まあ、ちょっと変数を php で処理して何かのメソッドに渡したい時、
一回しか使わないような modifier をいちいち作らなくてよいので便利かも。
ただし、入力値に対して使う場合は任意のコードを実行されないように気をつけること(棒読み)。