2017-01-26 130 views
1
<?php 

class foo 
{ 
    private $callVar = false; 
    private $constructorVar = false; 

    public function __construct() 
    { 
     $this->constructorVar = get_class($this); 
    } 

    public function __call($methodName, $arguments) 
    { 
     $this->callVar = get_class($this); 
     call_user_func_array(array($this, $methodName), $arguments); 
    } 

    protected function method($params) 
    { 
     echo('<br>Call var: '.$this->callVar.'<br>Constructor var: '.$this->constructorVar); 
    } 
} 

class foo_sec extends foo 
{ 
    protected function method($params) 
    { 
     echo 'First call: '; 
     parent::method($params); 
     echo '<br> Second call: '; 
     $test = new foo_trd(); 
     $test->method('param2'); 
    } 
} 

class foo_trd extends foo 
{ 

} 

$m = new foo_sec(); 
$m->method('param'); 

?> 

內實例給出了這樣的結果:PHP call_user_func_array例如

First call: 
Call var: foo_sec 
Constructor var: foo_sec 
Second call: 
Call var: 
Constructor var: foo_trd 

此代碼應返回當前正在運行的實例的名稱,但如果實例是另一個實例中,類名是空的在第二個。這是一個PHP錯誤或我缺少的其他問題?

換句話說,第二次調用中的Call var應該是foo_trd - 不爲空。

+0

你的問題並不在於call_user_func_array(),而是使用php調用magic函數__call。 – Rahi

+0

@Rahi但是爲什麼?這是一個全新的例子 – dfilkovi

+0

@RyanVincent我已經使用另一種方法解決了它,但我徘徊爲什麼這不是正確的工作原因它應該 – dfilkovi

回答

0

我相信你對PHP和它的inheritance visibility感興趣。

總之,當你在裏面和實例的Foo您可以訪問所有其他實例也延長Fooprotectedprivate範圍。由於您可以直接訪問protected method(),因此您將跳過__call()

這實際上是有用的,當你想讓你的構造函數私有並強制工廠。

+0

但在foo_sec裏面我創建了一個新的實例,這應該作爲它自己的實例來處理,沒有回想一下創建它的實例。 – dfilkovi

+0

我接受這個答案,因爲這個鏈接到PHP文檔說明這是正常的PHP行爲 – dfilkovi

+0

由於兩個實例繼承了一個共同的父母,他們是「相關的」。有一個很好的方法來實現工廠模式,方法是使'__construct'方法protected/private,並強制使用'public static create()'(或類似的)函數來構造它。但是,是的,它在PHP中是一件有趣的事情。 –