Функция или метод могут быть вызваны динамически с помощью call_user_func_array
, Если сам вызов не удается, FALSE
возвращается Также, call_user_func_array
возвращает возвращаемые значения из вызываемой функции или метода.
Поэтому, когда вызываемая функция или метод возвращает FALSE
а также (например, см. SO пример), это значение будет признано ложным срабатыванием.
Как можно надежно проверить, был ли вызов функции или метода успешно выполнен call_user_func_array
?
РЕДАКТИРОВАТЬ: Люди склонны указывать на существование is_callable
, Но речь не идет о проверке существования метода перед его вызовом, что позволяет избежать возможных ошибок. На самом деле, прежде чем делать call_user_func_array
вызов функции и ее аргументы и типы аргументов уже проверены с использованием Reflection
чтобы избежать Massive Assign attack.
документация упоминает FALSE
возвращаемое значение, но я не вижу, как его можно использовать, чтобы проверить, был ли вызов успешным.
Я бы преобразовал логический вызываемый элемент в тот, который является недействительным, но который выдает исключение при ошибке.
Таким образом, вы могли бы поймать исключение, и вы бы знали, если false
был возвращен call_user_func_array
что только его вызов не удался:
<?php
$booleanCallable = function (... $args): bool {
foreach ($args as $arg) {
echo "$arg \n";
};
return false;
};
$transformBooleanCallableToVoidThrowingException = function (callable $c): callable {
return function (... $args) use ($c): void {
if (false === $c(... $args)) {
throw new \RuntimeException("the call to the callable failed");
}
};
};
try {
$callable = $transformBooleanCallableToVoidThrowingException($booleanCallable);
$response = call_user_func_array($callable, [1, 2, 3]);
if (false === $response) {
throw new \RuntimeException("call_user_func_array failed");
}
} catch (\Exception $e) {
echo $e->getMessage();
}
Это выведет предоставленные аргументы и сообщение об ошибке:
1
2
3
the call to the callable failed
Вы можете явно проверить, произошла ли ошибка во время последнего вызова:
error_clear_last(); // since PHP 7, before that you'll need to store and
// compare the error state before and after the call
$result = call_user_func_array($foo, $bar);
if ($result === false && error_get_last()) {
echo 'Failed to call ', $foo;
}
Выше это общая проверка для любой ошибка, возможно, вы хотите проверить последнюю ошибку более подробно. Это будет выглядеть примерно так:
Array
(
[type] => 2
[message] => call_user_func_array() expects parameter 1 to be a valid callback, function 'foo' not found or invalid function name
[file] => /in/M8PrG
[line] => 3
)
Вы можете проверить, что message
соответствует что-то вроде 'call_user_func_array() expects parameter 1 to be a valid callback'
и / или что указанная строка является строкой выше. Обратите внимание, что особенно проверка сообщения может прерваться между версиями PHP.
Альтернативой является проверка до Ваш предполагаемый обратный звонок is_callable
.