# PHP AOP A minimalistic Aspect-Oriented Programming (AOP) implementation for PHP that uses attributes and Composer's autoloading system to weave aspects into classes at runtime. ## Installation ```bash composer install ``` ## Usage ### Create an Aspect class: ```php namespace Tests\Aspects; use Attribute; #[Attribute(Attribute::TARGET_METHOD)] class MyAspect { public function before(object|string $target, mixed ...$args): void { // $target is the class (for static methods) or object (for instance methods) // Access all parameters before the wrapped function is called var_dump($args); } public function after(object|string $target, mixed $result): mixed { // Access the returned value with $result var_dump($result); // modify the return value, or simply return the unmodified value return $result; } } ``` ### Register all Aspect classes on application bootstrap: ``` ``` $cacheDir = $useCache = false; $weaver = new AspectWeaver( [MyAspect::class], // provide a cache directory to avoid reprocessing class sys_get_temp_dir() . '/cache/php-aop-cache'; // whether to use cache. Disable in dev, enable in production false, // PSR compatible log, for debugging. new NullLogger(), ); // Provide with classes or namespaces will be evaluated for Aspects // trying to evaluate all vendor classes will result in a bad time // at minimum, use withNamespaces to filter your application // classes will be evaluated if they match the list of classes OR belong to the namespace $loader = AspectBuilder::begin() // list of class names ->withClasses([ MyClass::class ]) // namespace prefix ->withNamespaces([ "MyApplication\" ]) ->build($weaver) ->register(); ``` ### Create a class and mark a method with your Aspect class: ```php add(5, 3); /// MyAspect@before will var_dump([5, 3]) /// MyClass@add will echo "Adding 5 + 3\n" /// MyAspect@after will var_dump(8) ``` ## 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]` ## TODO Features that may or may not exist in the future 1. **Around Advice**: Allow aspects to control method execution 2. Demonstrate exception handling 3. Demonstrate Aspect constructor arguments ## References - [okapi-web/php-aop](https://github.com/okapi-web/php-aop) - [goaop/framework](https://github.com/goaop/framework)