-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Description
Description
When using a virtual property, if the set
hook returns a value, that value get stored inside the object.
While that would be expected as the value is returned, it collides with the essence of being a virtual property. The get
hook doesn't interacts with the backed value, neither the set
hook.
This doesn't happen when set
uses brackets to not return a value, but is not something a developer may expect when there is no interaction with a backed value. The problem is that the value gets stored and it cannot be retrieved from the property itself since the get
gets in the way, rendering the backed value useless, but potentially dangerous as the value could be duplicated.
^1: Dangerous as, trying to serialize the object and having a big value serialized twice, like an article or some other binary data.
<?php
class Example
{
protected $attributes = [];
public string $email {
get => $this->attributes['email'];
set => $this->attributes['email'] = strtolower($value);
}
}
Resulted in this output:
object(Example)#1 (2) {
["attributes":protected]=>
array(1) {
["email"]=>
string(23) "should only appear once"
}
["email"]=>
string(23) "should only appear once"
}
But I expected this output instead:
object(Example)#1 (2) {
["attributes":protected]=>
array(1) {
["email"]=>
string(23) "should only appear once"
}
}
PHP Version
PHP 8.4.6 (cli) (built: Apr 11 2025 17:00:54) (NTS)
Copyright (c) The PHP Group
Built by https://github.com/docker-library/php
Zend Engine v4.4.6, Copyright (c) Zend Technologies
with Zend OPcache v8.4.6, Copyright (c), by Zend Technologies
with Xdebug v3.4.2, Copyright (c) 2002-2025, by Derick Rethans
Operating System
Debian 12.10 (bookworm)