1--TEST--
2Lazy Objects: GH-15999 001: Object is released during initialization
3--FILE--
4<?php
5
6class C {
7    public $s;
8    public function __destruct() {
9        var_dump(__METHOD__);
10    }
11}
12
13print "# Ghost:\n";
14
15$r = new ReflectionClass(C::class);
16
17$o = $r->newLazyGhost(function ($obj) {
18    global $o;
19    $o = null;
20});
21$p = new stdClass;
22
23try {
24    $o->s = $p;
25} catch (Error $e) {
26    printf("%s: %s\n", $e::class, $e->getMessage());
27}
28
29print "# Proxy:\n";
30
31$o = $r->newLazyProxy(function ($obj) {
32    global $o;
33    $o = null;
34    return new C();
35});
36$p = new stdClass;
37
38try {
39    $o->s = $p;
40} catch (Error $e) {
41    printf("%s: %s\n", $e::class, $e->getMessage());
42}
43
44print "# GC cycle:\n";
45
46$o = $r->newLazyGhost(function ($obj) {
47    global $o;
48    $o->s = $o;
49    $o = null;
50    gc_collect_cycles();
51});
52$p = new stdClass;
53
54$o->s = $p;
55gc_collect_cycles();
56
57print "# Nested error (ghost):\n";
58
59$r = new ReflectionClass(C::class);
60
61$o = $r->newLazyGhost(function ($obj) {
62    global $o;
63    $o = null;
64    return new stdClass;
65});
66$p = new stdClass;
67
68try {
69    $o->s = $p;
70} catch (Error $e) {
71    do {
72        printf("%s: %s\n", $e::class, $e->getMessage());
73    } while ($e = $e->getPrevious());
74}
75
76print "# Nested error (proxy):\n";
77
78$r = new ReflectionClass(C::class);
79
80$o = $r->newLazyProxy(function ($obj) {
81    global $o;
82    $o = null;
83    return new stdClass;
84});
85$p = new stdClass;
86
87try {
88    $o->s = $p;
89} catch (Error $e) {
90    do {
91        printf("%s: %s\n", $e::class, $e->getMessage());
92    } while ($e = $e->getPrevious());
93}
94
95?>
96==DONE==
97--EXPECT--
98# Ghost:
99string(13) "C::__destruct"
100Error: Lazy object was released during initialization
101# Proxy:
102string(13) "C::__destruct"
103Error: Lazy object was released during initialization
104# GC cycle:
105string(13) "C::__destruct"
106# Nested error (ghost):
107Error: Lazy object was released during initialization
108TypeError: Lazy object initializer must return NULL or no value
109# Nested error (proxy):
110Error: Lazy object was released during initialization
111TypeError: The real instance class stdClass is not compatible with the proxy class C. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods.
112==DONE==
113