如何从非实例化的类调用该对象

时间:2012-08-14 13:58:11

标签: php object overloading

关于重载的手册我无法抓住其中一个线程。代码如下:

<?php

class a
{
   function __get($v)
   {
       $this->$v = new $v;
       return $this->$v;
   }
}

class b
{
    function say($word){
        echo $word;
    }
}
$a = new a();
$a->b->say('hello world');

// echos 'hello world'
?> 

正如评论中指出的那样,它呼应着你的世界。但即使b尚未实例化,它是如何被调用的?请帮忙,指向手册的链接是here,条目属于名为垃圾80的用户,位于gmail dot com

7 个答案:

答案 0 :(得分:6)

它的作用:

$a->b

function __get('b'){
    $this->b = new b;
    return $this->b;
}

$a->b->say('hello world')

function say('hello world'){
    echo 'hello world';
}

答案 1 :(得分:4)

它是在A的__get方法中构造的.Get是一个在尝试检索属性时调用的魔术方法,请参阅:documentation。 __get传递作为字符串访问的属性名称。由于该字符串用于实例化一个类然后返回它,因此无效。

以下内容也适用:

class a
{
   function __get($v)
   {
       $this->$v = new $v;
       return $this->$v;
   }
}

class b
{
    function say($word){
        echo $word;
    }
}

class c
{
    function say($word){
        echo 'c: ' . $word;
    }
}
$a = new a();
$a->b->say('hello world');

// echos 'hello world'

$a->c->say('hello world');

// echos 'c: hello world'

答案 2 :(得分:3)

但是b 已经实例化了!

内部课程a的魔法吸气方法:

function __get($v)
{
    $this->$v = new $v;
    return $this->$v;
}

稍后致电$v$a->b的值为'b'。这意味着行$this->$v = new $v;实际上被评估为等同于:$this->b = new b;,然后是return $this->b;

所以回顾一下,你的getter的通话时间评估将如下所示:

function __get($v)
{
    $this->b = new b;
    return $this->b;
}

答案 3 :(得分:2)

$ b实际上是实例化的,因为属性$ b未定义为$ a,当调用$ a-&gt; $ b ...时,它调用带有参数$ v = $ b的魔术方法__get,所以该行

$this->$b = new $b; 

已执行。

答案 4 :(得分:1)

__get方法是一种神奇的方法。每当您尝试在PHP中访问对象的属性,并且未定义该属性时,将使用属性名称作为参数调用__get方法。

所以,在这种情况下你有:

$a->b

b还不是$ a的成员,因此使用b作为参数调用__get。然后运行:

function __get($v) {
     $this->$v = new $v;
     return $this->$v;
 }

将b替换为$ v,所以得到:

$this->b = new b;

这使得$ a-&gt; b成为b的新实例,然后你可以调用say成员函数。

答案 5 :(得分:1)

在此处实例化:$this->$v = new $v;

细分:

创建A对象     $ a = new a();

$b = $a->b;

这会动态调用a::__get

function __get($v)
{
   $this->$v = new $v;
   return $this->$v;
}

这将返回一个b对象,以便您有效地执行:

$b->say('hello world');

答案 6 :(得分:0)

您应该在PHP documentation中查找魔术功能。 __get()中的逻辑是创建并返回b

的新实例