diff --git a/src/Symfony/Bundle/DebugBundle/DebugBundle.php b/src/Symfony/Bundle/DebugBundle/DebugBundle.php index fdd7724dfc..3aa536dba7 100644 --- a/src/Symfony/Bundle/DebugBundle/DebugBundle.php +++ b/src/Symfony/Bundle/DebugBundle/DebugBundle.php @@ -14,7 +14,6 @@ namespace Symfony\Bundle\DebugBundle; use Symfony\Bundle\DebugBundle\DependencyInjection\Compiler\DumpDataCollectorPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; -use Symfony\Component\VarDumper\Dumper\CliDumper; use Symfony\Component\VarDumper\VarDumper; /** @@ -31,7 +30,7 @@ class DebugBundle extends Bundle // configuration for CLI mode is overridden in HTTP mode on // 'kernel.request' event VarDumper::setHandler(function ($var) use ($container) { - $dumper = new CliDumper(); + $dumper = $container->get('var_dumper.cli_dumper'); $cloner = $container->get('var_dumper.cloner'); $handler = function ($var) use ($dumper, $cloner) { $dumper->dump($cloner->cloneVar($var)); diff --git a/src/Symfony/Bundle/DebugBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/DebugBundle/DependencyInjection/Configuration.php index 52cdfa94fe..5761e62a72 100644 --- a/src/Symfony/Bundle/DebugBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/DebugBundle/DependencyInjection/Configuration.php @@ -41,6 +41,11 @@ class Configuration implements ConfigurationInterface ->min(-1) ->defaultValue(-1) ->end() + ->scalarNode('dump_destination') + ->info('A stream URL where dumps should be written to') + ->example('php://stderr') + ->defaultNull() + ->end() ->end() ; diff --git a/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php b/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php index d5c4fd93d1..4e5351c0e0 100644 --- a/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php +++ b/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php @@ -14,6 +14,7 @@ namespace Symfony\Bundle\DebugBundle\DependencyInjection; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpKernel\DependencyInjection\Extension; /** @@ -37,6 +38,15 @@ class DebugExtension extends Extension $container->getDefinition('var_dumper.cloner') ->addMethodCall('setMaxItems', array($config['max_items'])) ->addMethodCall('setMaxString', array($config['max_string_length'])); + + if (null !== $config['dump_destination']) { + $container->getDefinition('var_dumper.cli_dumper') + ->replaceArgument(0, $config['dump_destination']) + ; + $container->getDefinition('data_collector.dump') + ->replaceArgument(4, new Reference('var_dumper.cli_dumper')) + ; + } } /** diff --git a/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml b/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml index 7de182861b..16e27a22c5 100644 --- a/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml +++ b/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml @@ -16,6 +16,7 @@ null %kernel.charset% + null @@ -25,6 +26,10 @@ + + null + %kernel.charset% + diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php index 0327a46f71..32b99e562c 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php @@ -35,13 +35,16 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface private $rootRefs; private $charset; private $dumper; + private $dumperIsInjected; - public function __construct(Stopwatch $stopwatch = null, $fileLinkFormat = null, $charset = null, RequestStack $requestStack = null) + public function __construct(Stopwatch $stopwatch = null, $fileLinkFormat = null, $charset = null, RequestStack $requestStack = null, DataDumperInterface $dumper = null) { $this->stopwatch = $stopwatch; $this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format'); $this->charset = $charset ?: ini_get('php.output_encoding') ?: ini_get('default_charset') ?: 'UTF-8'; $this->requestStack = $requestStack; + $this->dumper = $dumper; + $this->dumperIsInjected = null !== $dumper; // All clones share these properties by reference: $this->rootRefs = array( @@ -123,11 +126,11 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface if ($this->dumper) { $this->doDump($data, $name, $file, $line); - } else { - $this->data[] = compact('data', 'name', 'file', 'line', 'fileExcerpt'); - ++$this->dataCount; } + $this->data[] = compact('data', 'name', 'file', 'line', 'fileExcerpt'); + ++$this->dataCount; + if ($this->stopwatch) { $this->stopwatch->stop('dump'); } @@ -136,7 +139,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface public function collect(Request $request, Response $response, \Exception $exception = null) { // Sub-requests and programmatic calls stay in the collected profile. - if (($this->requestStack && $this->requestStack->getMasterRequest() !== $request) || $request->isXmlHttpRequest() || $request->headers->has('Origin')) { + if ($this->dumper || ($this->requestStack && $this->requestStack->getMasterRequest() !== $request) || $request->isXmlHttpRequest() || $request->headers->has('Origin')) { return; } @@ -154,13 +157,9 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface $this->dumper = new CliDumper('php://output', $this->charset); } - foreach ($this->data as $i => $dump) { - $this->data[$i] = null; + foreach ($this->data as $dump) { $this->doDump($dump['data'], $dump['name'], $dump['file'], $dump['line']); } - - $this->data = array(); - $this->dataCount = 0; } } @@ -174,7 +173,9 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface $this->data = array(); $this->dataCount = 0; $this->isCollected = true; - $this->dumper = null; + if (!$this->dumperIsInjected) { + $this->dumper = null; + } return $ser; } @@ -250,20 +251,33 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface private function doDump($data, $name, $file, $line) { - if ($this->dumper instanceof HtmlDumper) { - $name = $this->htmlEncode($name); - $file = $this->htmlEncode($file); - if ('' !== $file) { - if ($this->fileLinkFormat) { - $link = strtr($this->fileLinkFormat, array('%f' => $file, '%l' => $line)); - $name = sprintf('%s', $link, $file, $name); + if (PHP_VERSION_ID >= 50400 && $this->dumper instanceof CliDumper) { + $contextDumper = function ($name, $file, $line, $fileLinkFormat) { + if ($this instanceof HtmlDumper) { + if ('' !== $file) { + $s = $this->style('meta', '%s'); + $name = strip_tags($this->style('', $name)); + $file = strip_tags($this->style('', $file)); + if ($fileLinkFormat) { + $link = strtr($fileLinkFormat, array('%f' => $file, '%l' => (int) $line)); + $name = sprintf(''.$s.'', $link, $file, $name); + } else { + $name = sprintf(''.$s.'', $file, $name); + } + } else { + $name = $this->style('meta', $name); + } + $this->line = $name.' on line '.$this->style('meta', $line).':'; } else { - $name = sprintf('%s', $file, $name); + $this->line = $this->style('meta', $name).' on line '.$this->style('meta', $line).':'; } - } - echo "\n{$name} on line {$line}:"; + $this->dumpLine(0); + }; + $contextDumper = $contextDumper->bindTo($this->dumper, $this->dumper); + $contextDumper($name, $file, $line, $this->fileLinkFormat); } else { - echo "{$name} on line {$line}:\n"; + $cloner = new VarCloner(); + $this->dumper->dump($cloner->cloneVar($name.' on line '.$line.':')); } $this->dumper->dump($data); } diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php index 7d19cb01b1..e9b8433c46 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php @@ -71,7 +71,13 @@ class DumpDataCollectorTest extends \PHPUnit_Framework_TestCase $collector->collect(new Request(), new Response()); $output = ob_get_clean(); - $this->assertSame("DumpDataCollectorTest.php on line {$line}:\n123\n", $output); + if (PHP_VERSION_ID >= 50400) { + $this->assertSame("DumpDataCollectorTest.php on line {$line}:\n123\n", $output); + } else { + $this->assertSame("\"DumpDataCollectorTest.php on line {$line}:\"\n123\n", $output); + } + $this->assertSame(1, $collector->getDumpsCount()); + $collector->serialize(); } public function testCollectHtml() @@ -83,12 +89,23 @@ class DumpDataCollectorTest extends \PHPUnit_Framework_TestCase $collector->dump($data); $line = __LINE__ - 1; $file = __FILE__; - $xOutput = <<DumpDataCollectorTest.php on line {$line}:
123
+        if (PHP_VERSION_ID >= 50400) {
+            $xOutput = <<DumpDataCollectorTest.php on line {$line}:
+123
 
EOTXT; + } else { + $len = strlen("DumpDataCollectorTest.php on line {$line}:"); + $xOutput = <<"DumpDataCollectorTest.php on line {$line}:" + +
123
+
+ +EOTXT; + } ob_start(); $response = new Response(); @@ -99,6 +116,8 @@ EOTXT; $output = preg_replace('/sf-dump-\d+/', 'sf-dump', $output); $this->assertSame($xOutput, $output); + $this->assertSame(1, $collector->getDumpsCount()); + $collector->serialize(); } public function testFlush() @@ -110,6 +129,10 @@ EOTXT; ob_start(); $collector = null; - $this->assertSame("DumpDataCollectorTest.php on line {$line}:\n456\n", ob_get_clean()); + if (PHP_VERSION_ID >= 50400) { + $this->assertSame("DumpDataCollectorTest.php on line {$line}:\n456\n", ob_get_clean()); + } else { + $this->assertSame("\"DumpDataCollectorTest.php on line {$line}:\"\n456\n", ob_get_clean()); + } } }