2017-01-04 17 views
3

我不知道這是錯誤還是正常。比方說,我有一些神奇的功能類:爲什麼PHP`__invoke`在從對象屬性觸發時無法工作

class Foo { 
    public function __toString() { 
     return '`__toString` called.'; 
    } 
    public function __get($key) { 
     return '`__get(' . $key . ')` called.'; 
    } 
    public function __invoke($x = "") { 
     return '`__invoke(' . $x . ')` called.'; 
    } 
} 

然後在這樣一個對象的屬性創建一個實例:

$object = (object) [ 
    'foo' => 'bar', 
    'baz' => new Foo 
]; 

然後對其進行測試:

echo $object->baz; 
echo $object->baz->qux; 
echo $object->baz('%'); // :(

這是在最後一個回聲中斷了:Call to undefined method stdClass::baz()

目前,唯一的解決方案,我可以做我S到__invoke部分存儲在一個臨時變量,然後調用該變量作爲這樣的功能:

$x = $object->baz; 
echo $x('%'); // :) 

它正常工作時,我實例化一個數組屬性的類:

$array = [ 
    'baz' => new Foo 
]; 

echo $array['baz']; 
echo $array['baz']->qux; 
echo $array['baz']('%'); // :) 

由這樣,我需要我的對象上這種能力的東西相關的API:

$foo = (object) ['bar' => new MyClass]; 
  • echo $foo->bar;→應觸發__toString
  • echo $foo->bar->baz;→應觸發__get
  • echo $foo->bar();→應觸發__invoke
  • echo $foo->bar->baz();→應觸發__call

他們都應該返回一個字符串。

這完全可以在PHP中完成嗎?謝謝。

+1

有趣的問題,我不知道它是否是php的缺陷,就像在[文檔](http://php.net/manual/en/language.oop5.magic.php#object.invoke)中建議的其中一個貢獻調用類中的類會引發錯誤。 –

+2

等待,實際上你不需要把它暫時放在某個地方,'echo($ object-> baz)('%')'起作用。 –

+0

@Bagus Tesa您使用的是什麼PHP版本?我剛在第22行的I:\ server \ www \ test.php中出現錯誤:語法錯誤,意外'(',expect','或';')。 **。 –

回答

2

不可以。

有問題的線條很模糊,錯誤消息告訴你如何...嘗試訪問$object對象的baz()方法更符合邏輯。
這只是由解析器給定的背景下,當它看到$object->baz()

在評論中已經提到,您可以刪除不確定性,告訴它該$object->baz本身是一個需要首先被執行的表達式幫助解析器:

($object->baz)('arg'); 

PHP本身也是一個程序,在執行它之前必須知道如何執行某些操作。如果它可以盲目地在$foo->bar->baz->qux鏈中的每個對象上嘗試每種可能的「魔術」方法,那麼它將無法告訴你遇到什麼錯誤 - 它只會靜悄悄地崩潰。

+0

括號語法在將來看起來很有希望。 –

+2

是的,它只是'$ var = $ object-> baz; $ var('arg');'的縮寫,它在PHP 7之前不起作用,但是您應該儘快轉向ASAP。 – Narf

相關問題