[英]PHP5.3: “Call to undefined method” error when calling invoke from class variable
我一直在使用__invoke magic方法進行一些測試(以替換舊代碼),但我不確定這是否是錯誤:
假設我們有一個類:
class Calc {
function __invoke($a,$b){
return $a*$b;
}
}
以下是可能的,並且可以正常工作:
$c = new Calc;
$k = $c;
echo $k(4,5); //outputs 20
但是,如果我想讓另一個類存儲該對象的實例,則無法正常工作:
class Test {
public $k;
function __construct() {
$c = new Calc;
$this->k = $c; //Just to show a similar situation than before
// $this-k = new Calc; produces the same error.
}
}
當我們嘗試像這樣調用時會發生錯誤:
$t = new Test;
echo $t->k(4,5); //Error: Call to undefined method Test::k()
我知道“解決方案”可能是在Test類(名為k)中具有一個函數,以使用call_user_func_array“轉發”調用,但這並不優雅。
我需要將該實例保留在一個公共類中(出於設計目的),並能夠從其他類中將其作為函數調用...有什么建議嗎?
更新:
我發現了一些有趣的東西(至少出於我的目的):
如果我們將“類變量”分配給局部變量,它將起作用:
$t = new Test;
$m = $t->k;
echo $m(4,5);
PHP認為您要在實例$ t上調用方法k:
$t->k(4, 5)
這是完全合理的。 您可以使用中間變量來調用對象:
$b = $t->k;
$b(4, 5);
另請參見錯誤#50029 ,它描述了您的問題。
當您執行$test->k()
,PHP認為您正在$test
實例上調用一個方法。 由於沒有名為k()
方法,PHP會引發異常。 您想要做的是使PHP返回公共屬性k
並調用它,但是要這樣做,您必須首先將k
分配給變量。 這是取消引用的問題。
您可以將魔術__call
方法添加到Test
類中,以檢查是否存在帶有被調用方法名稱的屬性,並通過以下方式調用該屬性:
public function __call($method, $args) {
if(property_exists($this, $method)) {
$prop = $this->$method;
return $prop();
}
}
我將在調用中添加參數。 您可能還需要檢查屬性是否為is_callable
。
但是無論如何,你可以做
$test->k();
您不能使用方法語法(例如$ foo-> bar())來通過__invoke調用閉包或對象,因為引擎始終認為這是方法調用。 您可以通過__call模擬它:
function __call($name, $params) {
if(is_callable($this->$name)) {
call_user_func_array($this->$name, $params);
}
}
但它不能按原樣工作。
如果您調用$ test-> k(),PHP將在$ test實例上搜索一個名為“ k”的方法,顯然它將引發Exception。
要解決此問題,您可以創建屬性“ k”的吸氣劑
class Test {
public $k;
function __construct() {
$c = new Calc;
$this->k = $c; //Just to show a similar situation than before
// $this-k = new Calc; produces the same error.
}
public function getK() {
return $this->k;
}
}
因此,現在您可以按以下方式使用函子:
$t = new Test();
echo $t->getK()(4,5);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.