2017-01-26 48 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中是一件有趣的事情。 –