# PHP AOP - Proof of Concept A minimalistic Aspect-Oriented Programming (AOP) implementation for PHP that uses attributes and Composer's autoloading system to weave aspects into classes at runtime. ## Features - **Attribute-based AOP**: Use custom attributes to mark methods for aspect weaving - **Builder Pattern Configuration**: Fluent API for configuring aspects and classes - **Selective Class Loading**: Only process specified classes, avoiding vendor code - **Multiple Aspect Support**: Register multiple aspect attributes and control which ones are processed - **Reflection-based Weaving**: Uses native PHP Reflection for robust type handling - **Complex Type Support**: Union types, nullable, variadic, by-reference parameters - **Automatic proxy generation**: Hooks into Composer's class loading to generate proxy classes - **Before/After execution**: Methods marked with aspects will execute interceptor code - **Works with public and protected methods**: Full support for method visibility - **Smart Caching**: Generated proxies cached for performance ## How It Works ### Two-Pass Reflection Architecture 1. **Configuration**: Use builder pattern to specify which aspects and classes to process 2. **Class Loading Hook**: Custom autoloader intercepts class loading for registered classes 3. **Use Statement Detection**: Checks if source file imports registered aspect attributes 4. **Two-Pass Loading**: - **Pass 1 (String + eval)**: Rename class, load into memory for reflection analysis - **Pass 2 (Reflection)**: Use native PHP Reflection to inspect method signatures and attributes 5. **Proxy Generation**: Create self-contained proxy file with: - Original class with renamed identifier - Proxy class extending original with aspect methods overridden 6. **Caching**: Generated proxies cached to `/tmp/php-aop-cache` for performance ## Installation ```bash composer install ``` ## Configuration Configure the AspectLoader using the builder pattern in `src/bootstrap.php`: ```php withAspects([Aspect::class]) // Which aspect attributes to process ->withClasses([ // Which classes to weave (avoids vendor code) 'Example\Calculator', 'Example\ComplexExample', ]) ->register(); ``` ## Usage ### 1. Mark methods with aspect attributes ```php add(5, 3); ``` ## Running the Demo ```bash php example/demo.php ``` Expected output: ``` === PHP AOP Demo === 1. Calling add() with Aspect attribute: before Adding 5 + 3 after Result: 8 2. Calling multiply() with Aspect attribute: before Multiplying 4 * 7 after Result: 28 3. Calling subtract() WITHOUT Aspect attribute: Subtracting 10 - 3 Result: 7 4. Calling protected divide() method (with Aspect) via public wrapper: before Dividing 20 / 4 after Result: 5 === Demo Complete === ``` ## Architecture ### Components - **`Aspect.php`**: The attribute class that marks methods for aspect weaving - **`AspectWeaver.php`**: Parses source files and generates proxy classes with aspect behavior - **`AspectLoader.php`**: Hooks into Composer's autoloader to intercept class loading - **`bootstrap.php`**: Initializes the AspectLoader when the autoloader is included ### Proxy Generation Strategy The weaver uses a two-class approach: 1. **Original Class (renamed)**: The original class is included in the proxy file with a modified name (e.g., `__AopOriginal_Calculator`) 2. **Proxy Class**: A new class with the original name that extends the renamed original class and overrides methods marked with `#[Aspect]` This approach ensures: - No modification of source files - Full type safety and IDE support - Debuggability - No runtime performance overhead (after initial proxy generation) ## Limitations (POC) This is a proof of concept with the following limitations: - Only supports `before` and `after` behavior (no around, exception handling, etc.) - Simple regex-based parsing (not a full PHP parser) - Cache clearing requires manual deletion of `/tmp/php-aop-cache` - No support for static methods with static variables - No support for complex method signatures (references, variadic parameters may have issues) ## Extending To extend this POC to support more advanced AOP features: 1. **Custom Aspects**: Create different attribute classes with parameters 2. **Joinpoint Information**: Pass method name, arguments, and execution context to aspect code 3. **Around Advice**: Allow aspects to control method execution 4. **Exception Handling**: Add support for after-throwing and after-returning advice 5. **Performance**: Use a proper PHP parser (like nikic/php-parser) for more robust code analysis ## References - [okapi-web/php-aop](https://github.com/okapi-web/php-aop) - [goaop/framework](https://github.com/goaop/framework)