Why does array_map throw a warning when the closure raises an exception?
I've recently started programming with PHP again, after a long stint with other languages during which i've developed a more functional style - which i'm hoping to try and maintain.
I've noticed some weird behaviour, which I managed to distill into a testcase that I'm hoping someone can explain.
$func = function($item) {
if ($item == 0)
throw new开发者_开发技巧 Exception("Can't do 0");
return $item;
};
try {
array_map($func, array(1, 2, 3, 0, 5));
} catch (Exception $ex) {
echo "Couldn't map array";
}
When executing the above code, i see the following output:
Warning: array_map(): An error occurred while invoking the map callback in map_closure.php on line 10 Couldn't map array
I can suppress the error with @ on array_map, but this seems hacky at best.
The warning is generated because, put simply, the callback function is not returning normally (due to throwing the Exception). This is just the way that array_map()
is coded, if the callback function does not complete its execution. Remember an Exception breaks out of execution immediately, as far as your PHP code is concerned.
As for how to silence the warning, that's entirely up to you. Unfortunately, the warning will be generated and it's your choice to bury it or let it get displayed.
As an aside, maybe your test case was over-simplified but, it would make much more sense to use array_filter()
(or perhaps array_reduce()
) there.
As preinhaimer says, array_map
makes it really hard for you to see exactly what happened during its execution because it predates exceptions. It would not be practical to change its behavior anymore since that would lead to lots of (poorly-coded) applications breaking; that's life.
If you want a mechanism with which to check if the array_map
completed without errors or not, I have posted a detailed answer (with code) to this question which deals with practically the same problem. It's not as easy as try/catch
, but you work with what you have.
Either use @
or a foreach
instead of array_map
array_map() predates exceptions so it still uses warnings. There's a few annoying places in PHP where you're still forced to use error handling, this is one of them.
You're left with options like having it return null or some other un-used value when it encounters a problem, or filtering the array to ensure it only contains valid options before you run it through array_map.
精彩评论