In your example, the return value of the call to func1
is a function (more specifically, a Closure
). The error you're getting is due to php not being able to convert this object to a string. If you want to print the value returned by the closure, you need to call it.
function func1() {
return function () {
return 1;
};
}
$f = func1(); // Create the closure
echo $f(); // Calls the closure
This example is simply a function returning a function and doesn't demonstrate what sets a closure apart from any other first class function, and that is that a closure can contain state unique to it's creation. In other words, you can generate functions from the same code that differ in the data they can access.
Consider this trivial example:
function multiplier($m) {
return function ($v) use ($m) {
return $v * $m;
};
}
$mult_5 = multiplier(5);
echo $mult_5(5); // prints 25
$mult_10 = multiplier(10);
echo $mult_10(5); // prints 50
Again, this is a very trivial example, but it does demonstrate a couple of important things. First, we only defined a single function, yet by calling this function were able to generate two similar but different functions simply by changing the parameters when we called them. Also, consider that the function each have their own "state". In the case of the function I named $mult_5
, it knows that its own internal $m
value is 5
, and that is different than the $m
value of the $mult_10
function. The value for each of these was passed to the multiplier
function and that function has completed, but the value lives on in the returned function/closure.
It's also worth noting that each return value of a call to multiplier
is a first class function, meaning that you can write generalized functions (like multiplier
) and then use them to generate more specific functions 'on-the-fly', functions which are more specifically appropriate to the current environment/state of your program.
If you are familiar with OOP, the above example could be easily re-written using OOP:
class Multiplier {
protected $m;
public function __construct($m) {
$this->m = $m;
}
public function multiply($v) {
return $v * $this->m;
}
}
$mult_5 = new Multiplier(5);
echo $mult_5->multiply(5); // prints 25
$mult_10 = new Multiplier(10);
echo $mult_10->multiply(5); // prints 50
... and, this is very subjective, but I much prefer the more consice syntax of the closure.
Alternatively, you could just use a more general function to begin with:
function multiplier($a, $b) {
return $a * $b;
}
echo multiplier(5, 5);
echo multiplier(5, 10);
But the benefit of using a closure instead is that you can hide data (like the multiplier, in this example).