Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusion with 'use' identifier in PHP closures

Tags:

closures

php

I'm a little confused with PHP closures. Can someone clear this up for me:

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

What's the difference between $apples and $oranges and when should I be using each?

like image 824
enchance Avatar asked Sep 04 '13 14:09

enchance


1 Answers

$apples will take on the value that is passed to the function when it is called, e.g.

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

$oranges will refer to the value of the variable $oranges which exists in the scope where you defined the closure. E.g.:

$oranges = 'bar';

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

The differences is that $oranges is bound when the function is defined and $apples is bound when the function is called.


Closures let you access variables defined outside of the function, but you have to explicitly tell PHP which variables should be accessible. This is similar (but not equivalent!) to using the global keyword if the variable is defined in global scope:

$oranges = 'bar';

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

The differences between using closures and global:

  • You can bind local variables to closures, global only works with global variables.
  • Closures bind the value of the variable at the time the closure was defined. Changes to the variables after the function was defined does not effect it.
    On the other hand, if you use global, you will receive the value the variable has at the moment when the function is called.

    Example:

    $foo = 'bar';
    $closure = function() use ($foo) { 
        echo $foo; 
    };
    $global = function() {
        global $foo;
        echo $foo;
    };
    
    $foo = 42;
    $closure(); // echos "bar"
    $global(); // echos 42
    
like image 198
Felix Kling Avatar answered Sep 17 '22 23:09

Felix Kling