1--TEST--
2Readonly variations
3--FILE--
4<?php
5
6class Test {
7    public readonly int $prop;
8
9    public function init() {
10        $this->prop = 1;
11    }
12
13    public function r() {
14        echo $this->prop;
15    }
16
17    public function w() {
18        $this->prop = 1;
19        echo 'done';
20    }
21
22    public function rw() {
23        $this->prop += 1;
24        echo 'done';
25    }
26
27    public function im() {
28        $this->prop[] = 1;
29        echo 'done';
30    }
31
32    public function is() {
33        echo (int) isset($this->prop);
34    }
35
36    public function us() {
37        unset($this->prop);
38        echo 'done';
39    }
40}
41
42function r($test) {
43    echo $test->prop;
44}
45
46function w($test) {
47    $test->prop = 0;
48    echo 'done';
49}
50
51function rw($test) {
52    $test->prop += 1;
53    echo 'done';
54}
55
56function im($test) {
57    $test->prop[] = 1;
58    echo 'done';
59}
60
61function is($test) {
62    echo (int) isset($test->prop);
63}
64
65function us($test) {
66    unset($test->prop);
67    echo 'done';
68}
69
70foreach ([true, false] as $init) {
71    foreach ([true, false] as $scope) {
72        foreach (['r', 'w', 'rw', 'im', 'is', 'us'] as $op) {
73            $test = new Test();
74            if ($init) {
75                $test->init();
76            }
77
78            echo 'Init: ' . ((int) $init) . ', scope: ' . ((int) $scope) . ', op: ' . $op . ": ";
79            try {
80                if ($scope) {
81                    $test->{$op}();
82                } else {
83                    $op($test);
84                }
85            } catch (Error $e) {
86                echo $e->getMessage();
87            }
88            echo "\n";
89        }
90    }
91}
92
93?>
94--EXPECT--
95Init: 1, scope: 1, op: r: 1
96Init: 1, scope: 1, op: w: Cannot modify readonly property Test::$prop
97Init: 1, scope: 1, op: rw: Cannot modify readonly property Test::$prop
98Init: 1, scope: 1, op: im: Cannot modify readonly property Test::$prop
99Init: 1, scope: 1, op: is: 1
100Init: 1, scope: 1, op: us: Cannot unset readonly property Test::$prop
101Init: 1, scope: 0, op: r: 1
102Init: 1, scope: 0, op: w: Cannot modify readonly property Test::$prop
103Init: 1, scope: 0, op: rw: Cannot modify readonly property Test::$prop
104Init: 1, scope: 0, op: im: Cannot modify readonly property Test::$prop
105Init: 1, scope: 0, op: is: 1
106Init: 1, scope: 0, op: us: Cannot unset readonly property Test::$prop
107Init: 0, scope: 1, op: r: Typed property Test::$prop must not be accessed before initialization
108Init: 0, scope: 1, op: w: done
109Init: 0, scope: 1, op: rw: Typed property Test::$prop must not be accessed before initialization
110Init: 0, scope: 1, op: im: Cannot indirectly modify readonly property Test::$prop
111Init: 0, scope: 1, op: is: 0
112Init: 0, scope: 1, op: us: done
113Init: 0, scope: 0, op: r: Typed property Test::$prop must not be accessed before initialization
114Init: 0, scope: 0, op: w: Cannot initialize readonly property Test::$prop from global scope
115Init: 0, scope: 0, op: rw: Typed property Test::$prop must not be accessed before initialization
116Init: 0, scope: 0, op: im: Cannot indirectly modify readonly property Test::$prop
117Init: 0, scope: 0, op: is: 0
118Init: 0, scope: 0, op: us: Cannot unset readonly property Test::$prop from global scope
119