[php-src] Issue #12122: Readonly constructor parameter without visibility is promoted to public class property.
| From: | bartvanraaij | Date: | Mon, 04 Sep 2023 15:07:06 +0000 |
| Subject: | [php-src] Issue #12122: Readonly constructor parameter without visibility is promoted to public class property. | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-245324@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/12122
Author: bartvanraaij
### Description
https://3v4l.org/1AmKB#v8.2.10
The following code:
```php
<?php
class MyClass {
public function __construct(
readonly string $var,
) {}
}
$a = new MyClass('foo');
var_dump($a);
```
Resulted in this output:
```
object(MyClass)#1 (1) {
["var"]=>
string(3) "foo"
}
```
The constructor parameter
$var is promoted to a class property, because it has the
readonly keyword.
The [Constructor Property Promotion RFC](https://wiki.php.net/rfc/constructor_promotion) 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 dump of the class to look like this, as it would without
the readonly keyword:
```
object(MyClass)#1 (0) {
}
```
The source of this bug can be found here, I believe:
https://github.com/php/php-src/blob/3f38105740d160e448881b268ebc44bfed20c7db/Zend/zend_compile.c#L7181
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_