Skip to content

Readonly constructor parameter without visibility is promoted to public class property. #12122

@bartvanraaij

Description

@bartvanraaij

Description

https://3v4l.org/AapHF#v8.2.10
The following code:

<?php
class MyClass {
    public function __construct(
         readonly string $var,
    ) {}
}

$a = new MyClass('foo');
var_dump($a->var);

Resulted in this output:

object(MyClass)#1 (1) {
  ["var"]=>
  string(3) "foo"
}
string(3) "foo"

The constructor parameter $var is promoted to a public class property, because it has the readonly keyword.

The Constructor Property Promotion RFC however states that:

When a method parameter is prefixed with one of the visibility keywords public, protected or private, it is considered to be “promoted”.

So without a visibility keyword I would not expect the parameter to be promoted, and be scoped to the constructor method only. I expect the output to look like this, as it would without the readonly keyword:

object(MyClass)#1 (0) {
}

Warning: Undefined property: MyClass::$var in /tmp/preview on line 10
NULL

The source of this bug can be found here, I believe:

uint32_t flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_READONLY);

You can see here that the parameter is promoted if it has a ZEND_ACC_PPP_MASK keyword or a ZEND_ACC_READONLY.
I think the latter is erroneous, but I'm not a C programmer nor knowledgeable about the PHP source so I could be mistaken.

PHP Version

PHP 8.2.10

Operating System

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions