Description
Description
TL;DR: 3v4l link here to reproduce: https://3v4l.org/8XAEr
When having a class with promoted properties (readonly or not) having default values, the construction with ReflectionClass::newInstanceWithoutConstructor()
doesn't initialize the properties.
Example with this class:
<?php
class WithPromotedProps {
public function __construct(
private tring $data = '',
) {}
}
var_dump(new WithPromotedProps());
/* Output:
object(WithPromotedProps)#1 (1) {
["data":"WithPromotedProps":private]=>
string(0) ""
}
*/
Normal construction does properly defines the property with the default value.
However, when using the Reflection API, the default value isn't provided:
$ref = new ReflectionClass(WithPromotedProps::class);
$instance = $ref->newInstanceWithoutConstructor();
var_dump($instance);
This will result in this inconsistent object state:
object(WithPromotedProps)#3 (0) {
["data":"WithPromotedProps":private]=>
uninitialized(string)
}
Here, since the promoted property has a default value, we should expect the same output as the previous example.
This does not happen if the property isn't promoted:
<?php
class WithoutPromotedProps {
private string $data = '';
public function __construct(string $data = '') {
$this->data = $data;
}
}
$ref = new ReflectionClass(WithoutPromotedProps::class);
$instance = $ref->newInstanceWithoutConstructor();
// Value is initialized with empty string
var_dump($instance);
/* Output:
object(WithoutPromotedProps)#1 (1) {
["data":"WithoutPromotedProps":private]=>
string(0) ""
}
*/
Note: the exact same happens with readonly
properties, the code compiles even though readonly
properties should not have a default value, but creating the object with the Reflection API without its constructor will still result in this uninitialized
state.
PHP Version
Starts at 8.2.0 upwards
Operating System
No response