0

Ok folks, this is what I'm trying to accomplish here.

I want to call a method each time that another method is called, like a middle man.

I'm aware of these magic methods: __call($method, $args) and __callStatic($method, $args) and how they kick in when a method from a class is not accessible or does not exist if it's called.

Ok. Let's say I have this class and all its methods are public (accessible), no problem at all so far but I need to call the middleware() method within all other methods that I require:

class A {

    public function test()
    {
        $this->middleware();

        echo "Test method\n";
    }

    public function middleware()
    {
        echo "Middleware method\n";
    }

}

// [some code]

$foo = new A();
$foo->test(); // Output: Middleware method
              //         Test method

Now, I'd like to call a method, from this class or another inherited one, before $foo->test() body is called.

I know that I can achieve this if I do the next:

class A {

    private function test()
    {
        echo "Test method\n";
    }

    private function middleware()
    {
        echo "Middleware method\n";
    }

    public function __call( $method, $args )
    {
        $this->middleware();
        $this->$method(...$args);
    }

}

// [some code]

$foo = new A();
$foo->test(); // Output: Middleware method
              //         Test method

This way can lead to "force" any developer to write all methods as private or protected. No bueno.

Now, what about if there is a trait (preferably) or class that makes just the requested methods non-accessible?. Something like:

trait ChangeVisibility {

    // ReflectionClass, ReflectionObject?...
    // __constructor(){...}?....
    // Another technique?...
    // ...

}

trait Middleware {

    public function __call( $method, $args )
    {
        $this->middleware();
        $this->$method(...$args);
    }

}

Then use these traits in a class like this:

class A {

    use ChangeVisibility, Middleware;

    public function test()
    {
        echo "Test method\n";
    }

    public function middleware()
    {
        echo "Middleware method\n";
    }

}

// [some code]

$foo = new A();
$foo->test(); // Output?: Middleware method
              //          Test method

Something worth mentioning is that I don't want to follow the container service technique, I hope if I could achieve this without it, just plain classes and traits or another way would be more simple, direct, and maybe "elegant".

This is my limit and I'm in the burndown zone now, that's why I'm reaching out to you.

Thanks to everyone.

4
  • Changing scope in order to trigger some logic seems like a big red flag. What are you actually trying to accomplish here? Why do want to trigger some code when ever any method is run? What's the purpose? The reason I am asking that is I am wondering if a pub/sub, event broadcaster is perhaps better suited, but we don't know what you're actually trying to accomplish. Commented Jun 10, 2021 at 1:07
  • @waterloomatt like I mentioned, I'm trying to address some kind of middleware action at code level (using traits, extending classes...). It's like this, I want to add/use/extend a trait/class to call some method(s) on top of another method call, just like that. I liked what you said about "event broadcaster". Any example? Thanks Commented Jun 10, 2021 at 21:03
  • There are lots of variations out there: observer, pub/sub, event broadcaster,... and each has their use cases. To start, forget about the implementation and focus on what you're try to achieve. Are you trying to notify some parts of your system that an event has occurred? Are you trying to log something useful at various points in your system? Are you just trying to trigger something for learning purposes? Here are some links to get your started, refactoring.guru/design-patterns/observer, symfony.com/doc/current/components/event_dispatcher.html. Commented Jun 14, 2021 at 1:22
  • @waterloomatt I think an event dispatcher is what I need. Ok, I was trying to build my own dispatcher/observer with vanilla PHP for my own learning purposes, something like a "notifier" but I think it's the event dispatcher. I'll take a look a those examples. Thanks bud Commented Jun 14, 2021 at 21:05

0

Browse other questions tagged or ask your own question.