print "これはクロージャを使用する文字列値です。msg は $msg.
PHP の新しいオープン クロージャ構文では、クロージャの外側で定義された変数を使用するために use を使用します。ここでは外部変数 $msg を使用します。定義後、その値はクロージャの実行後に変更され、元の値が出力されます。値によって渡される基本型パラメータの場合、クロージャの作成時にクロージャの使用値が決定されます。
/**
* クロージャを使用したカウンタジェネレータ
* これは実際に Python でクロージャを導入する例に基づいています...
* 次のように考えることができます:
* 1. counter 関数が呼び出されるたびに、ローカル変数 $counter が作成され、1 に初期化されます。
* 2. 次に、ローカル変数 $counter への参照を生成するクロージャーを作成します。
* 3. 関数 counter は作成したクロージャを返し、ローカル変数を破棄しますが、このときクロージャから $counter への参照があり、
* リサイクルされないので、関数カウンターによって返されたクロージャーはフリー状態を保持していることがわかります
* 変数です。
* 4. counter への各呼び出しは独立した $counter とクロージャを作成するため、返されるクロージャは互いに独立しています
。
* 5. 返されたクロージャを実行し、それが保持する自由状態変数をインクリメントして返します。結果はカウンタです
。
* 結論: この関数は独立したカウンターを生成するために使用できます
*/
関数カウンター() {
$カウンター = 1;
return function() use(&$counter) {return $counter ++;};
}
$counter1 = カウンター();
$counter2 = カウンター();
echo "counter1: " . $counter1() . "
/n";
echo "counter1: " . $counter1() . "
/n";
echo "counter1: " . $counter1() . "
/n";
echo "counter1: " . $counter1() . "
/n";
echo "counter2: " . $counter2() . "
/n";
echo "counter2: " . $counter2() . "
/n";
echo "counter2: " . $counter2() . "
/n";
echo "counter2: " . $counter2() . "
/n";
?>
クロージャの役割
1. foreachループのコードを減らす
たとえば、マニュアル http://php.net/manual/en/functions.anonymous.php の Cart
の例
コードは次のとおりです:
// いくつかの追加アイテムと各アイテムの数量を含む基本的なショッピング カート。
// メソッドの 1 つは、ショッピング カート内のすべてのアイテムの合計価格を計算するために使用されます。このメソッドはコールバック関数としてクロージャを使用します。
クラスカート
{
const PRICE_BUTTER = 1.00;
const PRICE_MILK = 3.00;
const PRICE_EGGS = 6.95;
protected $products = array();
パブリック関数 add($product, $quantity)
{
$this->products[$product] = $数量;
}
パブリック関数 getQuantity($product)
{
return isset($this->products[$product]) $this->products[$product] :
誤り;
}
パブリック関数 getTotal($tax)
{
$total = 0.00;
$callback =
関数 ($quantity, $product) ($tax, &$total) を使用します
{
$pricePerItem = constant(__CLASS__ . "::PRICE_" .
strtoupper($product));
$total += ($pricePerItem * $quantity) * ($tax + 1.0);
};
//ユーザー定義関数を使用して、配列内の各要素に対してコールバック処理を実行します
array_walk($this->products, $callback);
ラウンドを返す($total, 2);;
}
}
$my_cart = 新しいカート;
//商品をショッピングカートに追加します
$my_cart->add('バター', 1);
$my_cart->add('ミルク', 3);
$my_cart->add('卵', 6);
// 5% の消費税を含む合計価格を出力します。
print $my_cart->getTotal(0.05) ;
//結果は54.29です
?>
ここで getTotal 関数を変更する場合は、foreach を使用する必要があります。
2.関数パラメータを減らす
コードは次のとおりです:
関数 html($code, $id="", $class=""){
if ($id !== "") $id = " id = "$id"" ;
$class = ($class !== "") " class ="$class">":">";
$open = "<$code$id$class";
$close = "$code>";
return 関数 ($inner = "") use ($open, $close){
"$open$inner$close" を返します;
};
}
通常の方法だとhtml関数のパラメータにinnerを入れることになるので、コードの読み込みでも利用でもクロージャを使った方が良いです。
3. 再帰関数のロックを解除する
コードは次のとおりです:
$fib = function($n) use(&$fib) {
if($n == 0 || $n == 1) 1 を返す;
return $fib($n - 1) + $fib($n - 2);
};
echo $fib(2) . "n";
$lie = $fib;
$fib = function(){die('error');};//$fib 変数を書き換えます
echo $lie(5); // $fib がクロージャーによって参照されているためエラー
上記の質問では & が使用されていることに注意してください。ここで & が使用されていない場合、fib(n-1) は関数を見つけることができません (fib の型が以前に定義されていませんでした)
したがって、ループ関数をキャンセルするためにクロージャを使用したい場合は、それを使用する必要があります
コードは次のとおりです:
$recursive = function () use (&$recursive){
// この関数は $recursive として利用可能になりました
}
このフォーム。
4. 遅延バインディング
使用中の変数のバインドを遅らせる必要がある場合は、参照を使用する必要があります。そうしないと、定義時にコピーが作成されて使用されます
コードは次のとおりです:
$結果 = 0;
$one = function()
{
var_dump($result);
};
$two = function() use ($result)
{
var_dump($result);
};
$three = function() use (&$result)
{
var_dump($result);
};
$結果++;
$one(); // NULL を出力します: $result はスコープ内にありません
$two(); // int(0) を出力します: $result がコピーされました
$three(); // int(1)を出力します
参照を使用するかどうかは、値が呼び出し時に割り当てられるか宣言時に割り当てられるかを表します
PHP の匿名関数 (クロージャー関数) について新たに理解できましたか? この記事がヒントになれば幸いです。
http://www.bkjia.com/PHPjc/966918.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/966918.html技術記事 phpのクロージャ(Closure)匿名関数の詳細説明 この記事では、php5.3で導入されたPHPの匿名関数、つまりクロージャ(Closure)について、そしてクロージャの役割を中心に紹介します。