2

在有关超载的手册上,我无法掌握其中一个线程。代码如下:

<?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'
?> 

正如在注释行中指出的那样,它与 hello world 相呼应。但是即使 b 没有被实例化,它是如何被调用的?请帮忙,手册的链接在这里,条目属于gmail dot com 上名为垃圾80 的用户

4

7 回答 7

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';
}
于 2012-08-14T14:01:41.710 回答
4

它是在 A 的 __get 方法中构造的。Get 是一种神奇的方法,当您尝试检索属性时会调用它,请参阅:文档。__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'
于 2012-08-14T14:01:24.683 回答
3

但是 b已经被实例化了!

在 classa的魔术 getter 方法中:

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

稍后调用时的值为$v'b' $a->b。这意味着该行$this->$v = new $v;实际上被评估为等效于:$this->b = new b;,然后return $this->b;

因此,回顾一下,您的 getter 的调用时评估将如下所示:

function __get($v)
{
    $this->b = new b;
    return $this->b;
}
于 2012-08-14T14:02:14.380 回答
2

$b 实际上是实例化的,因为 $a 的属性 $b 是未定义的,并且在调用 $a->$b ... 时,它会使用参数 $v = $b 调用魔术方法 __get,所以行

$this->$b = new $b; 

被执行。

于 2012-08-14T14:02:58.770 回答
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->ba 成为 b 的新实例,然后调用 say 成员函数。

于 2012-08-14T14:02:17.493 回答
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');
于 2012-08-14T14:03:21.077 回答
0

您应该在PHP 文档中查找魔术功能。里面的逻辑__get()是创建并返回一个新的实例b

于 2012-08-14T14:01:52.953 回答