Skip to content

Commit 84bde03

Browse files
committed
minor symfony#23974 [VarDumper] Use spl_object_id() with php72 polyfill when needed (nicolas-grekas)
This PR was merged into the 4.0-dev branch. Discussion ---------- [VarDumper] Use spl_object_id() with php72 polyfill when needed | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - Not possible on lower branches because the polyfill doesn't support HHVM. Commits ------- 6dd695e [VarDumper] Use spl_object_id() with php72 polyfill when needed
2 parents 9a6d3e5 + 6dd695e commit 84bde03

File tree

3 files changed

+12
-40
lines changed

3 files changed

+12
-40
lines changed

composer.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
"psr/log": "~1.0",
2828
"psr/simple-cache": "^1.0",
2929
"symfony/polyfill-intl-icu": "~1.0",
30-
"symfony/polyfill-mbstring": "~1.0"
30+
"symfony/polyfill-mbstring": "~1.0",
31+
"symfony/polyfill-php72": "~1.5"
3132
},
3233
"replace": {
3334
"symfony/asset": "self.version",

src/Symfony/Component/VarDumper/Cloner/VarCloner.php

+8-38
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
class VarCloner extends AbstractCloner
1818
{
1919
private static $gid;
20-
private static $hashMask = 0;
21-
private static $hashOffset = 0;
2220
private static $arrayCache = array();
2321

2422
/**
@@ -31,10 +29,10 @@ protected function doClone($var)
3129
$refsCounter = 0; // Hard references counter
3230
$queue = array(array($var)); // This breadth-first queue is the return value
3331
$indexedArrays = array(); // Map of queue indexes that hold numerically indexed arrays
34-
$hardRefs = array(); // Map of original zval hashes to stub objects
32+
$hardRefs = array(); // Map of original zval ids to stub objects
3533
$objRefs = array(); // Map of original object handles to their stub object couterpart
3634
$resRefs = array(); // Map of original resource handles to their stub object couterpart
37-
$values = array(); // Map of stub objects' hashes to original values
35+
$values = array(); // Map of stub objects' ids to original values
3836
$maxItems = $this->maxItems;
3937
$maxString = $this->maxString;
4038
$minDepth = $this->minDepth;
@@ -46,13 +44,9 @@ protected function doClone($var)
4644
$stub = null; // Stub capturing the main properties of an original item value
4745
// or null if the original value is used directly
4846

49-
if (!self::$hashMask) {
50-
self::$gid = uniqid(mt_rand(), true); // Unique string used to detect the special $GLOBALS variable
51-
self::initHashMask();
47+
if (!$gid = self::$gid) {
48+
$gid = self::$gid = uniqid(mt_rand(), true); // Unique string used to detect the special $GLOBALS variable
5249
}
53-
$gid = self::$gid;
54-
$hashMask = self::$hashMask;
55-
$hashOffset = self::$hashOffset;
5650
$arrayStub = new Stub();
5751
$arrayStub->type = Stub::TYPE_ARRAY;
5852
$fromObjCast = false;
@@ -89,7 +83,7 @@ protected function doClone($var)
8983
if ($zvalIsRef = $vals[$k] === $cookie) {
9084
$vals[$k] = &$stub; // Break hard references to make $queue completely
9185
unset($stub); // independent from the original structure
92-
if ($v instanceof Stub && isset($hardRefs[\spl_object_hash($v)])) {
86+
if ($v instanceof Stub && isset($hardRefs[\spl_object_id($v)])) {
9387
$vals[$k] = $refs[$k] = $v;
9488
if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) {
9589
++$v->value->refCount;
@@ -99,7 +93,7 @@ protected function doClone($var)
9993
}
10094
$refs[$k] = $vals[$k] = new Stub();
10195
$refs[$k]->value = $v;
102-
$h = \spl_object_hash($refs[$k]);
96+
$h = \spl_object_id($refs[$k]);
10397
$hardRefs[$h] = &$refs[$k];
10498
$values[$h] = $v;
10599
$vals[$k]->handle = ++$refsCounter;
@@ -172,7 +166,7 @@ protected function doClone($var)
172166

173167
case \is_object($v):
174168
case $v instanceof \__PHP_Incomplete_Class:
175-
if (empty($objRefs[$h = $hashMask ^ \hexdec(\substr(\spl_object_hash($v), $hashOffset, \PHP_INT_SIZE))])) {
169+
if (empty($objRefs[$h = \spl_object_id($v)])) {
176170
$stub = new Stub();
177171
$stub->type = Stub::TYPE_OBJECT;
178172
$stub->class = \get_class($v);
@@ -183,8 +177,7 @@ protected function doClone($var)
183177
if (Stub::TYPE_OBJECT !== $stub->type || null === $stub->value) {
184178
break;
185179
}
186-
$h = $hashMask ^ \hexdec(\substr(\spl_object_hash($stub->value), $hashOffset, \PHP_INT_SIZE));
187-
$stub->handle = $h;
180+
$stub->handle = $h = \spl_object_id($stub->value);
188181
}
189182
$stub->value = null;
190183
if (0 <= $maxItems && $maxItems <= $pos && $minimumDepthReached) {
@@ -291,27 +284,4 @@ protected function doClone($var)
291284

292285
return $queue;
293286
}
294-
295-
private static function initHashMask()
296-
{
297-
$obj = (object) array();
298-
self::$hashOffset = 16 - PHP_INT_SIZE;
299-
self::$hashMask = -1;
300-
301-
// check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below
302-
$obFuncs = array('ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush');
303-
foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) as $frame) {
304-
if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && in_array($frame['function'], $obFuncs)) {
305-
$frame['line'] = 0;
306-
break;
307-
}
308-
}
309-
if (!empty($frame['line'])) {
310-
ob_start();
311-
debug_zval_dump($obj);
312-
self::$hashMask = (int) substr(ob_get_clean(), 17);
313-
}
314-
315-
self::$hashMask ^= hexdec(substr(spl_object_hash($obj), self::$hashOffset, PHP_INT_SIZE));
316-
}
317287
}

src/Symfony/Component/VarDumper/composer.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
],
1818
"require": {
1919
"php": "^7.1.3",
20-
"symfony/polyfill-mbstring": "~1.0"
20+
"symfony/polyfill-mbstring": "~1.0",
21+
"symfony/polyfill-php72": "~1.5"
2122
},
2223
"require-dev": {
2324
"ext-iconv": "*",

0 commit comments

Comments
 (0)