Если кто-то работает с GO! Рамки, вы можете мне помочь. Я устанавливаю фреймворк на php 5.3.13. Демо-пример работает. Но мой собственный пример не работает. Аспект (метод beforeMethodExecution) не выполняется.
Вот мой код.
Основной файл:
//1 Include kernel and all classes if (file_exists(__DIR__ .'/../../vendor/autoload.php')) { $loader = include __DIR__ .'/../../vendor/autoload.php'; } // 2 Make own ascpect kernel use Go\Core\AspectKernel; use Go\Core\AspectContainer; class Kernel extends AspectKernel{ /** * Configure an AspectContainer with advisors, aspects and pointcuts * * @param AspectContainer $container * * @return void */ public function configureAop(AspectContainer $container) { } } //3 Initiate aspect kernel $Kernel = Kernel::getInstance(); $Kernel->init(); //4 Include aspect include(__DIR__.'/aspectclass/AspectClass.php'); $aspect = new DebugAspect(); //5 register aspect $Kernel->getContainer()->registerAspect($aspect); //6 Include test class include(__DIR__.'/class/class1.php'); //7 Execute test class $Class = new General('test'); $Class->publicHello();
Файл с тестовым классом:
class General{ protected $message = ''; public function __construct($message) { $this->message = $message; } public function publicHello() { echo 'Hello, you have a public message: ', $this->message, "<br>", PHP_EOL; }
}
Файл с аспектом:
use Go\Aop\Aspect; use Go\Aop\Intercept\FieldAccess; use Go\Aop\Intercept\FunctionInvocation; use Go\Aop\Intercept\MethodInvocation; use Go\Lang\Annotation\After; use Go\Lang\Annotation\Before; use Go\Lang\Annotation\Around; use Go\Lang\Annotation\Pointcut; use Go\Lang\Annotation\DeclareParents; use Go\Lang\Annotation\DeclareError; class DebugAspect implements Aspect{ /** * Method that should be called before real method * * @param MethodInvocation $invocation Invocation * @Before("execution(General->*(*))") * */ public function beforeMethodExecution(MethodInvocation $invocation) { $obj = $invocation->getThis(); echo 'Calling Before Interceptor for method: ', is_object($obj) ? get_class($obj) : $obj, $invocation->getMethod()->isStatic() ? '::' : '->', $invocation->getMethod()->getName(), '()', ' with arguments: ', json_encode($invocation->getArguments()), PHP_EOL; } }
Как вы знаете, go-aop не является расширением PHP, поэтому он не может преобразовать классы, загруженные непосредственно через require
или include
. Внутри он пытается перезаписать исходный код «на лету», но он должен получить элемент управления (путем интеграции с композитором или пользовательским классом автозагрузчика).
Итак, у вас есть ошибка здесь:
//6 Include test class include(__DIR__.'/class/class1.php');
Вы явно загружаете этот класс в память, и нет возможности преобразовать его из пользовательской. Чтобы передать элемент управления структуре, вы должны сделать это явно. Посмотрите на строку AopComposerLoader.php # L99, чтобы понять, как она работает. Здесь мы включаем исходный файл через фильтр источника потока, который передает управление инфраструктуре и может преобразовать класс, чтобы сплести аспекты.
Чтобы исправить ваш пример, просто измените include
на следующее:
include (FilterInjectorTransformer::rewrite(__DIR__.'/class/class1.php'));