How does PHP avoid infinite recursion here?

夙愿已清 提交于 2020-01-29 03:39:09

问题


Consider this class:

class test
{
    public function __set($n, $v)
    {
        echo "__set() called\n";
        $this->other_set($n, $v, true);
    }

    public function other_set($name, $value)
    {
        echo "other_set() called\n";    
        $this->$name = $value;
    }

    public function t()
    {
        $this->t = true;
    }
}

I am overloading PHP's magic __set() method. Whenever I set a property in an object of the test class, it will call __set(), which in turn calls other_set().

$obj = new test;
$test->prop = 10;

/* prints the following */
__set() called
other_set() called

But other_set() has the following line $this->$name = $value. Shouldn't this result in a call to __set(), causing infinite recursion?

I theorized that it would call __set() only when setting things outside the class. But if you call the method t() you can see it clearly goes through __set() too.


回答1:


__set is only called once per attempt for a given property name. If it (or anything it calls) attempts to set the same property, PHP won't call __set again -- it'll just set the property on the object.




回答2:


From the documentation:

__set() is run when writing data to inaccessible properties

For example:

class foo {
  private $attributes;
  public $bar;

  public function __construct() {
    $this->attributes = array();
  }

  public function __set($n, $v) {
    echo "__set() called\n";
    $this->attributes[$n] = $v;
  }
}

$x = new foo;
$x->prop = "value";
$x->attributes = "value";
$x->bar = "hello world";

In this case, $x->prop is inaccessible and __set will be called. $x->attributes is also inaccessible, so __set will be called. However, $x->bar is publicly accessible, so __set will not be called.

Similarly, in the __set method, $this->attribtues is accessible, so there is no recursion.

In your example code above, $this->$name is accessible in the scope in which its called, therefore __set is not called.



来源:https://stackoverflow.com/questions/10017741/how-does-php-avoid-infinite-recursion-here

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!