Without an explicit variant of the function, there is no reason to expect a function to execute your callback, rather than simply leaving it as a variable.
Let's break down the logic a bit:
// Declare the callback
$something = function(){
$c='abcdefghijklmnopqrstuvwxyz';
return (string)$c{rand(0,strlen($c)-1)};
}
Regardless of what this function does, we now have a variable which happens to be a Closure
.
// Fill the array
$list = array_fill(0,10,$something);
The array is now full of 10 copies of $something
. That happens to be 10 pointers to our Closure
. There's no reason for PHP to think that that's not what you want.
// Join up the items in the array to make a string
$str = implode($list);
Now, implode()
has to make a string, so it converts each item in the array it's given to a string before proceeding. For an object, it will try to call __toString()
(or the equivalent "under the hood" for built-in objects), but Closure
has no such method. This is where your error is coming from.
So, no, you haven't messed up exactly, but it's not reasonable to assume that PHP will execute a callback just because you know that's what you want.
As Mark Baker points out in a comment, you can use array_map
to execute your callback; reusing $something
from above, and breaking it down for clarity:
// Create 10 items, with nothing interesting in them
$list_of_nulls = array_fill(0, 10, null);
// Run the callback for each item of that list
// It will be given the current value each time, but ignore it
$list = array_map($something, $list_of_nulls);
// Now you have the list you wanted to join up
$str = implode($list);
Of course, you could also just run the function 10 times in a loop:
$str = '';
for ( $i=0; $i<10; $i++ ) {
$str .= $something();
}