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