任何知道php内幕的人都能解释一下这样的PHP行为吗?
<?php
class Test {
private $a;
public function __get($name) {
echo('GETTER CALLED!');
return null;
}
public function testme() {
$v = array(1, 2, 3);
unset($this->a); // <-- this line *
$this->a = &$v;
}
}
$test = new Test();
$test->testme();
当unset($this->a)
在这里(即没有注释掉)时,php导致以下输出错误:
GETTER CALLED!<br />
<b>Notice</b>: Indirect modification of overloaded property Test::$a has no effect in <b>[...][...]</b> on line <b>15</b><br />
<br />
<b>Fatal error</b>: Uncaught Error: Cannot assign by reference to overloaded object in [...][...]:15
Stack trace:
#0 [...][...](21): Test->testme()
#1 {main}
thrown in <b>[...][...]</b> on line <b>15</b><br />
但是评论出这条线似乎解决了问题所以原因是什么? 真正的问题是:
&#34;间接修改超载财产&#34;发生了什么?
&#34;无法通过引用分配重载对象&#34; - 为什么只能在unset
之后?
答案 0 :(得分:0)
见http://php.net/manual/en/language.oop5.overloading.php 和http://php.net/manual/en/language.oop5.magic.php
PHP中的重载提供了动态“创建”属性和方法的方法。这些动态实体通过魔术方法处理,可以在类中为各种动作类型建立。
当您取消设置()私有变量$ a时,就好像它从未存在过一样,就好像你从未设置“private $ a;”在课程开始时。在第16行,PHP注意到$ this-&gt; a没有设置,并且使用__get方法启动了魔法。您开始使用重载属性$ this-&gt; a“神奇地”创建。
所以回答你的问题:
<?php
class Test {
public function __get($name) {
echo('GETTER CALLED!');
return null;
}
public function testme() {
$v = array(1, 2, 3);
$this->a = &$v;
}
}
$test = new Test();
$test->testme();
答案 1 :(得分:0)
魔法方法__get的参数不能通过引用传递。
更简单的代码:
class Test {
public function __get($name) {
return null;
}
}
$test = new Test();
$a=1;
$test->a=&$a; # <-- Cannot assign by reference to overloaded object
答案 2 :(得分:0)
从DoPPeS的解释来看,我的工作变化很小。我在类外部移动了数组的创建,并添加了一个getter,以验证引用的赋值是否正常工作。
简单的解决方法是,从DoPPeS所说的,它必须重新创建属性,但不能直接分配引用,首先使用虚拟值来创建属性,它现在存在并且可以通过引用分配(那里)可能是更优雅的解决方案,但它的工作原理):
<?php
class Test {
private $a;
public function __get($name) {
echo('GETTER CALLED!');
return null;
}
public function testme(&$val) {
unset($this->a);
$this->a = 'test'; // <-- creates the property
$this->a = &$val; // <-- now reference works
}
public function getVal($name) {
if(!isset($this->{$name})){
return NULL;
}
return $this->{$name};
}
}
$v = array(1, 2, 3);
$test = new Test();
$test->testme($v);
$v[] = 4;
var_dump($test->getVal('a'));
?>
答案 3 :(得分:0)
最后一个问题非常有趣,我通过搜索获得以下信息,希望对您有所帮助。
这些魔术方法的参数可以通过引用传递。 PHP Manual
这个功能最初对我来说看起来像个错误,但在询问了很多之后,结果却是预期的行为。 Regression/unset properties behavior