Memo!無名関数と変数のスコープ - PHP
クロージャはローカルスコープの外で定義された、引数以外の変数を利用することができます。
引数以外の変数を利用したい場合は、useを使って渡します。
<?php $greeting = "Good morning"; $greet_nouse_use = function() { error_log("message: " . $greeting); }; $greet_use_use = function() use ($greeting) { error_log("message: " . $greeting); };
このコードの実行結果を見てみましょう。
useを使わない無名関数は親スコープの$greeting変数の値を参照できないですし、
使っている無名関数は参照できています。
message:
message: Good morning
message: Good morning
クロージャの特徴として、引数以外の変数を実行時ではなく、自分が定義された時点で解決するという特徴があります。
下のコードでは無名関数$greetが定義された時点で変数$greetingの値はGood morning、
実行の時点ではHelloです。
PHPの無名関数はクロージャですから、Helloが代入されたあとに実行された$greet()は、Good morningを出力します。
<?php $greeting = "Good morning"; $greet = function () use ($greeting) { error_log("message: " . $greeting); }; $greeting = 'Hello'; $greet();
message: Good morning
useには参照渡しが使えるので、実行時点の変数を使いたければ参照渡しにして変数を引き継ぎましょう。
<?php $greeting = "Good morning"; $greet = function () use (&$greeting) { error_log("message: " . $greeting); }; $greeting = 'Hello'; $greet(); $greeting = 'Good night'; $greet();
message: Hello
message: Good night
message: Good night
もちろん引数と一緒に使えます!
<?php $greeting = "Good morning"; $greet = function ($name) use ($greeting) { error_log($name . ', ' . $greeting); }; $greet('Hebisan');
Hebisan, Good morning
(byへびさん)