yceruto / decorator
PHP function decorators
v1.1.0
2024-11-04 04:16 UTC
Requires
- php: >=8.2
- psr/container: ^1.1|^2.0
- symfony/service-contracts: ^2.5|^3
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.64
- phpunit/phpunit: ^11.3
- psr/log: ^1|^2|^3
- symfony/dependency-injection: ^7.1
This package is auto-updated.
Last update: 2024-11-04 04:17:04 UTC
README
Note
Inspired by Python's decorator
This library implements the Decorator Pattern around any PHP callable, allowing you to:
- Execute logic before or after a callable is executed
- Skip the execution of a callable by returning earlier
- Modify the result of a callable
Installation
composer require yceruto/decorator
Usage
use Yceruto\Decorator\Attribute\DecoratorAttribute; use Yceruto\Decorator\CallableDecorator; use Yceruto\Decorator\DecoratorInterface; #[\Attribute(\Attribute::TARGET_METHOD)] class Debug extends DecoratorAttribute { } class DebugDecorator implements DecoratorInterface { public function decorate(\Closure $func): \Closure { return function (mixed ...$args) use ($func): mixed { echo "Do something before\n"; $result = $func(...$args); echo "Do something after\n"; return $result; }; } } class Greeting { #[Debug] public function sayHello(string $name): void { echo "Hello $name!\n"; } } $greeting = new Greeting(); $decorator = new CallableDecorator(); $decorator->call($greeting->sayHello(...), 'John');
Output:
Do something before
Hello John!
Do something after
Decorators
Compound
To create a reusable set of decorators, extend the Compound
class:
use Yceruto\Decorator\Attribute\Compound; #[\Attribute(\Attribute::TARGET_METHOD)] class Greetings extends Compound { /** * @return array<DecoratorAttribute> */ public function getDecorators(array $options): array { return [ new Hello(), new Welcome(), // ... ]; } } class Greeting { #[Greetings] public function __invoke(): void { // ... } }
When the Greeting::__invoke()
method is decorated, the Hello
and Welcome
decorator attributes will be applied
in the specified order. This is equivalent to directly defining #[Hello]
and #[Welcome]
on this method.
License
This software is published under the MIT License