问题
When do closures have parameters (or how do closures with parameters work)? I know that use()
is used to import variables outside the anonymous function, but what about the parameter(s) of the closure itself?
回答1:
An example of closures with parameters is currying:
function greeter($greeting)
{
return function($whom) use ($greeting) {
// greeting is the closed over variable
return "$greeting $whom";
};
}
$hello_greeter = greeter('hello');
echo $hello_greeter('world'); // will print 'hello world';
The greeter
function will return a "half-implemented" function that will always start with the same greeting, followed by whatever is passed into it (e.g. the person to greet).
回答2:
If you are using a function that accept an anonymous function as parameter, then check the doc of the function.
If the function is written by you, then you are the controller, you decide it.
回答3:
use()
is especially useful for functions that require a function as a parameter. It might be required that the passed function take only two parameters and that any extra parameter is simply ignored. In this case, use use()
to "import" a variable from current scope to the anon function.
$myvar = 10;
$fun = function(&$val, $index) use ($myvar) {$val += $myvar;};
$testArray = array(1,2,3);
array_walk($testArray, $fun);
var_dump($testArray); // 11, 12, 13
Note: if your anon function signature was function(&$val, $index, $myvar)
instead, you would get constant warnings
when using your anon function with array_walk
because that extra 3rd parameter is unused and undefined. So, use use()
to pass in that extra parameter instead.
Edit: you can also pass in variables by reference in use()
...
$myvar = 10;
$fun = function(&$val, $index) use (&$myvar) {$myvar = 1; $val += $myvar;};
$testArray = array(1,2,3);
array_walk($testArray, $fun);
var_dump($testArray); // 2, 3, 4
echo $myvar; // 1
回答4:
Closures passed to PHP functions that should have parameters are detailed in the docs. A good example of this is array_walk(), which is used to apply the callback to an iterable:
$arr = array('a', 'b', 'c');
array_walk($arr, function($key, $val) {
echo $key . ' => ' . $val . "\n";
});
In the docs, the parameters that you should include on the callable passed to array_walk()
are detailed under "Parameters." It says:
Typically, funcname takes on two parameters. The array parameter's value being the first, and the key/index second.
Often times you will find similar hints on other functions in the PHP docs. I was disappointed that the documentation for array_map()
was not as detailed, but I can remember there being other functions that excepted callables that had sufficient closure parameter documentation.
If you are looking to write your own function that accepts closures (or other values that you can call) and dictates what parameters it must have, you can use the typehint callback
in PHP 5.3 or callable
in PHP 5.4.
function gobblesUpCallable(callable $func) {
call_user_func($func); // Use this, someone could pass in a callable string or array
}
However, to specify parameters, you'll need to use ReflectionClass
or ReflectionFunction
which means you probably forgo call_user_func()
.
来源:https://stackoverflow.com/questions/10942560/how-do-you-know-what-parameters-arguments-to-put-in-a-closure