Php catch syntax error



Исключения

Содержание

В PHP реализована модель исключений, аналогичная тем, что используются в других языках программирования. Исключение в PHP может быть выброшено ( throw ) и поймано ( catch ). Код может быть заключён в блок try , чтобы облегчить обработку потенциальных исключений. У каждого блока try должен быть как минимум один соответствующий блок catch или finally .

Если выброшено исключение, а в текущей области видимости функции нет блока catch , исключение будет «подниматься» по стеку вызовов к вызывающей функции, пока не найдёт подходящий блок catch . Все блоки finally , которые встретятся на этом пути, будут выполнены. Если стек вызовов разворачивается до глобальной области видимости, не встречая подходящего блока catch , программа завершается с неисправимой ошибкой, если не был установлен глобальный обработчик исключений.

Выброшенный объект должен наследовать ( instanceof ) интерфейс Throwable . Попытка выбросить объект, который таковым не является, приведёт к неисправимой ошибке PHP.

Начиная с PHP 8.0.0, ключевое слово throw является выражением и может быть использовано в любом контексте выражения. В предыдущих версиях оно было утверждением и должно было располагаться в отдельной строке.

catch

Блок catch определяет, как реагировать на выброшенное исключение. Блок catch определяет один или несколько типов исключений или ошибок, которые он может обработать, и, по желанию, переменную, которой можно присвоить исключение (указание переменной было обязательно до версии PHP 8.0.0). Первый блок catch , с которым столкнётся выброшенное исключение или ошибка и соответствует типу выброшенного объекта, обработает объект.

Несколько блоков catch могут быть использованы для перехвата различных классов исключений. Нормальное выполнение (когда исключение не выброшено в блоке try ) будет продолжаться после последнего блока catch , определённого в последовательности. Исключения могут быть выброшены ( throw ) (или повторно выброшены) внутри блока catch . В противном случае выполнение будет продолжено после блока catch , который был вызван.

При возникновении исключения, код, следующий за утверждением, не будет выполнен, а PHP попытается найти первый подходящий блок catch . Если исключение не поймано, будет выдана неисправимая ошибка PHP с сообщением » Uncaught Exception . «, если только обработчик не был определён с помощью функции set_exception_handler() .

Начиная с версии PHP 7.1.0, в блоке catch можно указывать несколько исключений, используя символ | . Это полезно, когда разные исключения из разных иерархий классов обрабатываются одинаково.

Начиная с версии PHP 8.0.0, имя переменной для пойманного исключения является необязательным. Если оно не указано, блок catch будет выполнен, но не будет иметь доступа к выброшенному объекту.

finally

Блок finally также может быть указан после или вместо блоков catch . Код в блоке finally всегда будет выполняться после блоков try и catch , независимо от того, было ли выброшено исключение и до возобновления нормального выполнения.

Одно из заметных взаимодействий происходит между блоком finally и оператором return . Если оператор return встречается внутри блоков try или catch , блок finally всё равно будет выполнен. Более того, оператор return выполнится, когда встретится, но результат будет возвращён после выполнения блока finally . Кроме того, если блок finally также содержит оператор return , возвращается значение из блока finally .

Глобальный обработчик исключений

Если исключению разрешено распространяться на глобальную область видимости, оно может быть перехвачено глобальным обработчиком исключений, если он установлен. Функция set_exception_handler() может задать функцию, которая будет вызвана вместо блока catch , если не будет вызван никакой другой блок. Эффект по сути такой же, как если бы вся программа была обёрнута в блок try — catch с этой функцией в качестве catch .

Примечания

Внутренние функции PHP в основном используют отчёт об ошибках, только современные объектно-ориентированные модули используют исключения. Однако ошибки можно легко перевести в исключения с помощью класса ErrorException. Однако эта техника работает только с исправляемыми ошибками.

Пример #1 Преобразование отчётов об ошибках в исключения

function exceptions_error_handler ( $severity , $message , $filename , $lineno ) <
throw new ErrorException ( $message , 0 , $severity , $filename , $lineno );
>

Примеры

Пример #2 Выбрасывание исключения

function inverse ( $x ) <
if (! $x ) <
throw new Exception ( ‘Деление на ноль.’ );
>
return 1 / $x ;
>

try <
echo inverse ( 5 ) . «\n» ;
echo inverse ( 0 ) . «\n» ;
> catch ( Exception $e ) <
echo ‘Выброшено исключение: ‘ , $e -> getMessage (), «\n» ;
>

// Продолжение выполнения
echo «Привет, мир\n» ;
?>

Результат выполнения данного примера:

Пример #3 Обработка исключений с помощью блока finally

function inverse ( $x ) <
if (! $x ) <
throw new Exception ( ‘Деление на ноль.’ );
>
return 1 / $x ;
>

try <
echo inverse ( 5 ) . «\n» ;
> catch ( Exception $e ) <
echo ‘Поймано исключение: ‘ , $e -> getMessage (), «\n» ;
> finally <
echo «Первый блок finally.\n» ;
>

try <
echo inverse ( 0 ) . «\n» ;
> catch ( Exception $e ) <
echo ‘Поймано исключение: ‘ , $e -> getMessage (), «\n» ;
> finally <
echo «Второй блок finally.\n» ;
>

// Продолжение нормального выполнения
echo «Привет, мир\n» ;
?>

Результат выполнения данного примера:

Пример #4 Взаимодействие между блоками finally и return

Читайте также:  Net exited on with error code 1

function test () <
try <
throw new Exception ( ‘foo’ );
> catch ( Exception $e ) <
return ‘catch’ ;
> finally <
return ‘finally’ ;
>
>

Результат выполнения данного примера:

Пример #5 Вложенные исключения

class Test <
public function testing () <
try <
try <
throw new MyException ( ‘foo!’ );
> catch ( MyException $e ) <
// повторный выброс исключения
throw $e ;
>
> catch ( Exception $e ) <
var_dump ( $e -> getMessage ());
>
>
>

$foo = new Test ;
$foo -> testing ();

Результат выполнения данного примера:

Пример #6 Обработка нескольких исключений в одном блоке catch

class MyOtherException extends Exception

class Test <
public function testing () <
try <
throw new MyException ();
> catch ( MyException | MyOtherException $e ) <
var_dump ( get_class ( $e ));
>
>
>

$foo = new Test ;
$foo -> testing ();

Результат выполнения данного примера:

Пример #7 Пример блока catch без указания переменной

Допустимо начиная с PHP 8.0.0

class SpecificException extends Exception <>

function test () <
throw new SpecificException ( ‘Ой!’ );
>

try <
test ();
> catch ( SpecificException ) <
print «Было поймано исключение SpecificException, но нам безразлично, что у него внутри.» ;
>
?>

Пример #8 Throw как выражение

Допустимо начиная с PHP 8.0.0

class SpecificException extends Exception <>

function test () <
do_something_risky () or throw new Exception ( ‘Всё сломалось’ );
>

try <
test ();
> catch ( Exception $e ) <
print $e -> getMessage ();
>
?>

User Contributed Notes 13 notes

If you intend on creating a lot of custom exceptions, you may find this code useful. I’ve created an interface and an abstract exception class that ensures that all parts of the built-in Exception class are preserved in child classes. It also properly pushes all information back to the parent constructor ensuring that nothing is lost. This allows you to quickly create new exceptions on the fly. It also overrides the default __toString method with a more thorough one.

interface IException
<
/* Protected methods inherited from Exception class */
public function getMessage (); // Exception message
public function getCode (); // User-defined Exception code
public function getFile (); // Source filename
public function getLine (); // Source line
public function getTrace (); // An array of the backtrace()
public function getTraceAsString (); // Formated string of trace

/* Overrideable methods inherited from Exception class */
public function __toString (); // formated string for display
public function __construct ( $message = null , $code = 0 );
>

abstract class CustomException extends Exception implements IException
<
protected $message = ‘Unknown exception’ ; // Exception message
private $string ; // Unknown
protected $code = 0 ; // User-defined exception code
protected $file ; // Source filename of exception
protected $line ; // Source line of exception
private $trace ; // Unknown

public function __construct ( $message = null , $code = 0 )
<
if (! $message ) <
throw new $this ( ‘Unknown ‘ . get_class ( $this ));
>
parent :: __construct ( $message , $code );
>

public function __toString ()
<
return get_class ( $this ) . » ‘ < $this ->message > ‘ in < $this ->file > ( < $this ->line > )\n»
. » < $this ->getTraceAsString ()> » ;
>
>
?>

Now you can create new exceptions in one line:

class TestException extends CustomException <>
?>

Here’s a test that shows that all information is properly preserved throughout the backtrace.

function exceptionTest ()
<
try <
throw new TestException ();
>
catch ( TestException $e ) <
echo «Caught TestException (‘ < $e ->getMessage ()> ‘)\n < $e >\n» ;
>
catch ( Exception $e ) <
echo «Caught Exception (‘ < $e ->getMessage ()> ‘)\n < $e >\n» ;
>
>

echo » ;
?>

Here’s a sample output:

Источник

Современная обработка ошибок в PHP

как правильно использовать try catch

Хотя PHP уже давно поддерживает обработку исключений, однако, по сравнению с Java эта поддержка была довольно слабой

Первоначальная поддержка обработки исключений была введена в язык с 5 версии PHP, с двумя простыми встроенными классами исключений — Exception и ErrorException, с поддержкой дополнительных классов через SPL. Идея этого поста состоит в том, чтобы представить читателям современные возможности обработки исключений PHP.

Новый интерфейс

Хотя PHP 7 предоставляет классы Error и Exception, давайте сначала затронем интерфейс Throwable . И Error и Exception классы реализуют Throwable интерфейс — это основа для любого объекта , который может быть брошен с помощью оператора throw. Единственное, что он не может быть реализован непосредственно в классах пользовательского пространства, только через расширение класса Exception. Кроме того, он обеспечивает единую точку для отлова обоих типов ошибок в одном выражении:

Список доступных встроенных классов исключений начиная с PHP 7.4:

Дополнительные классы исключений можно найти в стандартной библиотеке PHP . И наиболее заметным из расширений JSON является класс JsonException.

THROWABLE

Интерфейс Throwable PHP 7:

Вот иерархия Throwable:

В предыдущих версиях PHP ошибки обрабатывались совершенно иначе, чем исключения. Если возникала ошибка, то пока она не была фатальной, она могла быть обработана пользовательской функцией.

Проблема заключалась в том, что было несколько фатальных ошибок, которые не могли быть обработаны определяемым пользователем обработчиком ошибок. Это означало, что вы не могли корректно обрабатывать фатальные ошибки в PHP. Было несколько побочных эффектов, которые были проблематичными, такие как потеря контекста времени выполнения, деструкторы не вызывались, да и вообще иметь дело с ними было неудобно. В PHP 7 фатальные ошибки теперь являются исключениями, и мы можем легко их обработать. Фатальные ошибки приводят к возникновению исключений. Вам необходимо обрабатывать нефатальные ошибки с помощью функции обработки ошибок.

Читайте также:  Php new static error

Вот пример ловли фатальной ошибки в PHP 7.1. Обратите внимание, что нефатальная ошибка не обнаружена.

Этот скрипт выведет сообщение об ошибке при попытке доступа к недопустимой переменной. Попытка вызвать функцию, которая не существует, приведет к фатальной ошибке в более ранних версиях PHP, но в PHP 7.1 вы можете ее перехватить. Вот вывод для скрипта:

Константы ошибок

В PHP много констант, которые используются в отношении ошибок. Эти константы используются при настройке PHP для скрытия или отображения ошибок определенных классов.

Вот некоторые из наиболее часто встречающихся кодов ошибок:

  • E_DEPRECATED — интерпретатор сгенерирует этот тип предупреждений, если вы используете устаревшую языковую функцию. Сценарий обязательно продолжит работать без ошибок.
  • E_STRICT — аналогично E_DEPRECATED, — указывает на то, что вы используете языковую функцию, которая не является стандартной в настоящее время и может не работать в будущем. Сценарий будет продолжать работать без каких-либо ошибок.
  • E_PARSE — ваш синтаксис не может быть проанализирован, поэтому ваш скрипт не запустится. Выполнение скрипта даже не запустится.
  • E_NOTICE — движок просто выведет информационное сообщение. Выполнение скрипта не прервется, и ни одна из ошибок не будет выдана.
  • E_ERROR — скрипт не может продолжить работу, и завершится. Выдает ошибки, а как они будут обрабатываться, зависит от обработчика ошибок.
  • E_RECOVERABLE_ERROR — указывает на то, что, возможно, произошла опасная ошибка, и движок работает в нестабильном состоянии. Дальнейшее выполнение зависит от обработчика ошибок, и ошибка обязательно будет выдана.

Полный список констант можно найти в руководстве по PHP.

Функция обработчика ошибок

Функция set_error_handler() используется, чтобы сообщить PHP как обрабатывать стандартные ошибки, которые не являются экземплярами класса исключений Error. Вы не можете использовать функцию обработчика ошибок для фатальных ошибок. Исключения ошибок должны обрабатываться с помощью операторов try/catch. set_error_handler() принимает callback функцию в качестве своего параметра. Callback-функции в PHP могут быть заданы двумя способами: либо строкой, обозначающей имя функции, либо передачей массива, который содержит объект и имя метода (именно в этом порядке). Вы можете указать защищенные и приватные методы для callable в объекте. Вы также можете передать значение null, чтобы указать PHP вернуться к использованию стандартного механизма обработки ошибок. Если ваш обработчик ошибок не завершает программу и возвращает результат, ваш сценарий будет продолжать выполняться со строки, следующей за той, где произошла ошибка.

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

Если вы запустите этот код в PHP-консоли php -a, вы должны получить похожий вывод:

Самые известные PHP библиотеки , которые делают обширное использование РНР set_error_handler() и могут сделать хорошие представления исключений и ошибок являются whoops, и Symony Debug, ErrorHandler компоненты. Я смело рекомендую использовать один из них. Если не собираетесь их использовать в своем проекте, то вы всегда можете черпать вдохновение из их кода. В то время как компонент Debug широко используется в экосистеме Symfony, Whoops остается библиотекой выбора для фреймворка Laravel .

Для подробного и расширенного использования, пожалуйста, обратитесь к руководству по PHP для обработчика ошибок.

Отображение или подавление нефатальной ошибки

Когда ваше приложение выходит в продакшн, логично, что вы хотите скрыть все системные сообщения об ошибках во время работы, и ваш код должен работать без генерации предупреждений или сообщений. Если вы собираетесь показать сообщение об ошибке, убедитесь, что оно сгенерировано и не содержит информации, которая может помочь злоумышленнику проникнуть в вашу систему.

В вашей среде разработки вы хотите, чтобы все ошибки отображались, чтобы вы могли исправить все проблемы, с которыми они связаны, но в процессе работы вы хотите подавить любые системные сообщения, отправляемые пользователю.

Для этого вам нужно настроить PHP, используя следующие параметры в вашем файле php.ini:

  • display_errors – может быть установлен в false для подавления сообщений
  • log_errors – может использоваться для хранения сообщений об ошибках в файлах журнала
  • error_reporting – можно настроить, какие ошибки вызывают отчет

Лучше всего корректно обрабатывать ошибки в вашем приложении. В производственном процессе вы должны скорее регистрировать необработанные ошибки, чем разрешать их отображение пользователю. Функция error_log() может использоваться для отправки сообщения одной из определенных процедур обработки ошибок. Вы также можете использовать функцию error_log() для отправки электронных писем, но лично вы бы предпочли использовать хорошее решение для регистрации ошибок и получения уведомлений при возникновении ошибок, например Sentry или Rollbar .

Читайте также:  Киберпанк исключение unknown software exception

Существует вещь, называемая оператором контроля ошибок ( @ ), который по своей сути может игнорировать и подавлять ошибки. Использование очень простое — просто добавьте любое выражение PHP с символом «собаки», и сгенерированная ошибка будет проигнорирована. Хотя использование этого оператора может показаться интересным, я призываю вас не делать этого. Мне нравится называть это живым пережитком прошлого.

Больше информации для всех функций, связанных с ошибками PHP, можно найти в руководстве.

Исключения (Exceptions)

Исключения являются основной частью объектно-ориентированного программирования и впервые были представлены в PHP 5.0. Исключением является состояние программы, которое требует специальной обработки, поскольку оно не выполняется ожидаемым образом. Вы можете использовать исключение, чтобы изменить поток вашей программы, например, чтобы прекратить что-либо делать, если некоторые предварительные условия не выполняются.

Исключение будет возникать в стеке вызовов, если вы его не перехватите. Давайте посмотрим на простой пример:

PHP включает в себя несколько стандартных типов исключений, а стандартная библиотека PHP (SPL) включает в себя еще несколько. Хотя вам не нужно использовать эти исключения, это означает, что вы можете использовать более детальное обнаружение ошибок и отчеты. Классы Exception и Error реализуют интерфейс Throwable и, как и любые другие классы, могут быть расширены. Это позволяет вам создавать гибкие иерархии ошибок и адаптировать обработку исключений. Только класс, который реализует класс Throwable, может использоваться с ключевым словом throw. Другими словами, вы не можете объявить свой собственный базовый класс и затем выбросить его как исключение.

Надежный код может встретить ошибку и справиться с ней. Разумная обработка исключений повышает безопасность вашего приложения и облегчает ведение журнала и отладку. Управление ошибками в вашем приложении также позволит вам предложить своим пользователям лучший опыт. В этом разделе мы рассмотрим, как отлавливать и обрабатывать ошибки, возникающие в вашем коде.

Ловля исключений

Вы должны использовать try/catch структуру:

Как видите, есть два предложения catch. Исключения будут сопоставляться с предложениями сверху вниз, пока тип исключения не будет соответствовать предложению catch. Эта очень простая функция throwMyCustomException() генерирует исключение MyCustomException, и мы ожидаем, что оно будет перехвачено в первом блоке. Любые другие исключения, которые произойдут, будут перехвачены вторым блоком. Здесь мы вызываем метод getMessage() из базового класса Exception. Вы можете найти больше информации о дополнительном методе в Exception PHP docs.

Кроме того, можно указать несколько исключений, разделяя их трубой ( | ).

Давайте посмотрим на другой пример:

Этот очень простой блок catch будет перехватывать исключения типа MyCustomException и MyAnotherCustomException.

Немного более продвинутый сценарий:

Это ваш окончательный ответ?

В PHP 5.5 и более поздних, блок finally также может быть указан после или вместо блоков catch. Код внутри блока finally всегда будет выполняться после блоков try и catch независимо от того, было ли выброшено исключение, и до возобновления нормального выполнения. Одним из распространенных применений блока finally является закрытие соединения с базой данных, но, наконец, его можно использовать везде, где вы хотите, чтобы код всегда выполнялся.

Вот хороший пример того, как работают операторы PHP catch/finally:

Функция обработчика исключений

Любое исключение, которое не было обнаружено, приводит к фатальной ошибке. Если вы хотите изящно реагировать на исключения, которые не перехватываются в блоках перехвата, вам нужно установить функцию в качестве обработчика исключений по умолчанию.

Для этого вы используете функцию set_exception_handler() , которая принимает вызываемый элемент в качестве параметра. Ваш сценарий завершится после того, как вызов будет выполнен.

Функция restore_exception_handler() вернет обработчик исключений к его предыдущему значению.

Здесь простая функция exception_handler будет выполняться после блока finally, когда ни один из типов исключений не был сопоставлен. Последний вывод никогда не будет выполнен.

Для получения дополнительной информации обратитесь к документации PHP.

Старый добрый «T_PAAMAYIM_NEKUDOTAYIM»

Вероятно, это было самое известное сообщение об ошибке PHP. В последние годы было много споров по этому поводу. Вы можете прочитать больше в отличном сообщении в блоге от Фила Осетра .

Сегодня я с гордостью могу сказать, что если вы запустите этот код с PHP 7, то сообщение о T_PAAMAYIM_NEKUDOTAYIM больше не будет:

В заключении

Со времени первого внедрения обработки исключений в PHP прошло много лет, пока мы не получили гораздо более надежную и зрелую обработку исключений, чем в Java. Обработка ошибок в PHP 7 получила много внимания, что делает его хорошим, открывая пространство для будущих улучшений, если мы действительно с сегодняшней точки зрения нуждаемся в них.

Веб-разработчик со стажем программирования более 13 лет, постоянно учусь, люблю делать новые проекты.

Источник

Оцените статью
toolgir.ru
Adblock
detector