1--TEST-- 2Readonly nested variations 3--FILE-- 4<?php 5 6class Inner { 7 public int $prop = 1; 8 public array $array = []; 9} 10 11class Test { 12 public readonly Inner $prop; 13 14 public function init() { 15 $this->prop = new Inner(); 16 } 17} 18 19function r($test) { 20 echo $test->prop->prop; 21} 22 23function w($test) { 24 $test->prop->prop = 0; 25 echo 'done'; 26} 27 28function rw($test) { 29 $test->prop->prop += 1; 30 echo 'done'; 31} 32 33function im($test) { 34 $test->prop->array[] = 1; 35 echo 'done'; 36} 37 38function is($test) { 39 echo (int) isset($test->prop->prop); 40} 41 42function us($test) { 43 unset($test->prop->prop); 44 echo 'done'; 45} 46 47function us_dim($test) { 48 unset($test->prop->array[0]); 49 echo 'done'; 50} 51 52foreach ([true, false] as $init) { 53 foreach (['r', 'w', 'rw', 'im', 'is', 'us', 'us_dim'] as $op) { 54 $test = new Test(); 55 if ($init) { 56 $test->init(); 57 } 58 59 echo 'Init: ' . ((int) $init) . ', op: ' . $op . ": "; 60 try { 61 $op($test); 62 } catch (Error $e) { 63 echo $e->getMessage(); 64 } 65 echo "\n"; 66 } 67} 68 69?> 70--EXPECT-- 71Init: 1, op: r: 1 72Init: 1, op: w: done 73Init: 1, op: rw: done 74Init: 1, op: im: done 75Init: 1, op: is: 1 76Init: 1, op: us: done 77Init: 1, op: us_dim: done 78Init: 0, op: r: Typed property Test::$prop must not be accessed before initialization 79Init: 0, op: w: Cannot indirectly modify readonly property Test::$prop 80Init: 0, op: rw: Typed property Test::$prop must not be accessed before initialization 81Init: 0, op: im: Cannot indirectly modify readonly property Test::$prop 82Init: 0, op: is: 0 83Init: 0, op: us: done 84Init: 0, op: us_dim: done 85