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?

- 14,299
- 26
- 93
- 133
-
2You certainly get your money out of the word *use*. `;)` – Jared Farrish Jun 08 '12 at 03:02
-
@JaredFarrish The `use` is for import variable to the scope of anonymous function. Someting like `$fuc = function ($a, $b) use ($c) {}` . – xdazz Jun 08 '12 at 03:17
-
Note, the link (as @xdazz points out above) was incorrect; reference [Anonymous functions](http://www.php.net/manual/en/functions.anonymous.php) instead. – Jared Farrish Jun 08 '12 at 03:27
4 Answers
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).

- 170,779
- 38
- 263
- 309
-
-
-
That's because I fixed them. There's a missing `;` on the `return` and you already fixed the missing `$` on the function call. – Jared Farrish Jun 08 '12 at 03:22
-
@JaredFarrish I see ... well, thank you :) morphing code from JS to PHP is easy to mess up – Ja͢ck Jun 08 '12 at 03:25
-
-
@JackSpairow - See the edit, there was a missing `;` on the end of the first `return`. – Jared Farrish Jun 08 '12 at 03:27
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.

- 158,678
- 38
- 247
- 274
-
I'm much more familiar with Javascript closures, but to address the "why or when do you have arguments in a closure?", I would say when you are either matching an incoming signature (like in a handler), or it is more convenient or useful to pass as arguments. Comments? – Jared Farrish Jun 08 '12 at 03:10
-
@JaredFarrish PHP's closure is a litter different with javascript. When you use the variable outside, you need to use `use`. – xdazz Jun 08 '12 at 03:15
-
Yes, I reading the Manual's [Using namespaces: Aliasing/Importing](http://php.net/manual/en/language.namespaces.importing.php) and I'm realizing I need to read up on this. Not the same as Javascript, for sure. – Jared Farrish Jun 08 '12 at 03:17
-
1@JaredFarrish The `use` mentioned here is nothing relative with the namespaces. – xdazz Jun 08 '12 at 03:18
-
@JaredFarrish Read here: the Example #3 http://www.php.net/manual/en/functions.anonymous.php – xdazz Jun 08 '12 at 03:18
-
Do you have a link to a Man page that explains in the context of the question? Note, I've never (had the opportunity) to use closures in PHP, so this is a bit new to me, too. EDIT: Oop, just saw your comment. – Jared Farrish Jun 08 '12 at 03:19
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()
.

- 15,599
- 5
- 53
- 91
-
I wouldn't call this a closure though, it doesn't close over anything; rather, it's an anonymous function .. then again, the term "closure" in PHP is ambiguous :) – Ja͢ck Jun 08 '12 at 03:24
-
-
@Jack - Referencing the Manual for [anonymous functions](http://www.php.net/manual/en/functions.anonymous.php), the first example is identical to the one here, except it uses a different function. What is wrong with the example? – Jared Farrish Jun 08 '12 at 03:38
-
-
@JackSpairow Initially I was going to use `array_map()`, but then when I noticed how sparse the docs were for the callable I switched to `array_walk()` but forgot to swap the parameters. Good catch! – Bailey Parker Jun 08 '12 at 03:45
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

- 3,164
- 2
- 23
- 30