php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #81386 ReflectionProperty::getDefaultValue() and promoted properties
Submitted: 2021-08-26 10:30 UTC Modified: 2024-05-17 07:07 UTC
Votes:5
Avg. Score:2.8 ± 1.0
Reproduced:4 of 4 (100.0%)
Same Version:1 (25.0%)
Same OS:1 (25.0%)
From: enumag at gmail dot com Assigned:
Status: Duplicate Package: *General Issues
PHP Version: 8.0.9 OS:
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: enumag at gmail dot com
New email:
PHP Version: OS:

 

 [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

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-08-26 10:33 UTC] enumag at gmail dot com
Forgot to mention: ReflectionProperty::hasDefaultValue() needs to be fixed or better documented as well.
 [2021-08-26 10:35 UTC] nikic@php.net
-Type: Bug +Type: Documentation Problem
 [2021-08-26 10:35 UTC] nikic@php.net
Promoted properties intentionally don't have a default value. The property is always initialized by the constructor.

I don't think this needs to be mentioned in the ReflectionProperty::getDefaultValue() docs, as reflection simply reflects reality. However, it should be mentioned in the promoted property docs at https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion.
 [2021-08-26 10:45 UTC] enumag at gmail dot com
@nikic I have to disagree. As a programmer who is using promoted properties I don't differentiate if the default value is for the property or the parameter. Even if the behavior is expected from the language's point of view, it's not entirely expected from the user's point of view. I'd much rather see it mentioned there than only randomly stumbling on it while debugging.
 [2022-12-29 15:02 UTC] hugo dot nicolas dot hn at gmail dot com
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()); // null
 [2023-05-02 18:33 UTC] kevinhawks14 at aol dot com
(https://collegegrazing.com/)github.com
(https://collegegrazing.com/blog/)github.com
(https://collegegrazing.com/affiliate-disclosure/)github.com
(https://collegegrazing.com/terms-of-use/)github.com
(https://collegegrazing.com/fake-id/best-fake-id-websites/)github.com
(https://collegegrazing.com/about/)github.com
(https://collegegrazing.com/contact/)github.com
(https://collegegrazing.com/fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-fake-ids/)github.com
(https://collegegrazing.com/how-to-get-a-fake-id/)github.com
(https://collegegrazing.com/top-fake-id-review/)github.com
(https://collegegrazing.com/fake-id/buy-virginia-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-new-mexico-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-kentucky-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-iowa-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-maine-fake-id/)github.com
(https://collegegrazing.com/all-state-fakes-review/)github.com
(https://collegegrazing.com/fake-id/buy-colorado-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-missouri-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-new-hampshire-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-vermont-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-georgia-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-arizona-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-alabama-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-florida-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-maryland-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-wyoming-fake-id/)github.com
(https://collegegrazing.com/fake-id/what-happens-if-i-get-caught/)github.com
(https://collegegrazing.com/fake-id/buy-california-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-new-york-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-alaska-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-rhode-island-fake-id/)github.com
(https://collegegrazing.com/magic-fake-id-review/)github.com
(https://collegegrazing.com/fake-id/buy-utah-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-hawaii-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-minnesota-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-oklahoma-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-illinois-fake-id/)github.com
(https://collegegrazing.com/evolved-ids-review/)github.com
(https://collegegrazing.com/fake-id/buy-indiana-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-montana-fake-id/)github.com
(https://collegegrazing.com/how-do-bouncers-spot-fake-ids/)github.com
(https://collegegrazing.com/fake-id/common-uses/)github.com
(https://collegegrazing.com/fake-id/buy-arkansas-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-pennsylvania-fake-id/)github.com
(https://collegegrazing.com/blog/page/2/)github.com
(https://collegegrazing.com/fake-id/buy-new-jersey-fake-id/)github.com
(https://collegegrazing.com/how-to-spot-a-georgia-fake-id/)github.com
(https://collegegrazing.com/scannable-fake-ids/)github.com
(https://collegegrazing.com/fake-id/buy-south-dakota-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-massachusetts-fake-id/)github.com)github.com
(https://collegegrazing.com/fake-id/how-to-spot/)github.com
(https://collegegrazing.com/fake-id/buy-west-virginia-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-connecticut-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-wisconsin-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-idaho-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-columbia-fake-id/)github.com
(https://collegegrazing.com/fake-id/how-to-make/)github.com
(https://collegegrazing.com/fake-id/buy-mississippi-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-nevada-fake-id/)github.com
(https://collegegrazing.com/how-to-pay-for-fake-id/)github.com
(https://collegegrazing.com/how-to-take-a-fake-id-photo-at-home/)github.com
(https://collegegrazing.com/fake-id/buy-oregon-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-texas-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-north-dakota-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-louisiana-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-south-carolina-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-kansas-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-tennessee-fake-id/)github.com
(https://collegegrazing.com/fake-id/types-of-fake-ids/)github.com
(https://collegegrazing.com/fake-id/buy-delaware-fake-id/)github.com
(https://collegegrazing.com/lost-identification-review/)github.com
(https://collegegrazing.com/fake-id/buy-washington-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-nebraska-fake-id/)github.com
(https://collegegrazing.com/dingo-fakes-review/)github.com
(https://collegegrazing.com/fake-id/buy-north-carolina-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-michigan-fake-id/)github.com
(https://collegegrazing.com/fake-id/buy-ohio-fake-id/)github.com
(https://collegegrazing.com/fake-id/best-states/)github.com
(https://collegegrazing.com/idviking-review/)github.com
(https://collegegrazing.com/super-printer-bros-review/)github.com
(https://collegegrazing.com/idgod-review/)github.com
(https://collegegrazing.com/bogus-braxtor-review/)github.com
(https://collegegrazing.com/newids-review/)github.com
(https://collegegrazing.com/litfakes-review/)github.com
(https://collegegrazing.com/old-ironside-fakes-review/)github.com
(https://collegegrazing.com/idhurry-review/)github.com
 [2023-06-08 09:35 UTC] evgeeek at gmail dot com
Hello!
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, 5
 [2024-05-17 06:36 UTC] rafr at generaxion dot dk
Honestly 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());
    }
}
 [2024-05-17 07:07 UTC] requinix@php.net
-Status: Open +Status: Duplicate -Package: Documentation problem +Package: *General Issues
 [2024-05-17 07:07 UTC] requinix@php.net
I'm moving this over to https://github.com/php/doc-en/issues/3386
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Oct 16 07:01:27 2024 UTC