Статьи

Исключения PHP: попробуйте Catch для обработки ошибок

В этом посте вы узнаете, как использовать обработку исключений в PHP. Начиная с PHP 5, мы можем использовать блоки try catch для обработки ошибок — это лучший способ обработки исключений и управления потоком вашего приложения. В этой статье мы рассмотрим основы обработки исключений вместе с парой реальных примеров.

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

Здесь важно отметить, что обработка исключений отличается от обработки ошибок. При обработке ошибок мы можем использовать функцию set_error_handler для установки нашей пользовательской функции обработки ошибок, чтобы при каждом set_error_handler нашу пользовательскую функцию обработки ошибок. Таким образом, вы можете контролировать ошибки. Однако, как правило, некоторые виды ошибок являются неустранимыми и останавливают выполнение программы.

С другой стороны, исключения генерируются намеренно кодом, и ожидается, что они будут обнаружены в какой-то момент в вашем приложении. Таким образом, мы можем сказать, что исключения восстанавливаются, в отличие от определенных ошибок, которые невозможно исправить. Если выбрасываемое исключение обнаруживается где-то в вашем приложении, выполнение программы продолжается с того места, где было обнаружено исключение. И исключение, которое нигде не встречается в вашем приложении, приводит к ошибке, что останавливает выполнение программы.

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

Обработка исключений в блоке try catch

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
// code before the try-catch block
 
try {
  // code
 
  // if something is not as expected
      // throw exception using the «throw» keyword
 
  // code, it won’t be executed if the above exception is thrown
} catch (Exception $e) {
  // exception is raised and it’ll be handled here
  // $e->getMessage() contains the error message
}
 
// code after the try-catch block, will always be executed

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

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

Исключение может быть вызвано вызываемой вами функцией, или вы можете использовать ключевое слово throw, чтобы вызвать исключение вручную. Например, вы можете проверить некоторые входные данные перед выполнением какой-либо операции и выдать исключение, если данные неверны.

Здесь важно отметить, что если вы сгенерируете исключение, но не определили блок catch который должен обрабатывать это исключение, это приведет к фатальной ошибке. Поэтому вам нужно убедиться, что вы всегда определяете блок catch если вы генерируете исключения в своем приложении.

Как только исключение перехватывается в блоке catch , объект Exception содержит сообщение об ошибке, которое было выдано с использованием ключевого слова throw . Переменная $e в приведенном выше примере является экземпляром класса Exception , поэтому она имеет доступ ко всем методам этого класса. В этом блоке вы должны определить свою собственную логику обработки исключений что именно вы хотите сделать с ошибкой, которую вы поймали.

В следующем разделе мы рассмотрим реальный пример, чтобы понять, как работает обработка исключений.

В этом разделе мы создадим реальный пример, чтобы продемонстрировать обработку исключений в PHP.

Давайте предположим, что вы создали приложение, которое загружает конфигурацию приложения из файла config.php . Теперь важно, чтобы файл config.php присутствовал при загрузке приложения. Таким образом, ваше приложение не может работать, если файл config.php отсутствует. Так что это идеальный вариант использования, чтобы вызвать исключение и сообщить пользователю, что он должен решить проблему.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<?php
try {
    // init bootstrapping phase
 
    $config_file_path = «config.php»;
 
    if (!file_exists($config_file_path))
    {
      throw new Exception(«Configuration file not found.»);
    }
  
    // continue execution of the bootstrapping phase
} catch (Exception $e) {
    echo $e->getMessage();
    die();
}
?>

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

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

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

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

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

Давайте вернемся к предыдущему примеру, как показано в следующем фрагменте.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
class ConfigFileNotFoundException extends Exception {}
 
try {
    // init bootstrapping phase
 
    $config_file_path = «config.php»;
 
    if (!file_exists($config_file_path))
    {
      throw new ConfigFileNotFoundException(«Configuration file not found.»);
    }
  
    // continue execution of the bootstrapping phase
} catch (ConfigFileNotFoundException $e) {
    echo «ConfigFileNotFoundException: «.$e->getMessage();
    // other additional actions that you want to carry out for this exception
    die();
} catch (Exception $e) {
    echo $e->getMessage();
    die();
}
?>

Во-первых, мы определили класс ConfigFileNotFoundException , который расширяет класс Exception по умолчанию. Теперь он становится нашим пользовательским классом исключений, и мы можем использовать его, когда хотим ConfigFileNotFoundException исключение ConfigFileNotFoundException в нашем приложении.

Затем мы использовали ключевое слово throw, чтобы ConfigFileNotFoundException исключение ConfigFileNotFoundException если файл config.php не существует. Важное отличие заключается в блоке catch , однако. Как видите, мы определили два блока catch , и каждый блок используется для перехвата различных типов исключений.

Первый перехватывает исключения типа ConfigFileNotFoundException . Таким образом, если выбрасываемое исключение относится к типу ConfigFileNotFoundException , этот блок будет выполнен. Если тип исключения не соответствует ни одному из определенных блоков catch , он будет соответствовать последнему, который будет перехватывать все общие сообщения об исключениях.

В этом разделе мы расскажем, как использовать ключевое слово finally вместе с блоками try и catch . Иногда вы хотите выполнить фрагмент кода независимо от того, было ли выброшено исключение. Здесь вы можете использовать блок finally , так как код, который вы помещаете в блок finally, всегда будет выполняться после выполнения блоков try и catch, независимо от того, было ли создано исключение.

Давайте попробуем понять это на следующем примере.

01
02
03
04
05
06
07
08
09
10
11
12
13
try {
  // code
 
  // if something is not as expected
      // throw exception using the «throw» keyword
 
  // code, it won’t be executed if the above exception is thrown
} catch (Exception $e) {
  // exception is raised and it’ll be handled here
  // $e->getMessage() contains the error message
} finally {
  // code, it’ll always be executed
}

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

Типичные сценарии использования блока finally обычно связаны с очисткой ресурса. Например, если вы открыли соединение с базой данных или файл на диске в блоке try , вы можете выполнить такие задачи очистки, как закрытие соединения в блоке finally поскольку он гарантированно будет работать.

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

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