PHP 5.4 times the call to close

I was just making fun of the intercept class I'm working on. The idea is that you create a class via the Intercept class, and then use that object as if it were the class that you are intercepting. The specified callback is triggered every time the class is called. Here is the code:

<?php
class Intercept {

    protected $class = null;
    protected $callback = null;

    public function __construct($class, $callback = null) {

        $this->class = new $class();
        $this->callback = $callback;
    }

    protected function run_callback() {

        $this->callback();
    }

    public function __get($name) {

        $this->run_callback();
        return $this->class->$name;
    }

    public function __set($name, $value) {

        $this->run_callback();      
        return $this->class->$name = $value;
    }

    public function __isset($name) {

        $this->run_callback();
        return isset($this->class->$name);
    }

    public function __unset($name) {

        $this->run_callback();
        unset($this->class->$name);
    }

    public function __call($method, $args) {

        $this->run_callback();
        return call_user_func_array(array($this->class, $method), $args);
    }

    public function __toString() {

        $this->run_callback();
        return $this->class;
    }

    public function __invoke() {

        $this->run_callback();
        return $this->class();
    }
}

class test {
    public function hello() { 
        return 'world'; 
    }
}

$closure = function() {
    echo 123;
};

$test=new Intercept('test', $closure);
echo $test->hello();

      

Now, running the above code should display 'world123'. But for some strange reason that I can't see it ends up with a timeout. I tried this on my local machine and on various php 5.4 tester sites online. The same thing happens. I narrowed it down to triggering a closure ($ this-> callback ()) in the run_callback () method. If I just remove $ this-> callback () it works fine. Why is this happening?

Edit when I was writing this question I realized that instead of:

$this->callback();

      

This will stop the timeout:

$closure = $this->callback;
$closure();

      

It seems like the __call method is called every time I try to trigger the closure directly from the class properties. Is this the expected behavior or have I stumbled upon apon PHP error?

+3


source to share


1 answer


Pretty sure because you have an infinite loop with a stack of function calls. When you do

$this->callback();

      

You are trying to execute a member function callback()

that does not exist, therefore it is executed __call()

, which tries again callback()

, which does not exist, therefore it __call()

is executed, and so on, etc.

You have to use something along the lines:



call_user_func( $this->callback);

      

Or, as you edited, this will work too:

$closure = $this->callback;
$closure();

      

Hopefully this clears up what's going on. The timeout only happens because you are running out of resources (in this case, time). The main problem is an endless loop.

+4


source







All Articles