diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/DumpExtensionTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/DumpExtensionTest.php index 16361e3e5d..05166bd293 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/DumpExtensionTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/DumpExtensionTest.php @@ -13,7 +13,7 @@ namespace Symfony\Bridge\Twig\Tests\Extension; use Symfony\Bridge\Twig\Extension\DumpExtension; use Symfony\Component\VarDumper\VarDumper; -use Symfony\Component\VarDumper\Cloner\PhpCloner; +use Symfony\Component\VarDumper\Cloner\VarCloner; class DumpExtensionTest extends \PHPUnit_Framework_TestCase { @@ -22,7 +22,7 @@ class DumpExtensionTest extends \PHPUnit_Framework_TestCase */ public function testDumpTag($template, $debug, $expectedOutput, $expectedDumped) { - $extension = new DumpExtension(new PhpCloner()); + $extension = new DumpExtension(new VarCloner()); $twig = new \Twig_Environment(new \Twig_Loader_String(), array( 'debug' => $debug, 'cache' => false, @@ -62,7 +62,7 @@ class DumpExtensionTest extends \PHPUnit_Framework_TestCase */ public function testDump($context, $args, $expectedOutput, $debug = true) { - $extension = new DumpExtension(new PhpCloner()); + $extension = new DumpExtension(new VarCloner()); $twig = new \Twig_Environment(new \Twig_Loader_String(), array( 'debug' => $debug, 'cache' => false, @@ -77,7 +77,7 @@ class DumpExtensionTest extends \PHPUnit_Framework_TestCase if ($debug) { $this->assertStringStartsWith('\n"), + array(array(), array(), "
[]\n
\n"), array( array(), array(123, 456), - "
123\n
\n" - ."
456\n
\n", + "
123\n
\n" + ."
456\n
\n", ), array( array('foo' => 'bar'), @@ -99,7 +99,7 @@ class DumpExtensionTest extends \PHPUnit_Framework_TestCase "
array:1 [\n"
                 ."  \"foo\" => \"bar\"\n"
                 ."]\n"
-                ."
\n", + ."\n", ), ); } diff --git a/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php b/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php index 4b136c8945..23e9d0c96c 100644 --- a/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php +++ b/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php @@ -34,11 +34,6 @@ class DebugExtension extends Extension $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('services.xml'); - $container->setParameter( - 'var_dumper.cloner.class', - 'Symfony\Component\VarDumper\Cloner\\'.(function_exists('symfony_zval_info') ? 'Ext' : 'Php').'Cloner' - ); - $container->getDefinition('var_dumper.cloner') ->addMethodCall('setMaxItems', array($config['max_items'])) ->addMethodCall('setMaxString', array($config['max_string_length'])); diff --git a/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml b/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml index 290644c6d5..0593cc7efa 100644 --- a/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml +++ b/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml @@ -4,25 +4,20 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - - Symfony\Component\HttpKernel\DataCollector\DumpDataCollector - Symfony\Component\HttpKernel\EventListener\DumpListener - - - + %templating.helper.code.file_link_format% - + data_collector.dump - + diff --git a/src/Symfony/Bundle/DebugBundle/Resources/views/Profiler/dump.html.twig b/src/Symfony/Bundle/DebugBundle/Resources/views/Profiler/dump.html.twig index b453928c04..71f0082725 100644 --- a/src/Symfony/Bundle/DebugBundle/Resources/views/Profiler/dump.html.twig +++ b/src/Symfony/Bundle/DebugBundle/Resources/views/Profiler/dump.html.twig @@ -84,7 +84,7 @@ {{ dump.name }} {% endif %} line {{ dump.line }}: - + {% if dump.fileExcerpt %}{{ dump.fileExcerpt|raw }}{% else %}{{ dump.file|file_excerpt(dump.line) }}{% endif %} diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/debug.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/debug.xml index 36ddc2a33d..70bdafa77c 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/debug.xml +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/debug.xml @@ -6,7 +6,6 @@ Symfony\Bundle\TwigBundle\Debug\TimedTwigEngine - Symfony\Bridge\Twig\Extension\DumpExtension @@ -17,7 +16,7 @@ - + diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php index 5cfdba27d9..5af2959c89 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php @@ -38,7 +38,7 @@ class DumpDataCollectorTest extends \PHPUnit_Framework_TestCase $xDump = array( array( - 'data' => "
123\n
\n", + 'data' => "
123\n
\n", 'name' => 'DumpDataCollectorTest.php', 'file' => __FILE__, 'line' => $line, diff --git a/src/Symfony/Component/VarDumper/Cloner/ExtCloner.php b/src/Symfony/Component/VarDumper/Cloner/ExtCloner.php deleted file mode 100644 index cf1a0d19ea..0000000000 --- a/src/Symfony/Component/VarDumper/Cloner/ExtCloner.php +++ /dev/null @@ -1,201 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Cloner; - -/** - * @author Nicolas Grekas - */ -class ExtCloner extends AbstractCloner -{ - /** - * {@inheritdoc} - */ - protected function doClone($var) - { - $i = 0; // Current iteration position in $queue - $len = 1; // Length of $queue - $pos = 0; // Number of cloned items past the first level - $refs = 0; // Number of hard+soft references in $var - $queue = array(array($var)); // This breadth-first queue is the return value - $arrayRefs = array(); // Map of queue indexes to stub array objects - $hardRefs = array(); // Map of original zval hashes to stub objects - $softRefs = array(); // Map of original object hashes to their stub object couterpart - $maxItems = $this->maxItems; - $maxString = $this->maxString; - $a = null; // Array cast for nested structures - $stub = null; // Stub capturing the main properties of an original item value, - // or null if the original value is used directly - - for ($i = 0; $i < $len; ++$i) { - $indexed = true; // Whether the currently iterated array is numerically indexed or not - $j = -1; // Position in the currently iterated array - $step = $queue[$i]; // Copy of the currently iterated array used for hard references detection - foreach ($step as $k => $v) { - // $k is the original key - // $v is the original value or a stub object in case of hard references - if ($indexed && $k !== ++$j) { - $indexed = false; - } - $zval = symfony_zval_info($k, $step); - if ($zval['zval_isref']) { - $queue[$i][$k] =& $stub; // Break hard references to make $queue completely - unset($stub); // independent from the original structure - if (isset($hardRefs[$h = $zval['zval_hash']])) { - $hardRefs[$h]->ref = ++$refs; - $queue[$i][$k] = $hardRefs[$h]; - continue; - } - } - // Create $stub when the original value $v can not be used directly - // If $v is a nested structure, put that structure in array $a - switch ($zval['type']) { - case 'string': - if (isset($v[0]) && !preg_match('//u', $v)) { - $stub = new Stub(); - $stub->type = Stub::TYPE_STRING; - $stub->class = Stub::STRING_BINARY; - if (0 <= $maxString && 0 < $cut = strlen($v) - $maxString) { - $stub->cut = $cut; - $v = substr_replace($v, '', -$cut); - } - $stub->value = Data::utf8Encode($v); - } elseif (0 <= $maxString && isset($v[1+($maxString>>2)]) && 0 < $cut = iconv_strlen($v, 'UTF-8') - $maxString) { - $stub = new Stub(); - $stub->type = Stub::TYPE_STRING; - $stub->class = Stub::STRING_UTF8; - $stub->cut = $cut; - $stub->value = iconv_substr($v, 0, $maxString, 'UTF-8'); - } - break; - - case 'integer': - break; - - case 'array': - if ($v) { - $stub = $arrayRefs[$len] = new Stub(); - $stub->type = Stub::TYPE_ARRAY; - $stub->class = Stub::ARRAY_ASSOC; - $stub->value = $zval['array_count']; - $a = $v; - } - break; - - case 'object': - if (empty($softRefs[$h = $zval['object_hash']])) { - $stub = new Stub(); - $stub->type = Stub::TYPE_OBJECT; - $stub->class = $zval['object_class']; - $stub->value = $v; - $a = $this->castObject($stub, 0 < $i); - if ($v !== $stub->value) { - if (Stub::TYPE_OBJECT !== $stub->type) { - break; - } - $h = spl_object_hash($stub->value); - } - $stub->value = null; - if (0 <= $maxItems && $maxItems <= $pos) { - $stub->cut = count($a); - $a = null; - } - } - if (empty($softRefs[$h])) { - $softRefs[$h] = $stub; - } else { - $stub = $softRefs[$h]; - $stub->ref = ++$refs; - $a = null; - } - break; - - case 'resource': - if (empty($softRefs[$h = (int) $v])) { - $stub = new Stub(); - $stub->type = Stub::TYPE_RESOURCE; - $stub->class = $zval['resource_type']; - $stub->value = $v; - $a = $this->castResource($stub, 0 < $i); - if ($v !== $stub->value) { - if (Stub::TYPE_RESOURCE !== $stub->type) { - break; - } - $h = (int) $stub->value; - } - $stub->value = null; - if (0 <= $maxItems && $maxItems <= $pos) { - $stub->cut = count($a); - $a = null; - } - } - if (empty($softRefs[$h])) { - $softRefs[$h] = $stub; - } else { - $stub = $softRefs[$h]; - $stub->ref = ++$refs; - $a = null; - } - break; - } - - if (isset($stub)) { - if ($zval['zval_isref']) { - if (Stub::TYPE_ARRAY === $stub->type) { - $queue[$i][$k] = $hardRefs[$zval['zval_hash']] = $stub; - } else { - $queue[$i][$k] = $hardRefs[$zval['zval_hash']] = $v = new Stub(); - $v->value = $stub; - } - } else { - $queue[$i][$k] = $stub; - } - - if ($a) { - if ($i && 0 <= $maxItems) { - $k = count($a); - if ($pos < $maxItems) { - if ($maxItems < $pos += $k) { - $a = array_slice($a, 0, $maxItems - $pos); - if ($stub->cut >= 0) { - $stub->cut += $pos - $maxItems; - } - } - } else { - if ($stub->cut >= 0) { - $stub->cut += $k; - } - $stub = $a = null; - unset($arrayRefs[$len]); - continue; - } - } - $queue[$len] = $a; - $stub->position = $len++; - } - $stub = $a = null; - } elseif ($zval['zval_isref']) { - $queue[$i][$k] = $hardRefs[$zval['zval_hash']] = new Stub(); - $queue[$i][$k]->value = $v; - } - } - - if (isset($arrayRefs[$i])) { - if ($indexed) { - $arrayRefs[$i]->class = Stub::ARRAY_INDEXED; - } - unset($arrayRefs[$i]); - } - } - - return $queue; - } -} diff --git a/src/Symfony/Component/VarDumper/Cloner/PhpCloner.php b/src/Symfony/Component/VarDumper/Cloner/VarCloner.php similarity index 68% rename from src/Symfony/Component/VarDumper/Cloner/PhpCloner.php rename to src/Symfony/Component/VarDumper/Cloner/VarCloner.php index 3fdafff667..6d1a9ffd95 100644 --- a/src/Symfony/Component/VarDumper/Cloner/PhpCloner.php +++ b/src/Symfony/Component/VarDumper/Cloner/VarCloner.php @@ -14,29 +14,37 @@ namespace Symfony\Component\VarDumper\Cloner; /** * @author Nicolas Grekas */ -class PhpCloner extends AbstractCloner +class VarCloner extends AbstractCloner { /** * {@inheritdoc} */ protected function doClone($var) { + $useExt = extension_loaded('symfony_debug'); $i = 0; // Current iteration position in $queue $len = 1; // Length of $queue $pos = 0; // Number of cloned items past the first level $refs = 0; // Number of hard+soft references in $var $queue = array(array($var)); // This breadth-first queue is the return value $arrayRefs = array(); // Map of queue indexes to stub array objects - $hardRefs = array(); // By-ref map of stub objects' hashes to original hard `&` references + $hardRefs = array(); // Map of original zval hashes to stub objects $softRefs = array(); // Map of original object hashes to their stub object couterpart $values = array(); // Map of stub objects' hashes to original values $maxItems = $this->maxItems; $maxString = $this->maxString; $cookie = (object) array(); // Unique object used to detect hard references - $isRef = false; $a = null; // Array cast for nested structures $stub = null; // Stub capturing the main properties of an original item value, // or null if the original value is used directly + $zval = array( // Main properties of the current value + 'type' => null, + 'zval_isref' => null, + 'array_count' => null, + 'object_class' => null, + 'object_hash' => null, + 'resource_type' => null, + ); for ($i = 0; $i < $len; ++$i) { $indexed = true; // Whether the currently iterated array is numerically indexed or not @@ -48,20 +56,33 @@ class PhpCloner extends AbstractCloner if ($indexed && $k !== ++$j) { $indexed = false; } - $step[$k] = $cookie; - if ($queue[$i][$k] === $cookie) { - $queue[$i][$k] =& $stub; // Break hard references to make $queue completely - unset($stub); // independent from the original structure - if ($v instanceof Stub && isset($hardRefs[spl_object_hash($v)])) { - $v->ref = ++$refs; - $step[$k] = $queue[$i][$k] = $v; - continue; + if ($useExt) { + $zval = symfony_zval_info($k, $step); + if ($zval['zval_isref']) { + $queue[$i][$k] =& $stub; // Break hard references to make $queue completely + unset($stub); // independent from the original structure + if (isset($hardRefs[$h = $zval['zval_hash']])) { + $hardRefs[$h]->ref = ++$refs; + $queue[$i][$k] = $hardRefs[$h]; + continue; + } } - $isRef = true; + } else { + $step[$k] = $cookie; + if ($zval['zval_isref'] = $queue[$i][$k] === $cookie) { + $queue[$i][$k] =& $stub; // Break hard references to make $queue completely + unset($stub); // independent from the original structure + if ($v instanceof Stub && isset($hardRefs[spl_object_hash($v)])) { + $v->ref = ++$refs; + $step[$k] = $queue[$i][$k] = $v; + continue; + } + } + $zval['type'] = gettype($v); } // Create $stub when the original value $v can not be used directly // If $v is a nested structure, put that structure in array $a - switch (gettype($v)) { + switch ($zval['type']) { case 'string': if (isset($v[0]) && !preg_match('//u', $v)) { $stub = new Stub(); @@ -74,7 +95,7 @@ class PhpCloner extends AbstractCloner $cut = $v; } $stub->value = Data::utf8Encode($cut); - } elseif (0 <= $maxString && isset($v[1+($maxString>>2)]) && 0 < $cut = iconv_strlen($v, 'UTF-8') - $maxString) { + } elseif (0 <= $maxString && isset($v[1 + ($maxString >> 2)]) && 0 < $cut = iconv_strlen($v, 'UTF-8') - $maxString) { $stub = new Stub(); $stub->type = Stub::TYPE_STRING; $stub->class = Stub::STRING_UTF8; @@ -91,16 +112,16 @@ class PhpCloner extends AbstractCloner $stub = $arrayRefs[$len] = new Stub(); $stub->type = Stub::TYPE_ARRAY; $stub->class = Stub::ARRAY_ASSOC; - $stub->value = count($v); + $stub->value = $v ? $zval['array_count'] ?: count($v) : 0; $a = $v; } break; case 'object': - if (empty($softRefs[$h = spl_object_hash($v)])) { + if (empty($softRefs[$h = $zval['object_hash'] ?: spl_object_hash($v)])) { $stub = new Stub(); $stub->type = Stub::TYPE_OBJECT; - $stub->class = get_class($v); + $stub->class = $zval['object_class'] ?: get_class($v); $stub->value = $v; $a = $this->castObject($stub, 0 < $i); if ($v !== $stub->value) { @@ -129,7 +150,7 @@ class PhpCloner extends AbstractCloner if (empty($softRefs[$h = (int) $v])) { $stub = new Stub(); $stub->type = Stub::TYPE_RESOURCE; - $stub->class = get_resource_type($v); + $stub->class = $zval['resource_type'] ?: get_resource_type($v); $stub->value = $v; $a = $this->castResource($stub, 0 < $i); if ($v !== $stub->value) { @@ -155,17 +176,25 @@ class PhpCloner extends AbstractCloner } if (isset($stub)) { - if ($isRef) { - if (Stub::TYPE_ARRAY === $stub->type) { - $step[$k] = $stub; + if ($zval['zval_isref']) { + if ($useExt) { + if (Stub::TYPE_ARRAY === $stub->type) { + $queue[$i][$k] = $hardRefs[$zval['zval_hash']] = $stub; + } else { + $queue[$i][$k] = $hardRefs[$zval['zval_hash']] = $v = new Stub(); + $v->value = $stub; + } } else { - $step[$k] = new Stub(); - $step[$k]->value = $stub; + if (Stub::TYPE_ARRAY === $stub->type) { + $step[$k] = $stub; + } else { + $step[$k] = new Stub(); + $step[$k]->value = $stub; + } + $h = spl_object_hash($step[$k]); + $queue[$i][$k] = $hardRefs[$h] =& $step[$k]; + $values[$h] = $v; } - $h = spl_object_hash($step[$k]); - $queue[$i][$k] = $hardRefs[$h] =& $step[$k]; - $values[$h] = $v; - $isRef = false; } else { $queue[$i][$k] = $stub; } @@ -193,13 +222,17 @@ class PhpCloner extends AbstractCloner $stub->position = $len++; } $stub = $a = null; - } elseif ($isRef) { - $step[$k] = $queue[$i][$k] = new Stub(); - $step[$k]->value = $v; - $h = spl_object_hash($step[$k]); - $hardRefs[$h] =& $step[$k]; - $values[$h] = $v; - $isRef = false; + } elseif ($zval['zval_isref']) { + if ($useExt) { + $queue[$i][$k] = $hardRefs[$zval['zval_hash']] = new Stub(); + $queue[$i][$k]->value = $v; + } else { + $step[$k] = $queue[$i][$k] = new Stub(); + $step[$k]->value = $v; + $h = spl_object_hash($step[$k]); + $hardRefs[$h] =& $step[$k]; + $values[$h] = $v; + } } } diff --git a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php index b8bb8192f9..b6093fa14e 100644 --- a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php @@ -25,7 +25,7 @@ class HtmlDumper extends CliDumper protected $dumpHeader; protected $dumpPrefix = '
';
-    protected $dumpSuffix = '
'; + protected $dumpSuffix = ''; protected $dumpId = 'sf-dump'; protected $colors = true; protected $headerIsDumped = false; @@ -106,17 +106,16 @@ class HtmlDumper extends CliDumper $line = <<<'EOHTML'