【问题标题】:GoAOP framework, can't get simple Aspect to workGoAOP 框架,无法让简单的 Aspect 工作
【发布时间】:2018-01-25 06:55:48
【问题描述】:

我一直在尝试使用GoAOP 库,但从未成功地让它工作。我已经多次浏览documentation 并复制了示例,但甚至无法让它们工作。我现在想要实现的只是一个简单的方面。

我有几个文件如下:

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');

方面/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;
    }
}

当我运行php init.php 时,它会运行,但只是在没有 MonitorAspect 输出的情况下打印。我不知道我是否在 @Before 中定义了错误的切入点(我尝试了几种变体),或者我只是对这段代码的工作方式有根本的误解。

任何能帮助我指明正确方向的人都将不胜感激。

【问题讨论】:

    标签: goaop


    【解决方案1】:

    GoAOP 框架旨在与自动加载器一起使用,这意味着它只能处理通过 Composer 自动加载器间接加载的类。

    当您通过require_once './app/Example.php'; 手动包含您的类时,PHP 会立即加载该类,并且无法通过 AOP 进行转换,因此没有任何反应,因为类已经存在于 PHP 的内存中。

    为了使 AOP 正常工作,您应该将类​​加载委托给 Composer,并为您的类使用 PSR-0/PSR-4 标准。在这种情况下,AOP 会钩住自动加载过程,并在需要时进行转换。

    有关框架内部的更多详细信息,请参阅我对 how AOP works in plain PHP that doesn't require any PECL-extentions 的回答。这些信息应该对您有用。

    【讨论】:

    • 自动加载类而不是要求它们确实解决了问题,谢谢。在您的回答中,您说该库仅适用于自动加载器,然后专门说作曲家自动加载器。它是否必须来自作曲家,或者如果我要创建自己的自动加载器类来注册这些类仍然可以工作?
    • 默认只支持composer,但如果你有自己的逻辑,你可以很容易地采用来自AopComposerLoader的代码。主线是当你找到文件名时,然后用FilterInjectorTransformer::rewrite($file); 包装它
    猜你喜欢
    • 1970-01-01
    • 2013-09-23
    • 2014-12-21
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    • 2015-07-09
    • 2013-01-06
    • 1970-01-01
    相关资源
    最近更新 更多