Decorators are a way of bringing aspect oriented programming into PHP core,
yes, among other uses.  Go AOP is a fairly bulky framework which could be
easily replaced by a Decorator attribute for the purposes of cross-cutting
changes to function behaviour.

Regards,
David

On Sat, Mar 13, 2021 at 10:51 PM Peter Stalman <sarke...@gmail.com> wrote:

> Hi David,
>
> This sounds a lot like Asect Oriented Programming.  Have you looked into
> that?
>
> PHP framework:
> https://github.com/goaop/framework
>
> PECL extension:
> https://aop-php.github.io/
>
> Thanks,
> Peter
>
>
>
> On Sat., Mar. 13, 2021, 08:51 David Gebler, <davidgeb...@gmail.com> wrote:
>
>> With the introduction of attributes in PHP 8, this new behaviour is still
>> quite sparsely documented. Some of the articles I've seen out there,
>> though, liken PHP's attributes to similar constructs in other languages
>> including decorators in Python.
>>
>> Attributes are not the same thing as (Python's concept of) decorators and
>> they shouldn't be confused; a decorator is a function which wraps another
>> function and is automatically called in place of the wrapped function.
>>
>> This isn't currently possible in PHP. Using frameworks like Symfony, we
>> can
>> start to build things like this:
>>
>> class UserProfileController {
>>     #[LoginRequired]
>>     public function editProfile(...) { }
>> }
>>
>> but the logic of enforcing our "require the user to be logged in"
>> decorator
>> relies on the surrounding framework controlling the flow of execution,
>> reading the attribute and deciding whether to call the decorated method
>> editProfile() at all.
>>
>> What we *can't* do is something like this:
>>
>> class Foo {
>>     private function timer(callable $wrapped)
>>     {
>>         $start = microtime(true);
>>         $wrapped();
>>         $end = microtime(true);
>>         $total = $end - $start;
>>         echo "Executed function in $total second(s)\n";
>>     }
>>
>>      #[timer]
>>     public function bar($a, $b) { ... }
>>
>>     #[timer]
>>     public function baz($a, $b) { ... }
>> }
>>
>> What I'm wondering is whether there's a desire / interest for a built-in
>> attribute to provide this kind of behaviour modification.
>>
>> I'm thinking something like
>>
>> class Foo {
>>     private function timer(callable $wrapped) { ... }
>>
>>     #[Decorator([self::class, 'timer'])]
>>     public function bar() {
>>         echo "Bar";
>>     }
>> }
>>
>> Where this would result in any call to $foo->bar() being equivalent to as
>> if the above were defined as:
>>
>> class Foo {
>>     private function timer(callable $wrapped) { ... }
>>
>>      public function __bar() {
>>         echo "Bar";
>>      }
>>
>>     public function bar() {
>>         return $this->timer([$this, '__bar']);
>>     }
>> }
>>
>> I'm not saying I have the skills to implement this attribute (though I'd
>> happily try), I'm not even in a position to propose a draft RFC at this
>> stage, just throwing the idea out there to get a feel for what people
>> think
>> of the concept?
>>
>> Regards,
>> Dave
>>
>

Reply via email to