Проверьте, был ли call_user_func_array успешно выполнен

Функция или метод могут быть вызваны динамически с помощью 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 возвращаемое значение, но я не вижу, как его можно использовать, чтобы проверить, был ли вызов успешным.

1

Решение

Я бы преобразовал логический вызываемый элемент в тот, который является недействительным, но который выдает исключение при ошибке.

Таким образом, вы могли бы поймать исключение, и вы бы знали, если 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
1

Другие решения

Вы можете явно проверить, произошла ли ошибка во время последнего вызова:

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.

3