不需要任何PECL扩展名的纯PHP AOP(执行!)-如何? [英] AOP in plain PHP that doesn't require any PECL-extentions (Go!) - How?

查看:93
本文介绍了不需要任何PECL扩展名的纯PHP AOP(执行!)-如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个名为开始的框架! PHP的面向方面的框架

它是用纯PHP制成的,不需要任何PECL扩展名和DI容器即可工作.

And it is made in plain PHP, doesn't require any PECL-extentions and DI-containers to work.

此外,还可以与任何现有的PHP框架和库集成(带有或不带有其他配置).

What's more can be integrated with any existing PHP frameworks and libraries (with or without additional configuration).

并且没有切入点的运行时检查,没有运行时批注解析,没有eval和__call方法,没有慢速代理和call_user_func_array().快速引导过程(2-20毫秒)和建议调用.

And there is no runtime checks of pointcuts, no runtime annotations parsing, no evals and __call methods, no slow proxies and call_user_func_array(). Fast bootstraping process (2-20ms) and advice invocation.

所以我印象非常深刻,但是我想知道的是,它实际上是如何工作的?

So I am very impressed, but what I want to know, is how does that actually work?

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

These points that I listed here...

我查看了github和官方网站,以及其他一些文章,但找不到有关此工作方式的任何具体信息(一般而言和具体而言).

I looked on github and official website, and some other articles but couldn't find any concrete information about how does this work (in general and in specific).

我非常想知道这是如何工作的?它是如何实现的?

I'm so eager to know how does this work? How it was implemented?

推荐答案

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

This framework is using many hidden tricks to perform its job, but if we look from the bird's view, then process can be described as following:

  1. 当前版本的AOP引擎旨在与作曲家紧密合作,因此它使用自己的代理包装作曲家加载器.从那时起,AOP知道应该加载哪个类以及在何处查找其源代码.
  2. 从文件Foo.php中加载某个类Foo时,AOP会将其包装到特殊的过滤器流中,如下所示:include 'php://filter/read=go.source.transforming.loader/resource=Foo.php';.您可以在'php://stream'手册中了解有关此流过滤器的更多信息.
  3. 那时,类尚未加载到PHP内存中,但是框架已经知道它的内容,并且可以执行分析甚至修改源代码.
  4. 然后对源代码进行标记,并通过 nikic/PHP-Parser 库解析为AST,然后将其静态化通过 goaop/parser-reflection
  5. Engine从各个方面检查所有已注册的切入点,并执行原始类Foo的转换:将其重命名为Foo__AopProxied,并在缓存中生成类为Foo extends Foo__AopProxied的新文件.
  6. 然后,
  7. 引擎直接引导自动加载器从该新文件而不是原始文件中加载此类,因此您拥有原始的类名称,但带有建议中的其他逻辑.看起来像在运行时自动生成装饰器.
  1. Current version of AOP engine is designed to work tightly with composer, so it wraps composer loader with own proxy. From that point of time, AOP knows about which class should be loaded and where to look for its source code.
  2. When some class Foo is loading from file Foo.php, AOP wraps it into special filter stream like this: include 'php://filter/read=go.source.transforming.loader/resource=Foo.php';. You can read more about this stream filter at 'php://stream' manual
  3. At that point of time, class is not loaded into PHP memory, but framework already knows about it's content and can perform analysis or even modification of source code.
  4. Source code then tokenized, parsed into AST via nikic/PHP-Parser library and then static reflection of this code is generated (still without loading this file into PHP's memory) via goaop/parser-reflection
  5. Engine checks all registered pointcuts from aspects and performs transformation of original class Foo: it's renamed to Foo__AopProxied and new file with class Foo extends Foo__AopProxied is generated in cache.
  6. Engine then direct autoloader to load this class from that new file instead of original one, so you have your original class name, but with additional logic from advices. It's look like automatic decorator generation in runtime.

当然,这只是很少的信息,因为在纯PHP中实现AOP是一项艰巨的任务,在发现有效的解决方案之前,我尝试了很多次,因此,深入研究源代码以发现隐藏的gems可能会很有趣: )一些信息也可以在我的 PhpSerbia讨论有关PHP跨领域关注的问题中,您可以观看以便更好地理解(对不起我的英语).

Of course, it's only small amount of information, because implementing of AOP in pure PHP was very hard task and I tried many times before discovering of working solution, so it can be interesting to dig into source code to discover hidden gems :) Some information is also available in my PhpSerbia talk about cross-cutting concerns in PHP, you can watch it for better understanding (sorry for my English).

我们现在也正在为框架编写文档,因此,如果您想使其更好,只需将PR发送给我们

Also we are working on documentation for framework right now, so if you want to make it better, just send us a PR to the official documentation.

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

You should also use PhpStorm plugin, which provides many features for developers that use AOP in PHP projects.

这篇关于不需要任何PECL扩展名的纯PHP AOP(执行!)-如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆