В предыдущей части этой серии мы узнали, что такое Аспектно-ориентированное программирование (AOP) и значение важной терминологии AOP. В этой части я объясню, почему нам нужен AOP на практических примерах, и как добавить поведение AOP в ваше PHP-приложение с помощью инфраструктуры CodeIgniter.
Практические сквозные проблемы
Во-первых, давайте рассмотрим некоторые сквозные проблемы, которые можно найти практически в каждом веб-приложении.
логирование
Ведение журнала является одной из наиболее важных функций в веб-приложении, поскольку позволяет отслеживать процесс выполнения кода. Когда в живом приложении возникает ошибка, мы не можем изменить какой-либо код, чтобы идентифицировать ошибки. Файлы журналов часто являются единственным доступным ресурсом для поиска этих ошибок.
Запись сообщений журнала в файл или в базу данных является наиболее часто используемым методом. Информация, которую вы записываете в журнал, может отличаться в зависимости от типа приложения и логики, которую вы регистрируете. Некоторые общие моменты, которые стоит уловить, — это вход в функции, возврат из функций и возврат с ошибками.
<?php function addPost() { $log->writeToLog("Entering addPost"); // Business Logic $log->writeToLog("Leaving addPost"); }
Если мы думаем с точки зрения АОП, вышеупомянутая ситуация равна как до, так и после консультации. Следовательно, совет будет наиболее подходящим для ведения журнала.
Аутентификация и авторизация
Аутентификация — это процесс определения подлинности пользователя внутри системы. Мы часто используем имя пользователя и пароль на базовом уровне для аутентификации. Авторизация — это процедура проверки доступа к определенным разделам в системе. Нам нужно применять аутентификацию и авторизацию во многих приложениях.
<?php function addPost() { $authentication->validateAuthentication($user); $authorization->validateAccess($user); // business logic }
Аутентификация и авторизация обычно требуются в начале бизнес-логики. Сначала пользователь должен войти в систему, а затем у него должно быть необходимое разрешение для добавления сообщений. Это общие проблемы, поскольку они должны применяться к определенному набору методов. Нам потребуется предварительная консультация в контексте AOP для аутентификации и авторизации.
Управление транзакциями
Управление транзакциями обеспечивает согласованность и целостность данных в вашей базе данных. Рассмотрим ситуацию, когда у вас есть несколько зависимых функций, которые сохраняют данные в базе данных внутри одного процесса. В случае сбоя одной функции и успешного выполнения других ваша база данных будет повреждена. Следовательно, важно использовать обработку транзакций в каждом приложении.
<?php function addPost() { $tx->beginTransaction(); try{ // Business logic $tx->commit(); } catch (Exception $e) { $tx->rollback(); } }
Мы фиксируем данные, когда все вызовы функций успешно завершены, и выполняем операцию отката в случае сбоя. В контексте АОП это будет до рекомендации, после консультации и после выдачи рекомендации соответственно. До и после советы распространены в большинстве сред АОП. После броска совет можно найти в продвинутых AOP-фреймворках.
Как работает АОП
AOP все еще не пользуется популярностью в сообществе PHP, но полнофункциональные платформы AOP доступны для таких языков, как JAVA. В АОП у нас есть основной класс бизнес-логики с одной стороны и аспекты с другой. Эти аспекты могут быть применены к основным классам во время компиляции или во время выполнения. Фреймворки, такие как AspectJ, применяют AOP во время компиляции. Поскольку PHP является интерпретируемым языком, нам не нужно беспокоиться о применении AOP во время компиляции, и поэтому имеет смысл применять AOP во время выполнения.
Как видите, основная логика и сквозные задачи разделены с помощью двух классов PHP. Затем инфраструктура AOP объединяет классы ядра и аспекта во время выполнения и создает динамический прокси-класс. Динамические классы содержат вызовы функции совета до и после фактического класса метода.
Существует два типа методов, обычно используемых для объединения аспектов с базовой логикой: конфигурация на основе XML и конфигурация на основе аннотаций.
В конфигурациях на основе XML все правила AOP для применения сквозных задач документированы в файле XML.
В конфигурациях на основе аннотаций правила определяются в соответствии с фактическими методами, использующими аннотации. Мы можем использовать предопределенную структуру комментариев к документу, чтобы заменить аннотации в PHP.
Почему CodeIgniter
Вы можете быть удивлены, почему я выбрал CodeIgniter для объяснения AOP, поскольку он не обеспечивает никакой поддержки функциональности AOP. Я сделал это специально для того, чтобы создать базовые функции АОП с нуля, чтобы помочь вам лучше понять концепции и процессы. Если я выберу среду с поддержкой AOP, я смогу объяснить только структуру правил и то, как они работают. Вы не сможете применить свои знания в новых инфраструктурах АОП, так как не понимаете основ. Поскольку здесь мы создаем все с нуля, вы сможете без особых трудностей адаптироваться к любой новой среде или даже когда-нибудь создать свою собственную структуру АОП.
Хуки CodeIgniter — еще одна причина, побудившая меня выбрать именно эту платформу. Когда вызывается метод, вы должны создать прокси-класс. В AOP-средах этот процесс невидим и очень сложен и труден для объяснения. Хуки CodeIgniter позволяют нам запускать пользовательский код в определенных предопределенных точках хуков. Используя это, мы можем запускать пользовательский код при каждом вызове метода и таким образом выполнять функциональные возможности AOP. Я не буду создавать прокси-классы, так как создание такой функциональности требует большого количества кода и выходит за рамки этого руководства.
Использование CodeIgniter Hooks
На веб-сайте CodeIgniter объясняется, что функция перехвата «предоставляет средства для доступа и изменения внутренней работы каркаса без взлома основных файлов». Вы можете включить перехватчики, установив для параметра enable_hooks
в файле конфигурации значение true.
Доступен список предопределенных точек подключения, но я просто собираюсь объяснить, какие крючки необходимы для нашего приложения. Они есть:
-
pre_controller
—pre_controller
непосредственно передpre_controller
любого из ваших контроллеров -
post_controller
—post_controller
сразу после того, как ваш контроллер полностью выполнен
Давайте настроим хук для вызова пользовательского кода.
<?php $hook["pre_controller"] = array( "class" => "AOPCodeigniter", "function" => "applyBeforeAspects", "filename" => "AOPCodeigniter.php", "filepath" => "hooks" );
Поместите приведенный выше код в файл hooks.php
в каталоге config
. Затем создайте класс AOPCodeigniter
в папке application/hooks
. Теперь каждый раз, когда делается запрос, метод applyBeforeAspects()
класса будет вызываться перед фактическим методом контроллера. Это позволит нам объединить до советов с основной логикой (в реальной среде AOP это будет сделано с использованием прокси-класса).
Мы можем использовать следующий код для применения после советов таким же образом, как приведенный выше код:
<?php $hook["post_controller"] = array( "class" => "AOPCodeigniter", "function" => "applyAfterAspects", "filename" => "AOPCodeigniter.php", "filepath" => "hooks" );
Резюме
В этой части серии мы узнали, как определить, где можно использовать AOP, с учетом практических сценариев реальных проектов, и я представил CodeIgniter в качестве контекста для создания основных функций AOP. Теперь, когда мы завершили теоретические разделы, в следующей части я покажу вам, как использовать методы на основе XML и аннотаций для создания собственных структур правил и как обрабатывать эти правила для применения рекомендаций.
Изображение через Fotolia