PHP:__set 函数行为每次都不同

标签 php

这设法在对象上创建一个新属性。但是,有人可以通过支持链接解释为什么 setAttrib 有两种不同的行为方式吗?为什么它不会导致……等等……堆栈溢出!!??

class Test
{
  public function setAttrib( $key, $value ) {
    echo "setAttrib\n";

    // first time: calls $this->__set($key, $value)
    // second time: just sets a public property (but, when exactly was it created?)
    $this->$key = $value;
  }

  public function __set( $key, $value ) {
    echo "__set\n";
    $this->setAttrib($key, $value);
  }
}

$test = new Test();
$test->setAttrib('hey', 'It works');
var_dump($test);

产生...

setAttrib
__set
setAttrib
object(Test)#1 (1) {
  ["hey"]=>
  string(8) "It works"
}

编辑:我不是在寻找替代方案。 我正在寻找它起作用的原因。

最佳答案

您似乎不是唯一注意到非递归行为的人:this comment on the manual's page状态:

2 - PHP will not recursively call one magic method from within itself (at least for the same $name).

稍后在同一页上,有 this one ,其中指出:

The recursion detection feature can prove especially perilous when using __set. When PHP comes across a statement that would usually call __set but would lead to recursion, rather than firing off a warning or simply not executing the statement it will act as though there is no __set method defined at all.
The default behaviour in this instance is to dynamically add the specified property to the object thus breaking the desired functionality of all further calls to __set or __get for that property.


而且,在 PHP 的错误追踪器上,有 #47215 : magic method __set() is bypassed on recursive call ,它说:

Magic method __set() is bypassed on recursive call.
PHP automatically creates a property on instance instead of recursively calling __set() or instead of throwing a recursivity error

它已被关闭为:

Thank you for taking the time to write to us, but this is not a bug.

该错误报告本身指向 this blog-post ,以这句话结束(引用,强调我的):

After all I think it may not be a bug but expected behaviour, otherwise we could not be able to define object properties from within __set() method.

关于PHP:__set 函数行为每次都不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1948844/

相关文章:

php - zend 注册表 VS zend 缓存

php - 搜索拥有超过300万条记录的mysql数据库

php - 如何使用 Doctrine2 中的查询生成器更新多个字段?

javascript - JQuery 抖动对错误的影响

php - 照亮\数据库\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1064

javascript - 使用 Javascript 访问 PHP 变量

php - 第一次如何创建mysql数据库?

php - 'throw new Exception' 是否需要 exit()?

php - 将数据从中间件传递到 View 或以其他方式在每个页面中显示特定数据

php - htaccess 出现问题(每个页面上都显示一个参数)