[php-src] Issue #11920: Unable to recursivelly call __set()

From: Date: Wed, 09 Aug 2023 11:15:35 +0000
Subject: [php-src] Issue #11920: Unable to recursivelly call __set()
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-245139@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/11920 Author: survik1 ### Description Hello, we are upgrading our old and huge application to PHP 8.2 and we started to get Creation of dynamic property is deprecated error which really surprised us as we have related classes fully covered with __set and __get methods. Upon further investigation we found out that __set method is not being called for same $name if this method was found within stack. There is this note in php doc that could be related, but it just mention calling from within the same method, not having the call in stack. If this is a desired behavior, I believe that doc should be updated to inform that this structure is not possible. ``` PHP will not call an overloaded method from within the same overloaded method. That means, for example, writing return $this->foo inside of [__get()](https://www.php.net/manual/en/language.oop5.overloading.php#object.get) will return null and raise an E_WARNING if there is no foo property defined, rather than calling [__get()](https://www.php.net/manual/en/language.oop5.overloading.php#object.get) a second time. However, overload methods may invoke other overload methods implicitly (such as [__set()](https://www.php.net/manual/en/language.oop5.overloading.php#object.set) triggering [__get()](https://www.php.net/manual/en/language.oop5.overloading.php#object.get)). ``` The following code: ```php <?php class test { protected $data = []; public function set_status($value) { if ($value === 1) { $this->storage = 'a'; } $this->data['status'] = $value; } public function set_storage($value) { if ($value === 'a') { $this->status = 2; } $this->data['storage'] = $value; } public function __set($name, $value) { if (method_exists($this, 'set_' . $name)) { $this->{"set_{$name}"}($value); } } public function getStatus() { return $this->data['status']; } } $c = new test(); $c->status = 3; echo $c->getStatus() . ":" . @$c->status . PHP_EOL; $c->status = 1; echo $c->getStatus() . ":" . @$c->status . PHP_EOL; ``` Resulted in this output: ``` 3: 1:2 ``` But I expected this output instead: ``` 3: 2: ``` ### PHP Version PHP 8.2.6 ### Operating System Ubuntu 22.04

« previous php.bugs (#245139) next »