@@ -3,71 +3,41 @@ Readonly classes can be constructed via reflection by ORM
33--FILE--
44<?php
55
6- interface DbConnection {
7- public function loadCategory (string $ id ): Category ;
8- }
9-
106class Category {
11- public function __construct (public string $ name ) {}
12- }
13-
14- class MockDbConnection implements DbConnection {
15- public function loadCategory (string $ id ): Category {
16- echo "hit database \n" ;
17- return new Category ("Category {$ id }" );
18- }
7+ public function __construct (public string $ id ) {}
198}
209
2110readonly class Product
2211{
2312 public function __construct (
24- public string $ name ,
25- public float $ price ,
2613 public Category $ category ,
2714 ) {}
2815}
2916
3017readonly class LazyProduct extends Product
3118{
32- private DbConnection $ dbApi ;
33-
3419 private string $ categoryId ;
3520
3621 public Category $ category {
3722 get {
38- return $ this ->category ??= $ this -> dbApi -> loadCategory ($ this ->categoryId );
23+ return $ this ->category ??= new Category ($ this ->categoryId );
3924 }
4025 }
4126}
4227
4328$ reflect = new ReflectionClass (LazyProduct::class);
4429$ product = $ reflect ->newInstanceWithoutConstructor ();
4530
46- $ nameProperty = $ reflect ->getProperty ('name ' );
47- $ nameProperty ->setAccessible (true );
48- $ nameProperty ->setValue ($ product , 'Iced Chocolate ' );
49-
50- $ priceProperty = $ reflect ->getProperty ('price ' );
51- $ priceProperty ->setAccessible (true );
52- $ priceProperty ->setValue ($ product , 1.99 );
53-
54- $ db = $ reflect ->getProperty ('dbApi ' );
55- $ db ->setAccessible (true );
56- $ db ->setValue ($ product , new MockDbConnection ());
57-
5831$ categoryId = $ reflect ->getProperty ('categoryId ' );
5932$ categoryId ->setAccessible (true );
6033$ categoryId ->setValue ($ product , '42 ' );
6134
62- // lazy loading, hit db
6335$ category1 = $ product ->category ;
64- echo $ category1 ->name . "\n" ;
65-
66- // cached category returned
6736$ category2 = $ product ->category ;
68- echo $ category2 ->name . "\n" ;
6937
70- // same category instance returned
38+ echo $ category1 ->id . "\n" ;
39+ echo $ category2 ->id . "\n" ;
40+
7141var_dump ($ category1 === $ category2 );
7242
7343// cannot set twice
7949
8050?>
8151--EXPECT--
82- hit database
83- Category 42
84- Category 42
52+ 42
53+ 42
8554bool(true)
8655Error: Cannot modify readonly property LazyProduct::$categoryId
0 commit comments