Перейти к содержанию

(PHP) 1.1 Обработчик ошибок. Интерфейсы

Last updated on 17.04.2021

обработчик ошибок

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

«Эталонный» обработчик ошибок

В настоящее время «эталонным» обработчиком ошибок является библиотека Monolog. Возможно вы с ней сталкивались, а может и нет. Данная библиотека реализует PSR-3 стандарт для логирования данных. Конечно логично подробно разобрать эту библиотеку, а затем использовать её в дальнейшей работе. Но мы занимаемся созданием своего ядра. К тому же в этой библиотеке очень много классов, которые использоваться в дальнейшем не будут. Поэтому делаем морду кирпичом. Всех противников велосипедов мысленно отправляем на принять ванну и выпить чашечку кофе. Сами же пишем свой собственный обработчик ошибок.

Кратко о стандарте «PSR-3»

Что же это за зверь? Согласно этому стандарту обработчик ошибок должен реализовать Psr\Log\LoggerInterface . Этот интерфейс предоставляет восемь методов для записи журналов (debug, info, notice, warning, error, critical, alert, emergency), которые соответствуют каждому уровню ошибок.

Каждый метод принимает строку в качестве сообщения или объект, содержащий метода __toString (). Каждый метод принимает массив в качестве контекстных данных. Это предназначено для хранения любой посторонней информации, которая плохо вписывается в строку. Если объект Exception передается в контекстных данных, он должен храниться в массиве под ключом «exception».

Кроме того этот стандарт подразумевает наличие классов-помощников и трейтов. Те и другие расширяют Psr\Log\LoggerInterface .

Собственный обработчик ошибок

Наш обработчик ошибок будет отличаться от стандарта PSR-3. Основное отличие будет состоять в том, что интерфейс Psr\Log\LoggerInterface использован не будет. Вместо него будут реализованы два других интерфейса. Структура обработчика будет таковой:

структура обработчика ошибок
структура обработчика ошибок

FormatInterface — с помощью этого интерфейса объявляются методы, которые в дальнейшем использованы для преобразования записи. Запись может быть представлена в виде строки или же в виде html-кода.

<?php
namespace Hydra\Log\Interfaces;


interface FormatInterface
{
/**
 * Устанавливаем шаблон преобразования записи (напр: строка или html шаблон)
 * @param mixed $set
 * @return mixed
 */
public function setTemplate($set);

/**
 * Получаем шаблон преобразования записи
 * @return string
 */
public function getTemplate(): string;

/**
 * Задаём формат даты
 * @param $set
 * @return mixed
 */
public function setDateFormat($set);

/**
 * Получаем формат даты
 *
 * @return string
 */
public function getDateFormat(): string;

/**
 * Преобразуем все передаваемые данные записи в строковый формат
 *
 * @param  mixed $record
 * @return mixed Преобразованная запись
 */
public function format(array $record);

/**
 * Преобразуем все передаваемые данные набора записей в строковый формат
 *
 * @param array $records
 * @return mixed Набор преобразованных записей
 */
public function formatBatch(array $records);

/**
 * Парсинг шаблона записи и подстановка передаваемых данных
 * @param array $record
 * @return mixed
 */
public function build(array $record);
}

RecordInterface — этот интерфейс объявляет методы, которые в дальнейшем использованы для преобразования записи. С помощью используемых методов в классе будут храниться необходимые данные. Они будут передаваться классу-преобразователю записей.

<?php


namespace Hydra\Log\Interfaces;


use DateTimeZone;

interface RecordInterface
{

    public function __construct(FormatInterface $format,DateTimeZone $timezone = null);

    /**
     * Сохраняем текст сообщения об ошибке
     * @param string $set Текст сообщения
     * @return RecordInterface
     */
    public function setMessage(string $set): RecordInterface;


    /**
     * Получаем текст сообщения
     *
     * @return null | string
     */
    public function getMessage(): ?string;


    /**
     * Устанавливаем уровень ошибки
     * @param int $set Номер уровня ошибки
     * @return RecordInterface
     */
    public function setLevel(int $set): RecordInterface;


    /**
     * Получаем уровень ошибки
     *
     * @return null | int
     */
    public function getLevel(): ?int;


    /**
     * Устанавливаем класс, отвечающий за преобразование записи
     *
     * @param FormatInterface $set Класс отвечающий за преобразование записи согласно шаблону
     * @return RecordInterface
     */
    public function setFormatter(FormatInterface $set): RecordInterface;


    /**
     * Получаем ссылку на класс, отвечающий за преобразование записи
     *
     * @return FormatInterface|null
     */
    public function getFormatter(): ?FormatInterface;

    /**
     * Сохраняем дополнительные данные для записи
     *
     * @param array $set Массив дополнительных данных
     * @return mixed
     */
    public function setExtra(array $set);

    /**
     * Получаем массив дополнительных данных записи
     *
     * @return array
     */
    public function getExtra(): array;

    /**
     * Окончательное формирование записи согласно шаблону
     *
     * @param string $file Имя файла, где произошла ошибка
     * @param string $line Номер строки файла, где произошла ошибка
     * @return mixed
     */
    public function build(string $file, string $line);

}

Сейчас все методы описаны очень кратко. Но при разборе классов, которые реализуют эти интерфейсы, каждый из методов будет рассмотрен подробно. Этот обработчик позволит сохранять информацию о возникших ошибках в лог-файле, а также выводить её в окно браузера при помощи исключений (Exception).

Немного об именах классов и последовательности подключения любых компонентов ядра CMS

Так как подключения всех «.php файлов будет происходить автоматически, то крайне важно следить за порядком их подключения. Он обеспечивается благодаря расположению файлов в папках с определёнными именами и/или именам файлов.

Так в первую очередь подключаются файлы, находящиеся в папке с именем «_function» или «functions». Либо имя файла оканчивается на «Function.php». В этих файлах описываются обычные функции.

Вторыми в очереди стоят интерфейсы. Файлы с интерфейсами должны располагаться в папке «abstract/interface» и/или же имена файлов должны оканчиваться на «Interface.php».

После подключаются итераторы. Файлы с итераторами необходимо расположить в папке «abstract/iterator» и/или же имена файлов должны оканчиваться на «Iterator.php».

Далее следуют трейты Файлы с интерфейсами должны располагаться в папке «abstract/ trait» и/или же имена файлов должны оканчиваться на «Trait.php».

После подключаются файлы с абстрактными классами. Эти «.php» файлы должны располагаться в папке «abstract/class» и/или же имена файлов должны оканчиваться на «Abstract.php».

После подключения файлов с абстрактными классами, очередь доходит до самостоятельных классов. Эти классы не связаны с абстрактными классами или интерфейсами. Хотя в своей работе могут использовать трейты, иные классы и функции. Файлы с этими классами находятся в папке «class» корневой папки компонента ядра и/или имена этих файлов оканчиваются на «Class.php».

В последнюю очередь подключаются все остальные «.php» файлы. Имена этих файлов могут быть какими угодно, но стоит помнить, что порядок их подключения соответствует их расположению относительно друг друга.

Опубликовано в рубрикеЯдро CMS (PHP)1. Ошибки и Исключения