On Mon, Oct 23, 2023, at 2:18 PM, Pierre wrote:
> Hello internals,
>
> I stumbled upon this behavior, if I write this:
>
> ```php
> class Foo
> {
>      public ?string $prop = null;
>
>      public function __construct(?string $prop = null)
>      {
>          $this->prop = $prop;
>      }
> }
>
> class Bar extends Foo
> {
>      public function __construct(
>          public ?string $bar = null,
>      ) {}
> }
>
> // Echoes nothing, but it works as expected.
> echo (new Bar())->prop;
> ```
>
> It works as intended, but if I replace the `Foo` class using:
>
> ```php
> class Foo
> {
>      public function __construct(
>          public ?string $prop = null,
>      ) {}
> }
> ```
>
> It won't work anymore and I have the following error:
>
> ```
> PHP Warning:  Uncaught Error: Typed property Foo::$prop must not be 
> accessed before initialization in php shell code:9
> ```
>
> If I understand it correctly:
>   - in the first case, default value is attached to the object property, 
> so if I omit its constructor, I have the default,
>   - in the second case, default value is attached to the constructor 
> parameter, and not to the object property, which means that in case the 
> parent constructor is not called in the `Bar` class, `$prop` remains 
> initialized.
>
> It doesn't sound like a bug, but I think that many people would actually 
> expect otherwise: that the constructor promoted property keep their 
> default even when constructor is not explicitly called.
>
> Is there any good reason behind this ? Wouldn't it be best to change 
> this behavior ? Would it be a risk for backward compatibility (my guess 
> is "not that much, probably not a all even") ?

Where this becomes a problem is readonly properties, since those are not 
allowed to have default values.  (That would make them constants with worse 
performance.)  A solution would need to be able to detect that the 
parent::__construct() isn't called, and then call it anyway, or at least 
partially call it.  Unfortunately, I can think of many cases where such a call 
would result in unexpected behavior.

It might be possible to resolve, but it's definitely not simple, and it could 
easily lead to weird behavior.

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to