1--TEST--
2Lazy objects: RFC example 011
3--FILE--
4<?php
5
6// User code
7
8class BlogPost
9{
10    private int $id;
11    private string $name;
12    private string $email;
13
14    public function getName()
15    {
16        return $this->name;
17    }
18
19    public function getEmail()
20    {
21        return $this->email;
22    }
23}
24
25// ORM code
26
27class EntityManager
28{
29    public function getReference(string $class, int $id)
30    {
31        // The ReflectionClass and ReflectionProperty instances are cached in practice
32        $reflector = new ReflectionClass($class);
33
34        $entity = $reflector->newLazyGhost(function ($entity) use ($class, $id, $reflector) {
35            $data = $this->loadFromDatabase($class, $id);
36            $reflector->getProperty('name')->setValue($entity, $data['name']);
37            $reflector->getProperty('email')->setValue($entity, $data['email']);
38        });
39
40        // id is already known and can be accessed without triggering initialization
41        $reflector->getProperty('id')->setRawValueWithoutLazyInitialization($entity, $id);
42
43        return $entity;
44    }
45
46    public function loadFromDatabase($id)
47    {
48        return [
49            'name' => 'Example',
50            'email' => 'example@example.com',
51        ];
52    }
53}
54
55$em = new EntityManager();
56$blogPost = $em->getReference(BlogPost::class, 123);
57var_dump($blogPost);
58var_dump($blogPost->getName());
59var_dump($blogPost);
60
61?>
62==DONE==
63--EXPECTF--
64lazy ghost object(BlogPost)#%d (1) {
65  ["id":"BlogPost":private]=>
66  int(123)
67  ["name":"BlogPost":private]=>
68  uninitialized(string)
69  ["email":"BlogPost":private]=>
70  uninitialized(string)
71}
72string(7) "Example"
73object(BlogPost)#%d (3) {
74  ["id":"BlogPost":private]=>
75  int(123)
76  ["name":"BlogPost":private]=>
77  string(7) "Example"
78  ["email":"BlogPost":private]=>
79  string(19) "example@example.com"
80}
81==DONE==
82