Блоки try-catch PHP: могут ли они улавливать недопустимые типы аргументов?

Фон: Предположим, что у меня есть следующий явно неверный PHP:

    try{
        $vtest = '';
        print(array_pop($vtest));
    }catch(Exception $exx){}

Чтобы работать с array_pop, $vtest, очевидно, должен быть массивом, а не строкой. Тем не менее, когда я запускаю этот код, появляется предупреждение. Я не хочу этого, я просто хочу, чтобы код терпел неудачу.

Вопрос: Есть ли что-то особенное в PHP try-catch по сравнению с другими языками, которые заставляют это работать?

Отказ от ответственности: Просто для справки, правда, есть и другие способы справиться с этой ситуацией в PHP, но это нежелательно. Цель здесь состоит в том, чтобы избежать:

Трюк "at-sign":

        $vtest = '';
        print(@array_pop($vtest)); // <-- would like to avoid this

Тип:

        $vtest = '';
        $vtest = (array)$vtest;  
        print(array_pop($vtest));

Ответ 1

Предупреждения и уведомления не являются технически исключениями в PHP. Чтобы поймать исключение, он должен быть явно брошен, и многие из встроенных библиотек функций не генерируют исключений (главным образом потому, что они были написаны перед исключениями, поддерживаемыми PHP).

Было бы неплохо, если бы некоторые исключения были построены поверх существующей структуры уведомлений/предупреждений/ошибок, но, возможно, это слишком много.

Ответ 2

Предупреждение всегда будет выдаваться кодом, который вы указали, но вы можете использовать set_error_handler, чтобы диктовать, как обрабатывается предупреждение; т.е. вы можете вызвать его исключение. Кроме того, вы можете использовать restore_error_handler для возврата к обработке ошибок по умолчанию при выполнении.

function errorHandler($errno, $errstr, $errfile, $errline) {
    throw new Exception($errstr, $errno);
}
set_error_handler('errorHandler');

Ответ 3

Вы можете поймать такие ошибки при преобразовании каждой ошибки в исключение. Я создал небольшую среду обработки ошибок. Просто протестируйте его - он будет работать.

Ответ 4

Единственный способ, которым я могу думать, это сделать следующее:

try{
    $vtest = '';
    if(is_array($vtest)){
        print(array_pop($vtest));
    }
    else{
        throw new NotArrayException()
    }
}catch(NotArrayException $exx){}

Конечно, если вы просто хотите сделать это молча, вы можете просто сделать следующее, потому что вам не нужно ничего исключать:

    $vtest = '';
    if(is_array($vtest)){
        print(array_pop($vtest));
    }