2

If write my callback-function this way ...

$direction = 'asc';      
$compare = function ($a, $b) use ($direction) {
...

... then the script shows the same behaviour as with this:

$direction = 'asc';      
$compare = function ($a, $b, $direction = 'asc') {
...

In both cases the variable is passed by value. So, what's the advantage of using the use-function instead of passing the variable via standard function-parameter?

Sunny Patel
  • 7,830
  • 2
  • 31
  • 46
cluster1
  • 4,968
  • 6
  • 32
  • 49
  • 1
    that is PHP's way to express a closure. [check this answer](http://stackoverflow.com/a/1065197/2412895) and search up what `closure` means if you don't understand this concept. – KarelG Feb 15 '14 at 09:15
  • Try changing the first `$direction` variable in your second example to see how it does not work at all. – deceze Feb 15 '14 at 09:53

2 Answers2

1
$compare = function ($a, $b, $direction = 'asc') { ... };

This is a normal function which accepts 3 parameters, the last of which is optional. It needs to be called like:

$compare('foo', 'bar', 'desc');

Here:

$direction = 'asc';      
$compare = function ($a, $b, $direction = 'asc') { ... };

The two $direction variables have absolutely nothing to do with each other.

If you do:

usort($array, $compare)

then usort will only ever call $compare with two arguments, it will never ever pass the third argument which will always remain at its default value asc.

$direction = 'asc';      
$compare = function ($a, $b) use ($direction) { ... };

Here the $direction variable is actually included in the function.

$direction = 'asc';  -----------------+
                                      |
$compare = function ($a, $b) use ($direction) {
                                      |
    echo $direction;  <-------------- +
};

You are extending the scope of the variable into the function. That's what use does. Also see Reference: What is variable scope, which variables are accessible from where and what are "undefined variable" errors?.

Community
  • 1
  • 1
deceze
  • 510,633
  • 85
  • 743
  • 889
0

What is use?

use means to inherit variables or values from current scope. Parameter can be given from anywhere, but used variable can exist only under certain circumstances. So you might not be able to use closure outside a scope, where used variable is not set:

<?php
header('Content-Type: text/plain; charset=utf-8');

$fn = function($x)use($y){
    var_dump($x, $y);
};

$fn(1);
?>

Shows:

Notice:  Undefined variable: y in script.php on line 4
int(1)
NULL

However, you can use parametrized closure without such scope-dependecy:

<?php
header('Content-Type: text/plain; charset=utf-8');

$fn = function($x, $y = null){
    var_dump($x, $y);
};

$fn(1);
?>

See related question: In PHP 5.3.0, what is the function "use" identifier?.

What's an advantage?

One of the main use cases of use construct is using closures as a callback for other functions (methods). In this case you must follow fixed number of function parameters. So the only way to pass extra parameters (variables) to a callback is use construct.

<?php
header('Content-Type: text/plain; charset=utf-8');

$notWannaSeeThere = 15;
$array  = [ 1, 15, 5, 45 ];
$filter = function($value) use ($notWannaSeeThere){
    return $value !== $notWannaSeeThere;
};

print_r(array_filter($array, $filter));
?>

Shows:

Array
(
    [0] => 1
    [2] => 5
    [3] => 45
)

In this example, $filter closure is used by array_filter() and called with only one argument - array element value (and we "can not" force it to use additional arguments). Still, we can pass there additionl variables, which availible in parent scope.

Reference: anonymous functions.

Inheriting variables from the parent scope is not the same as using global variables.

Community
  • 1
  • 1
BlitZ
  • 12,038
  • 3
  • 49
  • 68
  • "One of the main use cases of use construct is using closures as a callback for other functions (methods). In this case you must follow fixed number of function parameters. So the only way to pass extra parameters (variables) to a callback is use construct." Great! That has answered it perfectly. If I use the PHP usort-function (http://de1.php.net/manual/en/function.usort.php) a callback-function with EXACT 2 parameters is expected. With the use-keyword I can provide the claimed callback AND passing additional parameters. Many thanks. You helped me a lot. – cluster1 Feb 15 '14 at 10:16