代码之家  ›  专栏  ›  技术社区  ›  Krystian Polska

普通PHP中的AOP,不需要任何PECL扩展(Go!)-怎样

  •  9
  • Krystian Polska  · 技术社区  · 6 年前

    有一个框架称为 Go! Aspect-Oriented Framework for PHP

    它是在普通PHP中制作的,不需要任何PECL扩展和DI容器即可工作。

    此外,还可以与任何现有的PHP框架和库集成(有或没有额外的配置)。

    并且没有切入点的运行时检查,没有运行时注释解析,没有evals和调用方法,没有慢速代理和call\u user\u func\u array()。快速引导过程(2-20ms)和通知调用。

    所以我印象深刻,但我想知道的是,这到底是怎么回事?

    我在这里列出的这些要点。。。

    我查看了github和官方网站,以及其他一些文章,但找不到任何关于这是如何工作的具体信息(一般和具体)。

    我很想知道这是怎么回事?它是如何实施的?

    1 回复  |  直到 6 年前
        1
  •  15
  •   lisachenko    6 年前

    该框架使用了许多隐藏的技巧来执行其工作,但如果我们从鸟瞰的角度来看,则过程可以描述为:

    1. 当前版本的AOP引擎设计为与composer紧密配合,因此它用自己的代理将composer loader包装起来。从那时起,AOP就知道应该加载哪个类以及在哪里查找其源代码。
    2. 当某个班级 Foo 正在从文件加载 Foo.php ,AOP将其包装到特殊的过滤流中,如下所示: include 'php://filter/read=go.source.transforming.loader/resource=Foo.php'; . 有关此流过滤器的更多信息,请访问 'php://stream' manual
    3. 此时,类并没有加载到PHP内存中,但框架已经知道它的内容,可以执行分析,甚至修改源代码。
    4. 然后对源代码进行标记,并通过 nikic/PHP-Parser 库,然后通过以下方式生成此代码的静态反射(仍然没有将此文件加载到PHP内存中) goaop/parser-reflection
    5. 引擎从方面检查所有注册的切入点,并执行原始类的转换 :已重命名为 Foo__AopProxied 和类的新文件 Foo extends Foo__AopProxied 在缓存中生成。
    6. 引擎然后指示autoloader从该新文件而不是原始文件加载该类,这样您就有了原始的类名,但带有来自Advice的附加逻辑。它看起来像是在运行时自动生成装饰器。

    当然,这只是少量的信息,因为在纯PHP中实现AOP是一项非常艰巨的任务,我在发现工作解决方案之前尝试了很多次,因此深入挖掘源代码以发现隐藏的精华可能会很有趣:)我的 PhpSerbia talk about cross-cutting concerns in PHP ,你可以看它以便更好地理解(对不起,我的英语)。

    此外,我们现在正在为框架编写文档,所以如果您想让它变得更好,只需将PR发送给 official documentation .

    您还应该使用PhpStorm插件,它为在PHP项目中使用AOP的开发人员提供了许多功能。