Hi again David,

I've been thinking about this some more, it could be quite useful.

I'd like to propose a bit more of a Attributes-y syntax:

```
<?php

#[Decorator(Decorator::TARGET_METHOD)]
// or
#[Attribute(Attribute::DECORATOR_METHOD)]
class Timer
{
    private $start;

    public function __construct(
        private string $name = 'Tim',
    )
    {
        $this->start = microtime(true);

        // these could be made available
        $foo = $this->getObject();
        $args = $this->getArguments(); // [$a, $b]
        $ref = $this->getReflection();
    }

    public function __destruct()
    {
        $end = microtime(true);
        $total = $end - $start;
        echo "Executed {$this->name} in $total second(s)\n";
    }
}

class Foo
{
    #[Timer]
    public function bar($a, $b) { ... }

    #[Timer('Bob')]
    public function baz($a, $b) { ... }
}
```


Thanks,
Peter



On Sat., Mar. 13, 2021, 15:04 David Gebler, <davidgeb...@gmail.com> wrote:

> 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