我有一些PHP cruft我想委托方法。一个穷人的混合物。
基本上我想要以下内容:
<?php
class Apprentice
{
public function magic() {
echo 'Abracadabra!';
}
}
class Sourcerer // I work magic with the source
{
private $apprentice;
public function __construct(){
$this->apprentice = new Apprentice();
}
public function __get($key) {
if (method_exists($this->apprentice, $key)) {
return $this->apprentice->{$key};
}
throw Exception("no magic left");
}
}
$source = new Sourcerer();
$source->magic();
?>
不要抛出Fatal error: Call to undefined method Sourcerer::magic() in .../test__get.php
。
答案 0 :(得分:9)
public function __call($name, $args) {
if (method_exists($this->apprentice, $name)) {
return $this->apprentice->$name($args);
}
throw Exception("no magic left");
}
ps:使用__call
作为方法,因为__get
仅适用于属性。
是的,最好使用call_user_func_array
,否则将参数作为数组提供给magic
函数。
return call_user_func_array(array($this->apprentice, $name), $args);
答案 1 :(得分:3)
要在apprentice
上实际调用该方法,您必须实际调用它:
return $this->apprentice->$key();
您正在使用$source->magic()
,它不会调用__get
方法。 __get
用于$source->magic
等变量访问,但$source->magic()
是函数调用。如果你想要一个魔术方法来进行函数调用,那就是__call
。
答案 2 :(得分:2)
更像是__call
而不是__get
:
class Sourcerer // I work magic with the source
{
private $apprentice;
public function __construct(){
$this->apprentice = new Apprentice();
}
public function __call($name, $arguments) {
if (method_exists($this->apprentice, $name)) {
return call_user_func_array(array($this->apprentice, $name), $arguments);
}
throw Exception("no magic left");
}
}
答案 3 :(得分:1)
您的电话将改为:
$source = new Sourcerer();
$source->apprentice->magic();
另外,我相信__get()
魔术方法适用于属性,而不适用于方法名称。
最后,在您的实际__get()
定义中,语法错误:它应该是throw new Exception('message');
。我还将其移至else
子句,否则无论如何都会触发每个调用,因为它超出任何if
/ else
或其他逻辑。