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