Путаница с идентификатором "use" при закрытии PHP

Я немного запутался с закрытием PHP. Может кто-то прояснить это для меня:

// Sample PHP closure
my_method(function($apples) use ($oranges) {
    // Do something here
});

В чем разница между $apples и $oranges и когда я должен использовать каждый?

Ответы

Ответ 1

$apples будет принимать значение, которое передается функции при ее вызове, например

function my_method($callback) {
    // inside the callback, $apples will have the value "foo"
    $callback('foo'); 
}

$oranges будет ссылаться на значение переменной $oranges, которое существует в области, в которой вы определили закрытие. Например:.

$oranges = 'bar';

my_method(function($apples) use ($oranges) {
    // $oranges will be "bar"
    // $apples will be "foo" (assuming the previous example)
});

Различия заключаются в том, что $oranges привязан, когда функция определена и $apples связана, когда функция называется.


Закрытия позволяют вам обращаться к переменным, определенным вне функции, но вы должны явно указать PHP, какие переменные должны быть доступны. Это похоже (но не эквивалентно!) На использование ключевого слова global, если переменная определена в глобальной области:

$oranges = 'bar';

my_method(function($apples) {
    global $oranges;
    // $oranges will be "bar"
    // $apples will be "foo" (assuming the previous example)
});

Различия между использованием замыканий и global:

  • Вы можете привязать локальные переменные к закрытию, global работает только с глобальными переменными.
  • Закрытие связывает значение переменной во время закрытия . Изменения в переменных после определения функции не влияют на нее.
    С другой стороны, если вы используете global, вы получите значение, которое имеет переменная в момент, когда функция называется.

    Пример:

    $foo = 'bar';
    $closure = function() use ($foo) { 
        echo $foo; 
    };
    $global = function() {
        global $foo;
        echo $foo;
    };
    
    $foo = 42;
    $closure(); // echos "bar"
    $global(); // echos 42
    

Ответ 2

$apples передается как аргумент my_method, а $oranges вводится внутри.