16
16
*/
17
17
class VarCloner extends AbstractCloner
18
18
{
19
+ private static $ gid ;
19
20
private static $ hashMask = 0 ;
20
21
private static $ hashOffset = 0 ;
22
+ private static $ arrayCache = array ();
21
23
22
24
/**
23
25
* {@inheritdoc}
@@ -36,14 +38,15 @@ protected function doClone($var)
36
38
$ maxItems = $ this ->maxItems ;
37
39
$ maxString = $ this ->maxString ;
38
40
$ cookie = (object ) array (); // Unique object used to detect hard references
39
- $ gid = uniqid (mt_rand (), true ); // Unique string used to detect the special $GLOBALS variable
40
41
$ a = null ; // Array cast for nested structures
41
42
$ stub = null ; // Stub capturing the main properties of an original item value
42
43
// or null if the original value is used directly
43
44
44
45
if (!self ::$ hashMask ) {
46
+ self ::$ gid = uniqid (mt_rand (), true ); // Unique string used to detect the special $GLOBALS variable
45
47
self ::initHashMask ();
46
48
}
49
+ $ gid = self ::$ gid ;
47
50
$ hashMask = self ::$ hashMask ;
48
51
$ hashOffset = self ::$ hashOffset ;
49
52
$ arrayStub = new Stub ();
@@ -58,9 +61,9 @@ protected function doClone($var)
58
61
if (\is_int ($ k )) {
59
62
continue ;
60
63
}
61
- foreach (array ($ k => true ) as $ j => $ v ) {
64
+ foreach (array ($ k => true ) as $ gk => $ gv ) {
62
65
}
63
- if ($ k !== $ j ) {
66
+ if ($ gk !== $ k ) {
64
67
$ fromObjCast = true ;
65
68
$ refs = $ vals = \array_values ($ queue [$ i ]);
66
69
break ;
@@ -95,7 +98,7 @@ protected function doClone($var)
95
98
case true === $ v :
96
99
case \is_int ($ v ):
97
100
case \is_float ($ v ):
98
- break ;
101
+ continue 2 ;
99
102
100
103
case \is_string ($ v ):
101
104
if (!\preg_match ('//u ' , $ v )) {
@@ -114,7 +117,10 @@ protected function doClone($var)
114
117
$ stub ->class = Stub::STRING_UTF8 ;
115
118
$ stub ->cut = $ cut ;
116
119
$ stub ->value = \mb_substr ($ v , 0 , $ maxString , 'UTF-8 ' );
120
+ } else {
121
+ continue 2 ;
117
122
}
123
+ $ a = null ;
118
124
break ;
119
125
120
126
case \is_array ($ v ):
@@ -146,11 +152,9 @@ protected function doClone($var)
146
152
} else {
147
153
$ a = $ v ;
148
154
}
149
- } else {
155
+ } elseif (\ PHP_VERSION_ID < 70200 ) {
150
156
$ indexedArrays [$ len ] = true ;
151
157
}
152
-
153
- $ stub ->value = \count ($ a );
154
158
break ;
155
159
156
160
case \is_object ($ v ):
@@ -210,42 +214,40 @@ protected function doClone($var)
210
214
break ;
211
215
}
212
216
213
- if (isset ($ stub )) {
214
- if ($ a ) {
215
- if (!$ i || 0 > $ maxItems ) {
216
- $ queue [$ len ] = $ a ;
217
- $ stub ->position = $ len ++;
218
- } elseif ($ pos < $ maxItems ) {
219
- if ($ maxItems < $ pos += \count ($ a )) {
220
- $ a = \array_slice ($ a , 0 , $ maxItems - $ pos );
221
- if ($ stub ->cut >= 0 ) {
222
- $ stub ->cut += $ pos - $ maxItems ;
223
- }
217
+ if ($ a ) {
218
+ if (!$ i || 0 > $ maxItems ) {
219
+ $ queue [$ len ] = $ a ;
220
+ $ stub ->position = $ len ++;
221
+ } elseif ($ pos < $ maxItems ) {
222
+ if ($ maxItems < $ pos += \count ($ a )) {
223
+ $ a = \array_slice ($ a , 0 , $ maxItems - $ pos );
224
+ if ($ stub ->cut >= 0 ) {
225
+ $ stub ->cut += $ pos - $ maxItems ;
224
226
}
225
- $ queue [$ len ] = $ a ;
226
- $ stub ->position = $ len ++;
227
- } elseif ($ stub ->cut >= 0 ) {
228
- $ stub ->cut += \count ($ a );
229
- $ stub ->position = 0 ;
230
- }
231
- }
232
-
233
- if ($ arrayStub === $ stub ) {
234
- if ($ arrayStub ->cut ) {
235
- $ stub = array ($ arrayStub ->cut , $ arrayStub ->class => $ arrayStub ->position );
236
- $ arrayStub ->cut = 0 ;
237
- } else {
238
- $ stub = array ($ arrayStub ->class => $ arrayStub ->position );
239
227
}
228
+ $ queue [$ len ] = $ a ;
229
+ $ stub ->position = $ len ++;
230
+ } elseif ($ stub ->cut >= 0 ) {
231
+ $ stub ->cut += \count ($ a );
232
+ $ stub ->position = 0 ;
240
233
}
234
+ }
241
235
242
- if ($ zvalIsRef ) {
243
- $ refs [$ k ]->value = $ stub ;
236
+ if ($ arrayStub === $ stub ) {
237
+ if ($ arrayStub ->cut ) {
238
+ $ stub = array ($ arrayStub ->cut , $ arrayStub ->class => $ arrayStub ->position );
239
+ $ arrayStub ->cut = 0 ;
240
+ } elseif (isset (self ::$ arrayCache [$ arrayStub ->class ][$ arrayStub ->position ])) {
241
+ $ stub = self ::$ arrayCache [$ arrayStub ->class ][$ arrayStub ->position ];
244
242
} else {
245
- $ vals [ $ k ] = $ stub ;
243
+ self :: $ arrayCache [ $ arrayStub -> class ][ $ arrayStub -> position ] = $ stub = array ( $ arrayStub -> class => $ arrayStub -> position ) ;
246
244
}
245
+ }
247
246
248
- $ stub = $ a = null ;
247
+ if ($ zvalIsRef ) {
248
+ $ refs [$ k ]->value = $ stub ;
249
+ } else {
250
+ $ vals [$ k ] = $ stub ;
249
251
}
250
252
}
251
253
@@ -255,9 +257,9 @@ protected function doClone($var)
255
257
$ vals = array ();
256
258
$ j = -1 ;
257
259
foreach ($ queue [$ i ] as $ k => $ v ) {
258
- foreach (array ($ k => true ) as $ a => $ v ) {
260
+ foreach (array ($ k => true ) as $ gk => $ gv ) {
259
261
}
260
- if ($ a !== $ k ) {
262
+ if ($ gk !== $ k ) {
261
263
$ vals = (object ) $ vals ;
262
264
$ vals ->{$ k } = $ refs [++$ j ];
263
265
$ vals = (array ) $ vals ;
@@ -268,7 +270,6 @@ protected function doClone($var)
268
270
}
269
271
270
272
$ queue [$ i ] = $ vals ;
271
- unset($ indexedArrays [$ i ]);
272
273
}
273
274
274
275
foreach ($ values as $ h => $ v ) {
0 commit comments