@@ -66,29 +66,39 @@ protected function doClone($var)
6666 // $v is the original value or a stub object in case of hard references
6767
6868 if (\PHP_VERSION_ID >= 70400 ) {
69- $ zvalIsRef = null !== \ReflectionReference::fromArrayElement ($ vals , $ k );
69+ $ zvalRef = ( $ r = \ReflectionReference::fromArrayElement ($ vals , $ k )) ? $ r -> getId () : null ;
7070 } else {
7171 $ refs [$ k ] = $ cookie ;
72- $ zvalIsRef = $ vals [$ k ] === $ cookie ;
72+ $ zvalRef = $ vals [$ k ] === $ cookie ;
7373 }
7474
75- if ($ zvalIsRef ) {
75+ if ($ zvalRef ) {
7676 $ vals [$ k ] = &$ stub ; // Break hard references to make $queue completely
7777 unset($ stub ); // independent from the original structure
78- if ($ v instanceof Stub && isset ($ hardRefs [spl_object_id ($ v )])) {
79- $ vals [$ k ] = $ refs [$ k ] = $ v ;
78+ if (\PHP_VERSION_ID >= 70400 ? null !== $ vals [$ k ] = $ hardRefs [$ zvalRef ] ?? null : $ v instanceof Stub && isset ($ hardRefs [spl_object_id ($ v )])) {
79+ if (\PHP_VERSION_ID >= 70400 ) {
80+ $ v = $ vals [$ k ];
81+ } else {
82+ $ refs [$ k ] = $ vals [$ k ] = $ v ;
83+ }
8084 if ($ v ->value instanceof Stub && (Stub::TYPE_OBJECT === $ v ->value ->type || Stub::TYPE_RESOURCE === $ v ->value ->type )) {
8185 ++$ v ->value ->refCount ;
8286 }
8387 ++$ v ->refCount ;
8488 continue ;
8589 }
86- $ refs [$ k ] = $ vals [$ k ] = new Stub ();
87- $ refs [$ k ]->value = $ v ;
88- $ h = spl_object_id ($ refs [$ k ]);
89- $ hardRefs [$ h ] = &$ refs [$ k ];
90- $ values [$ h ] = $ v ;
90+ $ vals [$ k ] = new Stub ();
91+ $ vals [$ k ]->value = $ v ;
9192 $ vals [$ k ]->handle = ++$ refsCounter ;
93+
94+ if (\PHP_VERSION_ID >= 70400 ) {
95+ $ hardRefs [$ zvalRef ] = $ vals [$ k ];
96+ } else {
97+ $ refs [$ k ] = $ vals [$ k ];
98+ $ h = spl_object_id ($ refs [$ k ]);
99+ $ hardRefs [$ h ] = &$ refs [$ k ];
100+ $ values [$ h ] = $ v ;
101+ }
92102 }
93103 // Create $stub when the original value $v can not be used directly
94104 // If $v is a nested structure, put that structure in array $a
@@ -154,12 +164,17 @@ protected function doClone($var)
154164 unset($ v [$ gid ]);
155165 $ a = [];
156166 foreach ($ v as $ gk => &$ gv ) {
157- if ($ v === $ gv ) {
167+ if ($ v === $ gv && (\ PHP_VERSION_ID < 70400 || ! isset ( $ hardRefs [\ReflectionReference:: fromArrayElement ( $ v , $ gk )-> getId ()])) ) {
158168 unset($ v );
159169 $ v = new Stub ();
160170 $ v ->value = [$ v ->cut = \count ($ gv ), Stub::TYPE_ARRAY => 0 ];
161171 $ v ->handle = -1 ;
162- $ gv = &$ hardRefs [spl_object_id ($ v )];
172+ if (\PHP_VERSION_ID >= 70400 ) {
173+ $ gv = &$ a [$ gk ];
174+ $ hardRefs [\ReflectionReference::fromArrayElement ($ a , $ gk )->getId ()] = &$ gv ;
175+ } else {
176+ $ gv = &$ hardRefs [spl_object_id ($ v )];
177+ }
163178 $ gv = $ v ;
164179 }
165180
@@ -257,10 +272,12 @@ protected function doClone($var)
257272 }
258273 }
259274
260- if ($ zvalIsRef ) {
261- $ refs [$ k ]->value = $ stub ;
262- } else {
275+ if (!$ zvalRef ) {
263276 $ vals [$ k ] = $ stub ;
277+ } elseif (\PHP_VERSION_ID >= 70400 ) {
278+ $ hardRefs [$ zvalRef ]->value = $ stub ;
279+ } else {
280+ $ refs [$ k ]->value = $ stub ;
264281 }
265282 }
266283
0 commit comments