Skip to content

json_encode() serializes an uninitialized backed property with a setter hook as null #25108

Open

Description

@JoaoMarcos44

Description

AI-assisted report. The explanation was prepared with AI assistance. The reproduction and outputs below were verified by local execution.

An uninitialized public typed property is omitted by json_encode(). Adding a setter hook makes the same uninitialized property appear with a null value. This changes the distinction between an absent field and an explicit null in serialized data.

<?php
class Plain {
    public int $id;
}
class WithSetter {
    public int $id {
        set => $value;
    }
}
echo json_encode(new Plain()), "\n";
echo json_encode(new WithSetter()), "\n";

Actual output:

{}
{"id":null}

Expected output:

{}
{}

The hooked-property encoder reads the internal uninitialized sentinel in silent mode and serializes it instead of omitting the property. Explicitly initialized null values and getters returning null should remain included.

PHP Version

Also reproduced on the lowest actively supported branch, PHP-8.4, at commit dfcc0433fcda7fb732cba8d7ee8c857d23f9a9e7, with debug and ZTS enabled.

PHP 8.4.28-dev (cli) (built: Oct 31 2026 18:38:26) (ZTS DEBUG)
Copyright (c) The PHP Group
Zend Engine v4.4.28-dev, Copyright (c) Zend Technologies
PHP 8.5.12 (cli) (built: Oct 28 2026 01:23:38) (NTS)
Copyright (c) The PHP Group
Built by https://github.com/docker-library/php
Zend Engine v4.5.12, Copyright (c) Zend Technologies
    with Zend OPcache v8.5.12, Copyright (c), by Zend Technologies

Also reproduced on PHP 8.7.0-dev at commit 248c5c45409667b5e69bba38a92c5cc9edd7582a.

Operating System

Debian GNU/Linux 12 (bookworm), Linux container.

Proposed fix and regression test: #25110.

Illustrated explanation and generation prompt.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions