При возникновении каких-либо ошибок чаще всего просто возвращают false . Затем там, где эта функция была вызвана, можно проверить её результат, и если там false , то выполнить соответствующие действия. Такой подход имеет недостатки (например, если там, где возникла проблема - вовсе не Ваш код, и Вы не знаете, откуда...

Исключения в PHP

При возникновении каких-либо ошибок чаще всего просто возвращают false. Затем там, где эта функция была вызвана, можно проверить её результат, и если там false, то выполнить соответствующие действия. Такой подход имеет недостатки (например, если там, где возникла проблема - вовсе не Ваш код, и Вы не знаете, откуда взялся false). Механизм исключений в PHP позволяет перехватить ошибку во время выполнения кода, которую затем можно обработать в наиболее подходящем месте программы. И что самое важное, данный механизм позволяет получить код ошибки. Давайте разберём механизм исключений в PHP более подробно.

Напишем вот такой код:

<?php
class DataBase {
  private $mysqli;
  public function connect($host, $user, $password, $db) {
    $this->mysqli = @new mysqli($host, $user, $password, $db);
  }
}
$db = new DataBase();
$db->connect("localhost", "root", "", "lesson-local");
?>

Не думаю, что код нуждается в комментировании. Отмечу только наличие оператора "@", который заглушает возможные ошибки. Но теперь представим ситуацию, что пользователь передал в метод connect() неправильные данные. Нам не нужны никакие Warning, выводящиеся через PHP - они испортят дизайн сайта, однако, нам необходимо эти ошибки, тем не менее, обрабатывать. Можно, конечно, написать так:

if ($this->mysqli->connect_errno != 0) return false;

И большинство так и напишет. Но в этом случае мы не сможем понять, а что это была за ошибка? И вот тут как раз приходят на помощь исключения. Задача разработчика класса выбрасывать исключения при некорректных переданных параметрах, а так же сообщать из-за какого именно параметра или что вообще не так работает. А уже обработка этих исключений лежит на стороне клиента:

<?php
class DataBase {
  private $mysqli;
  public function connect($host, $user, $password, $db) {
    $this->mysqli = @new mysqli($host, $user, $password, $db);
    if ($this->mysqli->connect_errno != 0) {
      if ($this->mysqli->connect_errno == 2002) throw new Exception("ERROR_HOST"); // Выбрасываем исключение, если ошибка связана с адресом хоста
      elseif ($this->mysqli->connect_errno == 1044) throw new Exception("ERROR_AUTH"); // Выбрасываем исключение, если ошибка связана с именем пользователя и паролем
      elseif ($this->mysqli->connect_errno == 1049) throw new Exception("ERROR_DB"); // Выбрасываем исключение, если ошибка связана с названием базы данных
    }
  }
}
$db = new DataBase();
try { // "Пытаемся" выполнить код
  $db->connect("localhost", "root", "", "lesson-local");
  echo "Подключение удалось";
} catch (Exception $e) {
  /* В этот блок мы попадаем, если было выброшено исключение */
  echo $e->getMessage(); // Можно вместо этого добавить if и вывести более понятную надпись, чем, например, просто ERROR_HOST
}
?>

Добавлю, что ещё есть и второй параметр у Exception - code. В примере выше мы использовали только параметр message. Так же стоит отметить, что при выбрасывании исключения (то есть при throw new Exception()), PHP будет искать первый try-catch. Например, если бы метод connect() вызывал другой метод, и в этом бы другом методе было выброшено исключение, то PHP сначала бы искал try-catch в этом другом методе, затем, не найдя его, поднялся бы на уровень выше, то есть в метод connect(). Не найдя там try-catch, он поднимется ещё выше, то есть туда, откуда был вызван метод connect(), и если вдруг и там не будет необходимого try-catch, то PHP выдаст Warning.

В следующей статье разберём возможность создания своих собственных классов-исключений.