AOP en PHP simple que no requiere ninguna extensión de PECL (¡Vaya!) – ¿Cómo?

Hay un marco llamado Go! Marco orientado a aspectos para PHP

Y está hecho en PHP simple, no requiere ninguna extensión de PECL ni contenedores DI para funcionar.

Lo que es más, se puede integrar con cualquier framework y biblioteca PHP existente (con o sin configuración adicional).

Y no hay controles de tiempo de ejecución de cortes de puntos, no hay análisis de anotaciones de tiempo de ejecución, no hay evals y __call métodos, no hay proxies lentos y call_user_func_array (). Rápido proceso de arranque (2-20ms) e invocación de consejos.

Así que estoy muy impresionado, pero lo que quiero saber es cómo funciona eso realmente.

Estos puntos que he enumerado aquí …

Busqué en github y en el sitio web oficial, y en algunos otros artículos, pero no pude encontrar ninguna información concreta sobre cómo funciona esto (en general y en particular).

Estoy tan ansioso por saber cómo funciona esto? ¿Cómo se implementó?

Este marco utiliza muchos trucos ocultos para realizar su trabajo, pero si observamos desde la vista de las aves, el proceso se puede describir de la siguiente manera:

  1. La versión actual del motor AOP está diseñada para trabajar estrechamente con el compositor, por lo que envuelve el cargador del compositor con su propio proxy. Desde ese momento, AOP sabe qué clase debe cargarse y dónde buscar su código fuente.
  2. Cuando alguna clase Foo está cargando desde el archivo Foo.php , AOP lo envuelve en un flujo de filtro especial como este: include 'php://filter/read=go.source.transforming.loader/resource=Foo.php'; . Puede leer más sobre este filtro de flujo en el manual ‘php: // stream’
  3. En ese momento, la clase no se carga en la memoria de PHP, pero Framework ya conoce su contenido y puede realizar análisis o incluso modificar el código fuente.
  4. El código fuente se tokenizó, se analizó en AST a través de la biblioteca nikic / PHP-Parser y luego se genera la reflexión estática de este código (aún sin cargar este archivo en la memoria de PHP) a través de goaop / parser-reflection
  5. El motor comprueba todos los puntos registrados de aspectos y realiza la transformación de la clase original Foo : se le cambió el nombre a Foo__AopProxied y el nuevo archivo con la clase Foo extends Foo__AopProxied se genera en el caché.
  6. Luego, el motor dirige el autocargador para cargar esta clase desde ese nuevo archivo en lugar del original, de modo que tenga su nombre de clase original, pero con lógica adicional de los consejos. Se parece a la generación decoradora automática en tiempo de ejecución.

Por supuesto, es solo una pequeña cantidad de información, porque la implementación de AOP en PHP puro fue una tarea muy difícil y lo intenté muchas veces antes de descubrir una solución operativa, por lo que puede ser interesante profundizar en el código fuente para descubrir gems ocultas 🙂 Parte de la información También está disponible en mi charla de PhpSerbia sobre las preocupaciones transversales en PHP , puede verlo para una mejor comprensión (lo siento por mi inglés).

También estamos trabajando en la documentación para el marco en este momento, así que si desea mejorarlo, simplemente envíenos un PR a la documentación oficial .

También debe usar el complemento PhpStorm, que proporciona muchas características para los desarrolladores que usan AOP en proyectos PHP.