I have been trying to play with the GoAOP library for awhile and have never successfully been able to get it to work. I have gone through the documentation several times and copied examples but haven't even been able to get them to work. All I am trying to achieve right now is a simple aspect.
I have several files as below:
app/ApplicationAspectKernel.php
<?php
require './aspect/MonitorAspect.php';
use Go\Core\AspectKernel;
use Go\Core\AspectContainer;
/**
* Application Aspect Kernel
*/
class ApplicationAspectKernel extends AspectKernel
{
/**
* Configure an AspectContainer with advisors, aspects and pointcuts
*
* @param AspectContainer $container
*
* @return void
*/
protected function configureAop(AspectContainer $container)
{
$container->registerAspect(new Aspect\MonitorAspect());
}
}
init.php
<?php
require './vendor/autoload.php';
require_once './ApplicationAspectKernel.php';
// Initialize an application aspect container
$applicationAspectKernel = ApplicationAspectKernel::getInstance();
$applicationAspectKernel->init(array(
'debug' => true, // Use 'false' for production mode
// Cache directory
'cacheDir' => __DIR__ . '/cache/', // Adjust this path if needed
// Include paths restricts the directories where aspects should be applied, or empty for all source files
'includePaths' => array(__DIR__ . '/app/')
));
require_once './app/Example.php';
$e = new Example();
$e->test1();
$e->test2('parameter');
aspect/MonitorAspect.php
<?php
namespace Aspect;
use Go\Aop\Aspect;
use Go\Aop\Intercept\FieldAccess;
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;
/**
* Monitor aspect
*/
class MonitorAspect implements Aspect
{
/**
* Method that will be called before real method
*
* @param MethodInvocation $invocation Invocation
* @Before("execution(public Example->*(*))")
*/
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()),
"<br>\n";
}
}
app/Example.php
<?php
class Example {
public function test1() {
print 'test1' . PHP_EOL;
}
public function test2($param) {
print $param . PHP_EOL;
}
}
When I run php init.php
it does run but just prints without the output from MonitorAspect. I don't know if I'm defining the pointcut wrong in the @Before
(I've tried several variations) or if I just have a fundamental misunderstanding of how this code is suppose to work.
Any help to point me in the right direction would be greatly appreciated.
GoAOP framework was designed to work with autoloader this means that it can handle only classes that were loaded indirectly via composer autoloader.
When you manually include you class via require_once './app/Example.php';
class is loaded by PHP immediately and could not be transformed by AOP, so nothing happens, because class is already present in the PHP's memory.
In order to make AOP working you should delegate class loading to the Composer
and use PSR-0/PSR-4 standard for your classes. In this case, AOP will hook autoloading process and will perform transformation when needed.
See my answer about how AOP works in plain PHP that doesn't require any PECL-extentions for additional details about internals of the framework. This information should be useful for you.