PHP高性能的AOP扩展-Xaop

@心欲无痕  September 20, 2018

在PHP语言的AOP扩展中,目前单单有一个 AOP-PHP,再也没有其他的扩展了,并且由于AOP-PHP扩展基于PHP5.2开发, 但是PHP7已经相对于5.2版本而言变化大大,导致AOP-PHP扩展需要进行多个设计上、代码上的重构等,这里应运而生了一款新的扩展AOP:Xaop,Xaop是利用Zend Engine引擎的一款AOP高性能扩展,不需要使用代理对象即可完成AOP切面,并且引入了注释注解文档模式与一个高性能的注释文档解析引擎,进入AOP主题之前我们先来讲讲什么是注释注解:

什么是注释注解?

<?php

/**
 * @Aspect
 */
class Swing
{
}

在上面的示例中,包含有一个注释注解, Aspect,注释注解使用 @字符开头,并且@字符之前不能有其他的字符(除了空白与*字符除外),如果存在其他的字符那么本行就不是一个注释注解单元,每一个注释注解占用一行。如下:

<?php

class Swing
{
    /**
     * @before( value="Xaop", author="Josin" )
     * @after( value="v0.1.1", website="https://www.supjos.cn" )
     */
    public function index() {
    
    }
}

在注释注解单元中可以使用扩展将参数进行包裹,每个参数使用 , 逗号进行分割,如果参数值存在逗号,那么请使用双引号"进行包裹即可。

1、注释注解AOP模式

文档注释注解AOP模式提供两种注解模式:内置注解自定义注解

  • 用户注解
    用户注解必须实现接口: Xaop\Annotations 并且实现方法 input,方法包含有两个参数: $object & $annotations.

如下自定的注解 Tag:

<?php

class Tag implements \Xaop\Annotations
{
    public function input($object, $annotations) {

    }
}

Xaop 解析到一个自定义的注解的时候,会自动调用注解类的 input方法,并且将所需参数传入,用户自己处理逻辑即可。

  • 内置注解
    Xaop 内置7个强大的注解: @api @disable @deprecated @success @failure @before @after

@api: 接口注解,可以将方法内返回的数组格式的数据转换为 JSON 或者 XML 格式,注解包含两个参数: type & charset
@api(type=JSON, charset=UTF-8)

@disable: 将类的方法设置为禁止运行

@deprecated:将类的方法设置为过期方法

@success:修饰类的方法返回true或者数组的时候执行的注释注解

@failure:修饰类的方法返回false或者null的时候执行的注释注解

@before:修饰类的方法运行之前执行的注释注解

@after:修饰类的方法运行之后运行的注释注解

2、方法注入AOP模式

方法注入AOP模式是在方法的执行之前或者之后插入一段代码,来达到切面的目的,目前方法注入模式提供的功能最强,性能也是最佳的一种,先来小瞧一下:

<?php

class Swing
{
    public function index() {
        echo 'yes';
    }
}

Xaop::addBeforeAop(Swing::class, "index", function(){
    echo '_before';
});

$swing = new Swing();
$swing->index();

输出结果如下:

_before yes

方法注入存在五种模式,分别如下:

Xaop 支持 五种 AOP 模式,分别是 前置AOP(addBeforeAop)、后置AOP(addAfterAop)、后置返回AOP(addAfterReturnAop)、后置异常AOP(addAfterThrowAop)、环绕AOP(addAroundAop)

其中 环绕AOP 跟其他的 AOP 互斥,如果存在环绕 AOP ,系统将会优先以 环绕AOP 模式处理,并且 环绕AOP 回调函数存在一个参数: $xaopExec 的一个资源表示当前的方法上下文,环绕AOP模式下,如果不在环绕AOP方法内,调用 :Xaop::exec($xaopExec); 那么实际的方法将会丢失,不会调用,在环绕模式下,实际方法需要开发者自行调用,并且在同个回调方法内,调用多次 Xaop::exec($xaopExec);,仅生效一次,重复调用无效。如:

    Xaop::addAroundAop(NULL, "__get*", function($exec){
        echo '_before<br>';
        Xaop::exec($exec);Xaop::exec($exec); // 此处调用多次,Xaop自动拦截,只执行一次
        echo '_after<br>';
    });

3、属性AOP模式

属性AOP模式正在开发中,敬请期待。


评论已关闭