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

Вступление

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

В чём разница между ошибками и исключениями?

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

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

Как эти процессы протекают в Yii?

В Yii, не фатальные PHP ошибки (заметки и предупреждения) отлавливаются, что даёт возможность должным образом на них среагировать. Все эти исключения могут направляться на определённый экшен контроллера. Также вы можете повлиять на формат отображения данных ошибок: HTML, JSON, XML и т.д.

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

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

К примеру:

$t = new Unknownobject();

Давайте же рассмотрим парочку примеров, где мы покажем как можно отловить ошибки/исключения, и обработать их.

Конфигурация обработчика ошибок и исключений

Для начала нам нужно внести кое-какие записи в файл конфигурации frontend/config/main.php. Как показано ниже, в этом файле определён компонент errorHandler. Взгляните на конфигурацию errorHandler в разделе components:

<?php
$params = array_merge(
    require(__DIR__ . '/params.php'),
    require(__DIR__ . '/params-local.php')
);
return [
    'id' => 'mp-frontend',
    'name' => 'Meeting Planner',
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log','\common\components\SiteHelper'],
    'controllerNamespace' => 'frontend\controllers',
    'catchAll'=> [],
    'components' => [
      'assetManager' => [...],
      ...
      'errorHandler' => [
            'errorAction' => 'site/error',
            'maxSourceLines' => 20,
        ],
        ...
    ],
];

В вышеприведённом примере определено, что при возникновении ошибки errorAction направит пользователя на экшен error SiteController-а.

Если более подробно, то Yii предлагает целый ряд конфигурационных настроек к компоненту errorHandler для редиректа и обработки информации:

Свойство Тип Описание
$callStackItemView строка Путь к файлу, в котором будет происходить рендеринг информации об ошибках. Пример: '@yii/views/errorHandler/callStackItem.php'
$displayVars массив Список определённых PHP переменных, которые должны отображаться в специальной секции отображения ошибок. Примеру: ['_GET', '_POST', '_FILES', '_COOKIE', '_SESSION']
$errorAction строка Маршрут (site/error) к контроллеру и экшену в котором будут обрабатываться ошибки.
$errorView строка Путь к файлу, в котором будет происходить рендеринг информации об ошибках без подробного описания. Пример: '@yii/views/errorHandler/error.php'
$exceptionView строка Путь к файлу, в котором будет происходить рендеринг информации об исключениях. Пример: '@yii/views/errorHandler/exception.php'
$maxSourceLines число Максимальное число отображаемого исходного кода.
$maxTraceSourceLines число Максимальное число отображаемого исходного трэйс-кода.
$previousExceptionView строка Путь к файлу, в котором будет происходить рендеринг информации о предыдущем исключении. Пример: '@yii/views/errorHandler/previousException.php'

Прямой вызов errorActions

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

Как раз-таки это и происходит в экшене errorAction класса errorHandler. С этой точки мы и будем направлены на SiteController -> actionError:

return [
    'components' => [
        'errorHandler' => [
            'errorAction' => 'site/error',
        ],
    ]
];

Определим экшен error в SiteController:

namespace app\controllers;

use Yii;
use yii\web\Controller;

class SiteController extends Controller
{
    public function actions()
    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
        ];
    }
}

Вот так вот будет выглядеть обработка ошибки (ссылка на более подробную информацию):

public function actionError()
{
    $exception = Yii::$app->errorHandler->exception;
    if ($exception !== null) {
        return $this->render('error', ['exception' => $exception]);
    }
}

Также вы можете точно определить, возникла ли ошибка или в вашем приложении не существует запрашиваемого маршрута:

public function actionError()
{
    $exception = Yii::$app->errorHandler->exception;
    if ($exception instanceof \yii\web\NotFoundHttpException) {
        // all non existing controllers+actions will end up here
        return $this->render('pnf'); // page not found
    } else {
      return $this->render('error', ['exception' => $exception]);
    }
}

Вот мой обработчик ошибки Page Not Found 404:

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

Вот моя страница с отображением ошибки (конечно же над ней нужно ещё работать и работать):

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

Для обработки исключений можем воспользоваться PHP-шной конструкцией try catch. Давайте посмотрим пример в котором разделим число на ноль:

use Yii;
use yii\base\ErrorException;

...

    try {
        10/0;
    } catch (ErrorException $e) {
        Yii::warning("Division by zero.");
    }

...

В блоке catch запишем предупреждение в лог. В Yii есть несколько методов логирования:

  • Yii::trace(): сообщение с куском кода. Обычно используется во время разработки.
  • Yii::info(): информационное сообщение.
  • Yii::warning(): предупреждение о каком-то событии
  • Yii::error(): сообщение о фатальной ошибке

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

use yii\web\NotFoundHttpException;

throw new NotFoundHttpException();

Вот пример в котором мы выбрасываем исключение с определённым HTTP кодом и специальным сообщением:

try {
    10/0;
} catch (ErrorException $e) {
  throw new \yii\web\HttpException(451,
      'Tom McFarlin\'s humor is often lost on me
          (and lots of people).');
}

А вот что в этом случае увидит пользователь:

О логировании в Yii

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

Заключение

Надеюсь, что мне удалось раскрыть тему, и должным образом показать процесс обработки ошибок и исключений.

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: https://code.tutsplus.com/tutorials/how-to-handle-errors-exceptions-in-the-yii-framework--cms-28531
Перевел: Станислав Протасевич
Урок создан: 20 Апреля 2017
Просмотров: 1091
Правила перепечатки


5 последних уроков рубрики "PHP"

  • Фильтрация данных с помощью zend-filter

    Когда речь идёт о безопасности веб-сайта, то фраза "фильтруйте всё, экранируйте всё" всегда будет актуальна. Сегодня поговорим о фильтрации данных.

  • Контекстное экранирование с помощью zend-escaper

    Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.

  • Подключение Zend модулей к Expressive

    Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение. В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.

  • Совет: отправка информации в Google Analytics через API

    Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.

  • Подборка PHP песочниц

    Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.

^ Наверх ^