Skip to content

PHP 8.4: Virtual Property with set returning a value stores the value #18341

@DarkGhostHunter

Description

@DarkGhostHunter

Description

3v4l reproduction

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)

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions