Description
Description
In PHP 8.4.17, assigning values to typed private properties using dynamic property names (e.g., $this->{$key} = $value) inside the __unserialize method fails to correctly update the property's internal initialization state.
Although var_dump() correctly displays the property value and the property is initialized, any attempt to access the property via a getter method results in a fatal error ($parameter must not be accessed before initialization). The Zend Engine's property hash table appears to be updated, but the initialization protection mechanism is not triggered when dynamically accessing private scopes.
PHP Version
PHP 8.4.17 (cli)
Reproduction Script
<?php
class Annotation
{
private ?string $method = null;
public function __construct(string $method)
{
$this->method = $method;
}
public function getMethod(): string
{
// This fails even if var_dump shows $this->method has a string value
if ($this->method === null) {
throw new \LogicException("Method is null");
}
return $this->method;
}
public function __serialize(): array
{
return get_object_vars($this);
}
public function __unserialize(array $data): void
{
foreach ($data as $key => $value) {
if (property_exists($this, $key)) {
$this->{$key} = $value;
}
}
}
}
// 1. Create and serialize
$obj = new Annotation("index");
$serialized = serialize($obj);
// 2. Unserialize
$unserialized = unserialize($serialized);
// 3. Inspection
echo "Var_dump output:\n";
var_dump($unserialized);
try {
echo "\nCalling getMethod(): " . $unserialized->getMethod() . "\n";
} catch (\Throwable $e) {
echo "\nCaught Exception: " . $e->getMessage() . "\n";
}
Expected Result
The output should be:
Calling getMethod(): index
Actual Result
$method must not be accessed before initialization
(Note: var_dump inside the script will show ["method":"Annotation":private]=> string(5) "index", proving that the data exists in memory but cannot be accessed.)
Additional Context
PHP Version
PHP 8.3.27 (cli) (built: Oct 25 2025 03:25:55) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.27, Copyright (c) Zend Technologies
Operating System
Ubuntu 24.04.4 LTS
Description
Description
In PHP 8.4.17, assigning values to typed private properties using dynamic property names (e.g., $this->{$key} = $value) inside the __unserialize method fails to correctly update the property's internal initialization state.
Although
var_dump()correctly displays the property value and the property is initialized, any attempt to access the property via a getter method results in a fatal error ($parameter must not be accessed before initialization). The Zend Engine's property hash table appears to be updated, but the initialization protection mechanism is not triggered when dynamically accessing private scopes.PHP Version
PHP 8.4.17 (cli)
Reproduction Script
Expected Result
The output should be:
Calling getMethod(): indexActual Result
$method must not be accessed before initialization(Note:
var_dumpinside the script will show["method":"Annotation":private]=> string(5) "index", proving that the data exists in memory but cannot be accessed.)Additional Context
This problem occurs with all visibility type properties.
Using explicit assignment
$this->method = $data['method']instead of aforeachloop also fails to solve this problem.PHP Version
Operating System
Ubuntu 24.04.4 LTS