On 14.03.21 12:52, Benjamin Eberlei wrote:
On Sat, Mar 13, 2021 at 5:51 PM 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?

In my opinion it would be a fantastic addition to Core to be used by
application frameworks with "hook philosophies" that hack this
functionality on top of PHP with code generation or event dispatchers at
the moment (Magento 2, Drupal, Neos, Wordpress and so on) makes this a
potential future with wide adoption. If you'd get 2/3 votes for it is
another topic.


I can fully agree here - this would be very useful and I also thought in trying out something similar to wrap expensive functions by a cache but I don't have enough C skills and even less time for that.


Thanks,

Marc

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to