スタッフブログ
satoです。
PHP4のサポート終了まであと2週間となりましたが、一方10月頃にリリースが予定されているPHP5.3で、クロージャ(Closure)が実装されることになりました。
今日はこのクロージャについて簡単に解説しようと思います。
まず、従来のPHPには、create_function()で無名関数(匿名関数)を定義できるという機能がありました。
ただし、使い方の制限が大きい上に、文字列内にコードを書く必要があるので、実行時まで文法がチェックできないという問題がありました。
PHP5.3からは、JavaScriptのような感じで無名関数を作成することができます。
さて、例えば、
単純に書いてみます。
クロージャをサポートしている言語なら、これは思った通りに動作します。
クロージャをサポートしていない言語なら、これは思った通りには動作しません。
「なんでこれで動くの?」と思った方はなかなか鋭いです。
コードだけを見ると、$countがその直前で定義されているのでそのまま使えると思うのですが、returnされる無名関数は、hoge()の外で実行されるため、hoge()内にある$countとは無縁になります。
しかしhoge()内の$countを参照したいということは多いと思います。これをそのまま実現するのがクロージャです。
もう少し突っ込むと、無名関数内の$countは、ここでは未定義変数です。
この未定義変数を解決する際に、この無名関数を定義した場所(ここではhoge())で定義されている変数を利用できるようにするのがクロージャです。
さて、そういう理由で、クロージャをサポートしているPHP5.3ならこれは動作するように思えるのですが、実際は動作しません。JavaScriptであれば動作するのですが…。
PHP5.3のクロージャは、定義した場所で定義されている変数を利用する際、無名関数の宣言時にどの変数を利用するか明示的に宣言してあげる必要があります。
具体的には以下のようになります。
無名関数とクロージャがサポートされることにより、PHP5.3以降では面白いコードがいろいろ書けそうで楽しみです。
今月末にはα1がリリースされる予定なので、興味のある方は是非チェックしてみてください。
PHP4のサポート終了まであと2週間となりましたが、一方10月頃にリリースが予定されているPHP5.3で、クロージャ(Closure)が実装されることになりました。
今日はこのクロージャについて簡単に解説しようと思います。
まず、従来のPHPには、create_function()で無名関数(匿名関数)を定義できるという機能がありました。
ただし、使い方の制限が大きい上に、文字列内にコードを書く必要があるので、実行時まで文法がチェックできないという問題がありました。
PHP5.3からは、JavaScriptのような感じで無名関数を作成することができます。
$f = function($var) {
return $var * 2;
};
$f(3); // return 6
これだけでも非常に書きやすくなったと思います。さて、例えば、
// 動作しないコード
function hoge() {
$count = 4;
return function($var) {
// ここで$count*$varをreturnさせたい
};
}
$f = hoge(); // $fにはreturnしたfunctionそのものが入る
$f(2);
という場合に、どうすればよいでしょうか。単純に書いてみます。
// 動作しないコード
function hoge() {
$count = 4;
return function($var) {
return $count * $var;
};
}
$f = hoge(); // $fにはreturnしたfunctionそのものが入る
$f(2);
クロージャをサポートしている言語なら、これは思った通りに動作します。
クロージャをサポートしていない言語なら、これは思った通りには動作しません。
「なんでこれで動くの?」と思った方はなかなか鋭いです。
コードだけを見ると、$countがその直前で定義されているのでそのまま使えると思うのですが、returnされる無名関数は、hoge()の外で実行されるため、hoge()内にある$countとは無縁になります。
しかしhoge()内の$countを参照したいということは多いと思います。これをそのまま実現するのがクロージャです。
もう少し突っ込むと、無名関数内の$countは、ここでは未定義変数です。
この未定義変数を解決する際に、この無名関数を定義した場所(ここではhoge())で定義されている変数を利用できるようにするのがクロージャです。
さて、そういう理由で、クロージャをサポートしているPHP5.3ならこれは動作するように思えるのですが、実際は動作しません。JavaScriptであれば動作するのですが…。
PHP5.3のクロージャは、定義した場所で定義されている変数を利用する際、無名関数の宣言時にどの変数を利用するか明示的に宣言してあげる必要があります。
具体的には以下のようになります。
function hoge() {
$count = 4;
return function($var) use($count) {
return $count * $var;
};
}
$f = hoge(); // $fにはreturnしたfunctionそのものが入る
$f(2);
このように、useで使用したい変数を宣言することにより、無名関数内で使用することができます。少々面倒な感じになっています。無名関数とクロージャがサポートされることにより、PHP5.3以降では面白いコードがいろいろ書けそうで楽しみです。
今月末にはα1がリリースされる予定なので、興味のある方は是非チェックしてみてください。