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 >> >