PHP - статьи

         

Аспектно-Ориентированная Разработка ПО на PHP


В настоящий момент имеется ряд инициативных проектов, авторы которых представили различные способы реализации АОП и PHP. В проекте aoPHP представлен препроцессор PHP, написанный на Java 1.5. Мы можем писать привычный PHP-код, но должны будем сообщать препроцессору о нашем желании приобщения к АОП. Для этого вместо конструкции <?PHP .. ?> мы будем использовать <?AOPHP ?>. Сквозную функциональность мы сможем разместить в отдельных скриптах.

before(): execr(add($x,$y)) | execr(sub($x,$y)){ echo "<font color=red>Im About To Add/Sub $x & $y</font><br>"; }

Эти скрипты при необходимости могут быть задействованы путем указания при декларации кода AOPHP

<?aophp filename="aotest.aophp,aotest2.aophp" debug="off" // PHP code ?>

В проекте Seasar.PHP применен иной путь. Здесь для структурирования деклараций аспектов используется XML, а компоновку производит сам PHP, после чего выполняет результирующий код посредством функции eval().

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

$pointCut = new PointCut(); $pointCut->addJoinPoint('Example', 'Foo'); $pointCut->addJoinPoint('Example', 'Bar'); $test1 = new Aspect($pointCut, before, 'echo "Before $MethodName";'); $test2 = new Aspect($pointCut, after, 'echo "After $MethodName";');

В отличие от библиотеки aop.lib.php в данном решении у вас нет необходимости расставлять "оповещатели" "вручную" для каждой функции. Но придется инсталлировать на сервере дополнительное расширение PHP PECL Classkit.

На мой взгляд, наиболее элегантное решение получилось у авторов проекта PHPAspect. Это стало возможным благодаря эффективному использованию новых возможностей PHP5, в частности, возможности создания абстрактных классов. PHPAspect вводит специальную конструкцию в язык PHP, которая наглядно представляет декларируемый аспект.


aspect TraceOrder{ pointcut logAddItem:exec(public Order::addItem(2)); pointcut logTotalAmount:call(Order->addItem(2)); after logAddItem{ printf("%d %s added to the cartn", $quantity, $reference); } after logTotalAmount{ printf(" Total amount of the cart : %.2f €n", $thisJoinPoint->getObject()->getAmount()); } }

Как видно, в примере область заданного аспекта четко определена. Задание Pointcut и Advice столь лаконично, но емко, что складывается впечатление, будто это "родной" синтаксис PHP. Данный проект предлагает обслуживание событий Join point семи (!) типов: вызов метода (call), выполнение метода (exec), инициализация класса (new), запись в атрибут (set), чтение атрибута (get), деструкция класса (unset) и захват блока (catch). Возможно задание Advice трех типов: before, after, around. Проект позволяет использовать неожиданно гибкие маски для задания областей наблюдения в Pointcut. Так, к примеру, есть возможность задания области для всех классов с заданным префиксом в имени.

new(*(*)); exec(* Order::addItem(2)); call(DataObject+->update(0));

Для установки PHPAspect вам потребуется PHP версии не ниже 5.0.0 и установленные библиотеки PEAR Console_Getopt, Console_ProgressBar, PHP_Beautifier.

Данный проект был с успехом представлен в прошлом году на PHP конференции во Франции (на родине авторов) и, судя по всему, активно развивается и ныне. Вполне возможно, что Zend Inc. обратит на него внимание и учтет этот опыт в следующих версиях PHP.


Содержание раздела