|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2021-08-26 10:30 UTC] enumag at gmail dot com
Description:
------------
Currently when you declare a promoted property with a default value the ReflectionProperty::getDefaultValue() won't return that value.
I'm not sure if this behavior is expected or not but in either case something needs to be changed.
If this behavior is unexpected then it should be fixed to return the correct value.
If this behavior is expected then the documentation of ReflectionProperty::getDefaultValue() should mention this drawback along with a few lines of code how to get to the relevant ReflectionParameter and get the value there.
Test script:
---------------
<?php
class X {
public function __construct(
public bool $y = false
) {
}
}
var_export((new ReflectionProperty('X', 'y'))->getDefaultValue());
Expected result:
----------------
Either the value should be returned or this behavior needs to be documented.
Actual result:
--------------
The default value is not returned and there is no mention of this behavior in the documentation
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Nov 13 01:00:01 2025 UTC |
Hello, I also stumbled across this "issue" today, and I am in no place to say if this is supposed to be a bug or not, but I wanted to add my experience, being that in addition, if a property is promoted but not typed, its associated ReflectionProperty::hasDefaultValue() seems to always return true. Test script: ------------- <?php class Foo { public function __construct( public $foo, public $bar = 'bar' ) { } } $reflection = new ReflectionClass(Foo::class); $fooReflection = $reflection->getProperty('foo'); $barReflection = $reflection->getProperty('bar'); var_dump($fooReflection->hasDefaultValue()); // true var_dump($fooReflection->getDefaultValue()); // null var_dump($barReflection->hasDefaultValue()); // true var_dump($barReflection->getDefaultValue()); // nullHello! You can get default values from promoted properties in another way: readonly class A { public function __construct( string $foo, private int $bar = 5, ) { } } $ro = new ReflectionClass(A::class); foreach ($ro->getConstructor()->getParameters() as $param) { var_export($param->name); var_export($param->isPromoted()); var_export($param->getType()->getName()); var_export($param->isDefaultValueAvailable()); if ($param->isDefaultValueAvailable()) { var_export($param->getDefaultValue()); } } //'foo', false, 'string', false //'bar', true, 'int', true, 5Honestly I can't find clear documentation outside of this bug report, which stumped me in fixing a queue issue where someone had updated a class constructor If we could get a promoted property's default value (assuming it has one within the construct), it would as simple as $reflection = new \ReflectionClass($this); $props = $reflection->getProperties(); foreach($props as $prop) { if (!$prop->isInitialized($this) && $prop->hasDefaultValue()) { $prop->setValue($this, $prop->getDefaultValue()); } } But as is, another loop is needed on top of the previous to ensure all defaults are initialized foreach($reflection->getConstructor()->getParameters() as $param) { if (!$param->isPromoted() || !$param->isOptional()) { continue; } $property = $reflection->getProperty($param->getName()); if ($property->isInitialized($this)) { continue; } if ($param->isDefaultValueAvailable()) { $property->setValue($this, $param->getDefaultValue()); } }