I have a multidimensional array, e.g.:
$values = array(
'one' => array(
'title' => 'Title One',
'uri' => 'http://example.com/one',
),
'two' => array(
'title' => 'Title Two',
'uri' => 'http://example.com/two',
),
);
...and I'd like to parse through that with a closure in my implode
function, à la:
$final_string = implode(' | ', function($values) {
$return = array();
foreach($values as $value)
$return[] = '<a href="' . $value['uri'] . '">' . $value['title'] . '</a>';
return $return;
});
However, this usage yields an Invalid arguments passed
error. Is there syntax that I'm missing which will make this use of closures possible? I'm using PHP v5.3.16.
Ashwin's answer is correct. Here's why:
When you pass the closure directly to the
implode
method - which explicitly wants a second argument of typearray
, it essentially checks theinstanceof
- hence the invalid argument. Theimplode
function does not expectmixed
and doesn't know to execute the closure.When you first assign that function to a variable, it causes PHP to first evaluate that variable and it ends up passing the returned value from the function into
implode
.In that case you're returning an array from the function and passing that into
implode
- that checks out.edit/adding: that anonymous function would be
instanceof Closure
.Use
array_map
:I trust you'll properly escape the values as HTML in your real code.
As to why this works and your code doesn't, you were passing a function as the second argument to
implode
. Frankly, that makes little sense: you can join a bunch of strings together, or maybe even a bunch of functions, but you can't join a single function together. It sounds strange, especially if you word it that way.Instead, we first want to transform all of the items in an array using a function and pass the result of that into
implode
. This operation is most commonly calledmap
. Luckily, PHP provides this function as, well,array_map
. After we've transformed the items in the array, we can join the results.You can't use implode to what your trying to achieve, because implode only accept an
array
as the second argument.You can try something like this.
It seems that you need to assign the function to a variable, and then pass it through to make it work.
I am not sure what the reason is, though, and will need to check it in a little more depth to be able to give you a proper reason.
You can see the code working here
EDIT : Converted this answer to a community wiki so that everyone can contribute here.
EDIT : Explanation by @kmfk
When you pass the closure directly to the
implode
method - which explicitly wants a second argument of typearray
, it essentially checks theinstanceof
- hence the invalid argument. Theimplode
function does not expectmixed
type and doesn't know to execute the closure to get anarray
.When you first assign that function to a variable, it causes PHP to first evaluate that variable and it ends up passing the returned value from the function into
implode
.In that case you're returning an array from the function and passing that into
implode
- that checks out.That anonymous function would be
instanceof Closure
, andExample use:
See example code