27661


[クロージャは、変数を親のスコープから引き継ぐことができます。 引き継ぐ変数は、use
で渡さなければなりません。](http://php.net/manual/ja/functions.anonymous.php)

[code]

    $message = 'hello';
    
    // $message を引き継ぎます
    $example = function () use ($message) {
        var_dump($message);
    };
    $example();
    
[/code]

* * *

**どのような仕組み？**  
・引数として渡すわけではない？  
・引数とは何が違うのでしょうか？

**「use ($message)」と書いた時点で「親スコープから変数を引き継ぐ」？**  
・引数として渡さずとも、スコープ間で値渡しや、参照渡しが出来るということでしょうか？  
・意味合い的には引数と同じ？

**エイリアスを作成する[use
演算子](http://php.net/manual/ja/language.namespaces.importing.php)との違い**  
・同じ意味？  
・エイリアスを作成するから、結果的に「親スコープから変数を引き継ぐ」ということ？？？？

* * *


CC BY-SA 3.0
2016-07-16T00:04:45.930
27657
2016-07-16T03:21:55.603
7886
question
php
クロージャでuse演算子を使用すると、どのような仕組みで「変数を親のスコープから引き継ぐ」のでしょうか？


個人的にはPHPの挙動だと「親スコープから引き継ぐ」というより「その時点の変数をキャプチャする」と考えたほうがわかりやすいように思いますが・・・。

具体的には、useに指定した変数をフィールドに含んだ
[`Closure`](http://php.net/manual/ja/class.closure.php) オブジェクトが作成されます。

[code]

    function getGreeter($msg) {
        return function() use($msg) {
            echo $msg;
        };
    }
    
    $hello = getGreeter('hello');
    
    var_dump($hello);
    $hello();
    
    /* 出力：
      class Closure#1 (1) {
        public $static =>
        array(1) {
          'msg' =>
          string(5) "hello"
        }
      }
      hello
    */
    
[/code]

この場合 `$msg` はクロージャにキャプチャされているので、`$hello` を呼び出す際に引数として渡す必要はありませんし、キャプチャ元である
`getGreeter()` のスコープにアクセスできなくても動作します。

`use($msg)` を `use(&$msg)` とすると参照でキャプチャすることができますが、これも  
`$closure->static['msg'] = $msg` と、  
`$closure->static['msg'] = &$msg` の違いのようなものです。

「エイリアスを作成する use 演算子」は同じuseという英単語が使われたというだけで、機能としては全く別のものです。

  * `use Foo\Bar as Bar`  
`Foo\Bar` を `BarAlias` としてuseする＝エイリアスの作成

  * `function() use($msg)`  
関数内で `$msg` をuseする＝変数のキャプチャ


CC BY-SA 3.0
2016-07-16T03:21:55.603
27661
2016-07-16T03:21:55.603
8000
27657
answer