グローバルを使用せずにPHP5.2.xでクロージャをシミュレートすることは可能ですか?目的の変数を追加のパラメーターとしてクロージャーに渡す方法を考えることはできますが、それはベストプラクティスのようには感じられません。
何か案は?
グローバルを使用せずにPHP5.2.xでクロージャをシミュレートすることは可能ですか?目的の変数を追加のパラメーターとしてクロージャーに渡す方法を考えることはできますが、それはベストプラクティスのようには感じられません。
何か案は?
興味深い質問です。まったく不可能だと思いますが、見てみましょう
IBMの引用-PHP5.3、パート2の新機能
クロージャは、それ自体の環境で評価される関数であり、関数が呼び出されたときにアクセスできる1つ以上のバインドされた変数があります。
そしてさらに(強調鉱山)
外部環境からインポートする変数は、クロージャ関数定義のuse句で指定します。デフォルトでは、これらは値によって渡されます。つまり、クロージャ関数定義内で渡された値を更新しても、外部の値は更新されません。
使用すると参照渡しされ、句でglobal
使用することによりクロージャを使用して参照によって変数をバインドすることは可能ですが、5.3のデフォルトの動作からの逸脱です。&
use
$var = 'yes';
$fn = create_function('', 'global $var; $var = "no";');
$fn();
echo $var; // outputs no
ただし、値で使用するためにグローバル変数をコピーすることもできます。
$var = 'yes';
$fn = create_function('', 'global $var; $tmp = $var; $tmp = "no";');
$fn();
echo $var; // outputs yes
さらに、グローバル変数の値(を使用する場合create_function
)は、関数の作成時ではなく、関数の実行時に評価(バインド)されません。
$var = 'yes';
$fn = create_function('', 'global $var; $tmp = $var; return $tmp;');
$var = 'maybe';
echo $fn(); // outputs maybe
$var = 'yes';
$fn = function() use ($var) { return $var; };
$var = 'maybe';
echo $fn(); // outputs yes
また重要なのは
オブジェクト内で定義する場合、1つの便利な点は、クロージャーが$ this変数を介してオブジェクトに完全にアクセスでき、明示的にインポートする必要がないことです。*これは最終的なPHP5.3で削除されたと思いますが
これはキーワードでは不可能であり、global
単に使用することもできません$this
。関数本体をで定義するときに、クラスからプロパティを参照する方法はありませんcreate_function
。
class A {
protected $prop = 'it works';
public function test()
{
$fn = create_function('', 'echo $this->prop;');
return $fn;
}
}
$a = new A;
$fn = $a->test();
$fn();
結果として
Fatal error: Using $this when not in object context
要約する
と、グローバルスコープから変数をインポートする関数を作成することはできますが、別のスコープの変数を使用して関数を作成することはできません。また、使用時には技術的に拘束力はなく、作成された関数の実行時にインポートするため、この制限によりクロージャーがラムダになるcreate_function
と主張したいと思います。
編集:以下のOnnoMarsmanが提供するソリューションはかなりまともです。クロージャを完全にシミュレートしているわけではありませんが、実装はかなり近いです。
私の解決策:http ://techblog.triptic.nl/simulating-closures-in-php-versions-prior-to-php-5-3/
ただし、オブジェクト内の変数を最初の引数としてクロージャーに渡します。
http://en.wikipedia.org/wiki/Curryingのようにカリー化するという意味ですか
次にhttp://zaemis.blogspot.com/2009/06/currying-in-php.html
そうでない場合は、気にしないでください。:-)
あなたがそれをすることができるいくつかの特別な場合があります。
変数を(参照ではなく)値でキャプチャする必要があり、その値が上記の数値、文字列、配列などの単純な値型(オブジェクト、リソース、関数などの参照型ではない)の場合は、次のように簡単にできます。を使用して関数定義に挿入しますvar_export()
。
$var = array(1, 3);
$f = create_function('',
'$var=' . var_export($var,true) . '; return $var;');
関数の呼び出し間で可変状態を維持するために参照によって変数をキャプチャする必要があるが、変更が作成された元のスコープに反映される必要がない場合(たとえば、アキュムレータを作成するために、合計は、作成スコープの合計変数を変更する必要はありません)、同様に挿入できますが、静的変数として次のようになります。
function make_accumulator($sum) {
$f = create_function('$x',
'static $var=' . var_export($var,true) . '; return $var += $x;');
return $f;
}