Using $this in “anonymous” object

断了今生、忘了曾经 提交于 2020-01-02 06:56:06

问题


I am using the following class to mimic anonymous objects in PHP:

class AnonymousObject
{
    protected $methods = array();

    public function __construct(array $options) {
        $this->methods = $options;
    }

    public function __call($name, $arguments) {
        $callable = null;
        if (array_key_exists($name, $this->methods))
            $callable = $this->methods[$name];
        elseif(isset($this->$name))
            $callable = $this->$name;

        if (!is_callable($callable))
            throw new BadMethodCallException("Method {$name} does not exist");

        return call_user_func_array($callable, $arguments);
    }
}

(https://gist.github.com/Mihailoff/3700483)

Now, as long as the declared functions stand on their own everything works fine, but whenever I try to call one function from the other like this ...

$anonymous = new AnonymousObject(array(
    "foo" => function() { $this->bar(); }, 
    "bar" => function() { } 
));

then of course I get Fatal error: Using $this when not in object context

Is there any way to work around this problem?


回答1:


You can use the bind() or bindTo() method of the Closure instance that represents the anonymous function.

<?php
class AnonymousObject
{
    protected $methods = array();

    public function __construct(array $options) {
        $this->methods = $options;
    }

    public function __call($name, $arguments) {
        $callable = null;
        if (array_key_exists($name, $this->methods))
            $callable = $this->methods[$name];
        elseif(isset($this->$name))
            $callable = $this->$name;

        if (!is_callable($callable))
            throw new BadMethodCallException("Method {$name} does not exists");

        $callable = $callable->bindTo($this);
        return call_user_func_array($callable, $arguments);
    }
}

$anonymous = new AnonymousObject(array(
    "foo" => function() { echo 'foo'; $this->bar(); }, 
    "bar" => function() { echo 'bar'; } 
));

$anonymous->foo();

(example not quite right, since it will work only with anonymous functions; not with all the other callable() alternatives like e.g. the $this->name part)

prints foobar.



来源:https://stackoverflow.com/questions/31367735/using-this-in-anonymous-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!