The array_map function in PHP has a quirk ( I know, shocker ) that I’ve managed to forget several times. Hopefully writing it here will cement it in my memory.
Using array_map
isn’t hard, here is a very contrived example:
[sourcecode lang=”php”]
namespace EXAMPLE;
function lowercase_string( $name ) {
return strtolower( $name );
}
function lowercase_array( $names ) {
return array_map( ‘lowercase_string’, $names );
}
print_r( lowercase_array( [
‘Bill’,
‘Max’,
‘Julie’,
‘Norm’
] ) );
echo "n";
[/sourcecode]
You feed an array to lowercase_array()
and it will return lower cased versions of all the array entries. Do you know what happens when you run this code?
[sourcecode lang=”plain”]
PHP Warning: array_map() expects parameter 1
to be a valid callback, function ‘lowercase_string’
not found or invalid function name in
/home/josephscott/tmp/array-map.php on line 9
[/sourcecode]
( I broke this up into multiple lines to make it easier to read )
How can lowercase_string
not be a valid callback? It is even defined right there in the same file. The answer to this question is in the very first line of my example.
When using array_map()
inside of a namespace you must provide the full namespace reference to the callback. In this case that means replacing lowercase_string
with EXAMPLElowercase_string
:
[sourcecode lang=”php”]
namespace EXAMPLE;
function lowercase_string( $name ) {
return strtolower( $name );
}
function lowercase_array( $names ) {
return array_map( ‘EXAMPLElowercase_string’, $names );
}
print_r( lowercase_array( [
‘Bill’,
‘Max’,
‘Julie’,
‘Norm’
] ) );
echo "n";
[/sourcecode]
Running this corrected version gives us what we’d expect:
[sourcecode lang=”plain”]
Array
(
[0] => bill
[1] => max
[2] => julie
[3] => norm
)
[/sourcecode]
I think the reason that I keep forgetting this is because it feels more obvious that array_map()
should know it is already in a namespace and try to dereference the callback based on that namespace first, the same way a regular function call would. This feels like a violation of the principle of least astonishment (POLA).
While the array_map() documentation makes no mention of the namespace requirement for the callback, it does appear to be the intended behavior. A PHP bug was filed describing this exact issue. It was closed as “this is not a bug”.