[TwigBridge] add Twig dump() function + tests and fixes
This commit is contained in:
parent
0f8d30fd89
commit
2e167ba351
|
@ -85,10 +85,7 @@
|
|||
"src/Symfony/Component/HttpFoundation/Resources/stubs",
|
||||
"src/Symfony/Component/Intl/Resources/stubs"
|
||||
],
|
||||
"files": [
|
||||
"src/Symfony/Component/Intl/Resources/stubs/functions.php",
|
||||
"src/Symfony/Component/VarDumper/Resources/functions/dump.php"
|
||||
]
|
||||
"files": [ "src/Symfony/Component/Intl/Resources/stubs/functions.php" ]
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
namespace Symfony\Bridge\Twig\Extension;
|
||||
|
||||
use Symfony\Bridge\Twig\TokenParser\DumpTokenParser;
|
||||
use Symfony\Component\VarDumper\Cloner\ClonerInterface;
|
||||
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
|
||||
|
||||
/**
|
||||
* Provides integration of the dump() function with Twig.
|
||||
|
@ -20,6 +22,18 @@ use Symfony\Bridge\Twig\TokenParser\DumpTokenParser;
|
|||
*/
|
||||
class DumpExtension extends \Twig_Extension
|
||||
{
|
||||
public function __construct(ClonerInterface $cloner = null)
|
||||
{
|
||||
$this->cloner = $cloner;
|
||||
}
|
||||
|
||||
public function getFunctions()
|
||||
{
|
||||
return array(
|
||||
new \Twig_SimpleFunction('dump', array($this, 'dump'), array('is_safe' => array('html'), 'needs_context' => true, 'needs_environment' => true)),
|
||||
);
|
||||
}
|
||||
|
||||
public function getTokenParsers()
|
||||
{
|
||||
return array(new DumpTokenParser());
|
||||
|
@ -29,4 +43,38 @@ class DumpExtension extends \Twig_Extension
|
|||
{
|
||||
return 'dump';
|
||||
}
|
||||
|
||||
public function dump(\Twig_Environment $env, $context)
|
||||
{
|
||||
if (!$env->isDebug() || !$this->cloner) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (2 === func_num_args()) {
|
||||
$vars = array();
|
||||
foreach ($context as $key => $value) {
|
||||
if (!$value instanceof \Twig_Template) {
|
||||
$vars[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$vars = array($vars);
|
||||
} else {
|
||||
$vars = func_get_args();
|
||||
unset($vars[0], $vars[1]);
|
||||
}
|
||||
|
||||
$html = '';
|
||||
$dumper = new HtmlDumper(function ($line, $depth) use (&$html) {
|
||||
if (-1 !== $depth) {
|
||||
$html .= str_repeat(' ', $depth).$line."\n";
|
||||
}
|
||||
});
|
||||
|
||||
foreach ($vars as $value) {
|
||||
$dumper->dump($this->cloner->cloneVar($value));
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,20 +13,22 @@ namespace Symfony\Bridge\Twig\Tests\Extension;
|
|||
|
||||
use Symfony\Bridge\Twig\Extension\DumpExtension;
|
||||
use Symfony\Component\VarDumper\VarDumper;
|
||||
use Symfony\Component\VarDumper\Cloner\PhpCloner;
|
||||
|
||||
class DumpExtensionTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider getDumpParams
|
||||
* @dataProvider getDumpTags
|
||||
*/
|
||||
public function testDebugDump($template, $debug, $expectedOutput, $expectedDumped)
|
||||
public function testDumpTag($template, $debug, $expectedOutput, $expectedDumped)
|
||||
{
|
||||
$extension = new DumpExtension(new PhpCloner());
|
||||
$twig = new \Twig_Environment(new \Twig_Loader_String(), array(
|
||||
'debug' => $debug,
|
||||
'cache' => false,
|
||||
'optimizations' => 0,
|
||||
));
|
||||
$twig->addExtension(new DumpExtension());
|
||||
$twig->addExtension($extension);
|
||||
|
||||
$dumped = null;
|
||||
$exception = null;
|
||||
|
@ -46,7 +48,7 @@ class DumpExtensionTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertSame($expectedDumped, $dumped);
|
||||
}
|
||||
|
||||
public function getDumpParams()
|
||||
public function getDumpTags()
|
||||
{
|
||||
return array(
|
||||
array('A{% dump %}B', true, 'AB', array()),
|
||||
|
@ -54,4 +56,50 @@ class DumpExtensionTest extends \PHPUnit_Framework_TestCase
|
|||
array('A{% dump %}B', false, 'AB', null),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getDumpArgs
|
||||
*/
|
||||
public function testDump($context, $args, $expectedOutput, $debug = true)
|
||||
{
|
||||
$extension = new DumpExtension(new PhpCloner());
|
||||
$twig = new \Twig_Environment(new \Twig_Loader_String(), array(
|
||||
'debug' => $debug,
|
||||
'cache' => false,
|
||||
'optimizations' => 0,
|
||||
));
|
||||
|
||||
array_unshift($args, $context);
|
||||
array_unshift($args, $twig);
|
||||
|
||||
$dump = call_user_func_array(array($extension, 'dump'), $args);
|
||||
|
||||
if ($debug) {
|
||||
$this->assertStringStartsWith('<script>', $dump);
|
||||
$dump = preg_replace('/^.*?<pre/', '<pre', $dump);
|
||||
}
|
||||
$this->assertEquals($expectedOutput, $dump);
|
||||
}
|
||||
|
||||
public function getDumpArgs()
|
||||
{
|
||||
return array(
|
||||
array(array(), array(), '', false),
|
||||
array(array(), array(), "<pre id=sf-dump><span class=sf-dump-0>[]\n</span></pre><script>Sfjs.dump.instrument()</script>\n"),
|
||||
array(
|
||||
array(),
|
||||
array(123, 456),
|
||||
"<pre id=sf-dump><span class=sf-dump-0><span class=sf-dump-num>123</span>\n</span></pre><script>Sfjs.dump.instrument()</script>\n"
|
||||
."<pre id=sf-dump><span class=sf-dump-0><span class=sf-dump-num>456</span>\n</span></pre><script>Sfjs.dump.instrument()</script>\n",
|
||||
),
|
||||
array(
|
||||
array('foo' => 'bar'),
|
||||
array(),
|
||||
"<pre id=sf-dump><span class=sf-dump-0><span class=sf-dump-note>array:1</span> [<span name=sf-dump-child>\n"
|
||||
." <span class=sf-dump-1>\"<span class=sf-dump-meta>foo</span>\" => \"<span class=sf-dump-str>bar</span>\"\n"
|
||||
."</span></span>]\n"
|
||||
."</span></pre><script>Sfjs.dump.instrument()</script>\n",
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,12 +17,9 @@
|
|||
<argument type="service" id="debug.stopwatch" />
|
||||
</service>
|
||||
|
||||
<service id="twig.extension.debug" class="Twig_Extension_Debug" public="false">
|
||||
<tag name="twig.extension" />
|
||||
</service>
|
||||
|
||||
<service id="twig.extension.dump" class="%twig.extension.dump.class%" public="false">
|
||||
<tag name="twig.extension" />
|
||||
<argument type="service" id="var_dumper.cloner" on-invalid="null" />
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
|
|
|
@ -169,7 +169,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
|
|||
$dumper->dump(
|
||||
$dump['data']->getLimitedClone($maxDepthLimit, $maxItemsPerDepth),
|
||||
function ($line, $depth) use (&$data) {
|
||||
if (false !==$depth) {
|
||||
if (-1 !== $depth) {
|
||||
$data .= str_repeat(' ', $depth).$line."\n";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,14 +34,17 @@ class DumpDataCollectorTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
$xDump = array(
|
||||
array(
|
||||
'data' => "<!DOCTYPE html><style> pre.sf-dump { background-color: #300a24; white-space: pre; line-height: 1.2em; color: #eee8d5; font-family: monospace, sans-serif; padding: 5px; } .sf-dump span { display: inline; }a.sf-dump-ref {color:#444444}span.sf-dump-num {font-weight:bold;color:#0087FF}span.sf-dump-const {font-weight:bold;color:#0087FF}span.sf-dump-str {font-weight:bold;color:#00D7FF}span.sf-dump-cchr {font-style: italic}span.sf-dump-note {color:#D7AF00}span.sf-dump-ref {color:#444444}span.sf-dump-public {color:#008700}span.sf-dump-protected {color:#D75F00}span.sf-dump-private {color:#D70000}span.sf-dump-meta {color:#005FFF}</style><pre class=sf-dump><span class=sf-dump-0><span class=sf-dump-num>123</span>\n</pre>\n",
|
||||
'data' => "<pre id=sf-dump><span class=sf-dump-0><span class=sf-dump-num>123</span>\n</span></pre><script>Sfjs.dump.instrument()</script>\n",
|
||||
'name' => 'DumpDataCollectorTest.php',
|
||||
'file' => __FILE__,
|
||||
'line' => $line,
|
||||
'fileExcerpt' => false,
|
||||
),
|
||||
);
|
||||
$this->assertSame($xDump, $collector->getDumps('html'));
|
||||
$dump = $collector->getDumps('html');
|
||||
$this->assertTrue(isset($dump[0]['data']));
|
||||
$dump[0]['data'] = preg_replace('/^.*?<pre/', '<pre', $dump[0]['data']);
|
||||
$this->assertSame($xDump, $dump);
|
||||
|
||||
$this->assertStringStartsWith(
|
||||
'a:1:{i:0;a:5:{s:4:"data";O:39:"Symfony\Component\VarDumper\Cloner\Data":3:{s:45:"Symfony\Component\VarDumper\Cloner\Datadata";a:1:{i:0;a:1:{i:0;i:123;}}s:49:"Symfony\Component\VarDumper\Cloner\DatamaxDepth";i:-1;s:57:"Symfony\Component\VarDumper\Cloner\DatamaxItemsPerDepth";i:-1;}s:4:"name";s:25:"DumpDataCollectorTest.php";s:4:"file";s:',
|
||||
|
|
|
@ -29,8 +29,9 @@ class ReflectionCaster
|
|||
|
||||
public static function castClosure(\Closure $c, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$stub->class = 'Closure'; // HHVM generates unique class names for closures
|
||||
$a = static::castReflector(new \ReflectionFunction($c), $a, $stub, $isNested);
|
||||
unset($a["\0+\0000"], $a['name']);
|
||||
unset($a["\0+\0000"], $a['name'], $a["\0+\0this"], $a["\0+\0parameter"]);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ class ResourceCaster
|
|||
public static function castDba($dba, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$list = dba_list();
|
||||
$a['file'] = $list[substr((string) $dba, 13)];
|
||||
$a['file'] = $list[(int) $dba];
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
|
|
@ -21,64 +21,64 @@ use Symfony\Component\VarDumper\Exception\ThrowingCasterException;
|
|||
abstract class AbstractCloner implements ClonerInterface
|
||||
{
|
||||
public static $defaultCasters = array(
|
||||
'o:Symfony\Component\VarDumper\Caster\CasterStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castStub',
|
||||
'Symfony\Component\VarDumper\Caster\CasterStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castStub',
|
||||
|
||||
'o:Closure' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClosure',
|
||||
'o:Reflector' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castReflector',
|
||||
'Closure' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClosure',
|
||||
'Reflector' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castReflector',
|
||||
|
||||
'o:Doctrine\Common\Persistence\ObjectManager' => 'Symfony\Component\VarDumper\Caster\StubCaster::castNestedFat',
|
||||
'o:Doctrine\Common\Proxy\Proxy' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castCommonProxy',
|
||||
'o:Doctrine\ORM\Proxy\Proxy' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castOrmProxy',
|
||||
'o:Doctrine\ORM\PersistentCollection' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castPersistentCollection',
|
||||
'Doctrine\Common\Persistence\ObjectManager' => 'Symfony\Component\VarDumper\Caster\StubCaster::castNestedFat',
|
||||
'Doctrine\Common\Proxy\Proxy' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castCommonProxy',
|
||||
'Doctrine\ORM\Proxy\Proxy' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castOrmProxy',
|
||||
'Doctrine\ORM\PersistentCollection' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castPersistentCollection',
|
||||
|
||||
'o:DOMException' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castException',
|
||||
'o:DOMStringList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
|
||||
'o:DOMNameList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
|
||||
'o:DOMImplementation' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castImplementation',
|
||||
'o:DOMImplementationList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
|
||||
'o:DOMNode' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNode',
|
||||
'o:DOMNameSpaceNode' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNameSpaceNode',
|
||||
'o:DOMDocument' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDocument',
|
||||
'o:DOMNodeList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
|
||||
'o:DOMNamedNodeMap' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
|
||||
'o:DOMCharacterData' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castCharacterData',
|
||||
'o:DOMAttr' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castAttr',
|
||||
'o:DOMElement' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castElement',
|
||||
'o:DOMText' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castText',
|
||||
'o:DOMTypeinfo' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castTypeinfo',
|
||||
'o:DOMDomError' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDomError',
|
||||
'o:DOMLocator' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLocator',
|
||||
'o:DOMDocumentType' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDocumentType',
|
||||
'o:DOMNotation' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNotation',
|
||||
'o:DOMEntity' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castEntity',
|
||||
'o:DOMProcessingInstruction' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castProcessingInstruction',
|
||||
'o:DOMXPath' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castXPath',
|
||||
'DOMException' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castException',
|
||||
'DOMStringList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
|
||||
'DOMNameList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
|
||||
'DOMImplementation' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castImplementation',
|
||||
'DOMImplementationList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
|
||||
'DOMNode' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNode',
|
||||
'DOMNameSpaceNode' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNameSpaceNode',
|
||||
'DOMDocument' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDocument',
|
||||
'DOMNodeList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
|
||||
'DOMNamedNodeMap' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
|
||||
'DOMCharacterData' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castCharacterData',
|
||||
'DOMAttr' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castAttr',
|
||||
'DOMElement' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castElement',
|
||||
'DOMText' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castText',
|
||||
'DOMTypeinfo' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castTypeinfo',
|
||||
'DOMDomError' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDomError',
|
||||
'DOMLocator' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLocator',
|
||||
'DOMDocumentType' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDocumentType',
|
||||
'DOMNotation' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNotation',
|
||||
'DOMEntity' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castEntity',
|
||||
'DOMProcessingInstruction' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castProcessingInstruction',
|
||||
'DOMXPath' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castXPath',
|
||||
|
||||
'o:ErrorException' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castErrorException',
|
||||
'o:Exception' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castException',
|
||||
'o:Symfony\Component\DependencyInjection\ContainerInterface'
|
||||
'ErrorException' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castErrorException',
|
||||
'Exception' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castException',
|
||||
'Symfony\Component\DependencyInjection\ContainerInterface'
|
||||
=> 'Symfony\Component\VarDumper\Caster\StubCaster::castNestedFat',
|
||||
'o:Symfony\Component\VarDumper\Exception\ThrowingCasterException'
|
||||
'Symfony\Component\VarDumper\Exception\ThrowingCasterException'
|
||||
=> 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castThrowingCasterException',
|
||||
|
||||
'o:PDO' => 'Symfony\Component\VarDumper\Caster\PdoCaster::castPdo',
|
||||
'o:PDOStatement' => 'Symfony\Component\VarDumper\Caster\PdoCaster::castPdoStatement',
|
||||
'PDO' => 'Symfony\Component\VarDumper\Caster\PdoCaster::castPdo',
|
||||
'PDOStatement' => 'Symfony\Component\VarDumper\Caster\PdoCaster::castPdoStatement',
|
||||
|
||||
'o:ArrayObject' => 'Symfony\Component\VarDumper\Caster\SplCaster::castArrayObject',
|
||||
'o:SplDoublyLinkedList' => 'Symfony\Component\VarDumper\Caster\SplCaster::castDoublyLinkedList',
|
||||
'o:SplFixedArray' => 'Symfony\Component\VarDumper\Caster\SplCaster::castFixedArray',
|
||||
'o:SplHeap' => 'Symfony\Component\VarDumper\Caster\SplCaster::castHeap',
|
||||
'o:SplObjectStorage' => 'Symfony\Component\VarDumper\Caster\SplCaster::castObjectStorage',
|
||||
'o:SplPriorityQueue' => 'Symfony\Component\VarDumper\Caster\SplCaster::castHeap',
|
||||
'ArrayObject' => 'Symfony\Component\VarDumper\Caster\SplCaster::castArrayObject',
|
||||
'SplDoublyLinkedList' => 'Symfony\Component\VarDumper\Caster\SplCaster::castDoublyLinkedList',
|
||||
'SplFixedArray' => 'Symfony\Component\VarDumper\Caster\SplCaster::castFixedArray',
|
||||
'SplHeap' => 'Symfony\Component\VarDumper\Caster\SplCaster::castHeap',
|
||||
'SplObjectStorage' => 'Symfony\Component\VarDumper\Caster\SplCaster::castObjectStorage',
|
||||
'SplPriorityQueue' => 'Symfony\Component\VarDumper\Caster\SplCaster::castHeap',
|
||||
|
||||
'r:curl' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castCurl',
|
||||
'r:dba' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castDba',
|
||||
'r:dba persistent' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castDba',
|
||||
'r:gd' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castGd',
|
||||
'r:mysql link' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castMysqlLink',
|
||||
'r:process' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castProcess',
|
||||
'r:stream' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castStream',
|
||||
'r:stream-context' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castStreamContext',
|
||||
':curl' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castCurl',
|
||||
':dba' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castDba',
|
||||
':dba persistent' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castDba',
|
||||
':gd' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castGd',
|
||||
':mysql link' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castMysqlLink',
|
||||
':process' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castProcess',
|
||||
':stream' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castStream',
|
||||
':stream-context' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castStreamContext',
|
||||
);
|
||||
|
||||
protected $maxItems = 250;
|
||||
|
@ -107,8 +107,7 @@ abstract class AbstractCloner implements ClonerInterface
|
|||
*
|
||||
* Maps resources or objects types to a callback.
|
||||
* Types are in the key, with a callable caster for value.
|
||||
* Objects class are to be prefixed with a `o:`,
|
||||
* resources type are to be prefixed with a `r:`,
|
||||
* Resource types are to be prefixed with a `:`,
|
||||
* see e.g. static::$defaultCasters.
|
||||
*
|
||||
* @param callable[] $casters A map of casters.
|
||||
|
@ -193,7 +192,7 @@ abstract class AbstractCloner implements ClonerInterface
|
|||
$class,
|
||||
method_exists($class, '__debugInfo'),
|
||||
new \ReflectionClass($class),
|
||||
array_reverse(array($class => $class) + class_parents($class) + class_implements($class) + array('*' => '*')),
|
||||
array_reverse(array($class => $class) + class_parents($class) + class_implements($class)),
|
||||
);
|
||||
|
||||
$this->classInfo[$class] = $classInfo;
|
||||
|
@ -213,7 +212,7 @@ abstract class AbstractCloner implements ClonerInterface
|
|||
}
|
||||
|
||||
foreach ($classInfo[3] as $p) {
|
||||
if (!empty($this->casters[$p = 'o:'.strtolower($p)])) {
|
||||
if (!empty($this->casters[$p = strtolower($p)])) {
|
||||
foreach ($this->casters[$p] as $p) {
|
||||
$a = $this->callCaster($p, $obj, $a, $stub, $isNested);
|
||||
}
|
||||
|
@ -237,8 +236,8 @@ abstract class AbstractCloner implements ClonerInterface
|
|||
$a = array();
|
||||
$type = $stub->class;
|
||||
|
||||
if (!empty($this->casters['r:'.$type])) {
|
||||
foreach ($this->casters['r:'.$type] as $c) {
|
||||
if (!empty($this->casters[':'.$type])) {
|
||||
foreach ($this->casters[':'.$type] as $c) {
|
||||
$a = $this->callCaster($c, $res, $a, $stub, $isNested);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,9 +9,7 @@
|
|||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Dumper;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
namespace Symfony\Component\VarDumper\Cloner;
|
||||
|
||||
/**
|
||||
* Represents the current state of a dumper while dumping.
|
|
@ -11,9 +11,6 @@
|
|||
|
||||
namespace Symfony\Component\VarDumper\Cloner;
|
||||
|
||||
use Symfony\Component\VarDumper\Dumper\DumperInternalsInterface;
|
||||
use Symfony\Component\VarDumper\Dumper\Cursor;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
|
@ -57,21 +54,21 @@ class Data
|
|||
}
|
||||
|
||||
/**
|
||||
* Dumps data with a DumperInternalsInterface dumper.
|
||||
* Dumps data with a DumperInterface dumper.
|
||||
*/
|
||||
public function dump(DumperInternalsInterface $dumper)
|
||||
public function dump(DumperInterface $dumper)
|
||||
{
|
||||
$refs = array(0);
|
||||
$this->dumpItem($dumper, new Cursor, $refs, $this->data[0][0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Breadth-first dumping of items.
|
||||
* Depth-first dumping of items.
|
||||
*
|
||||
* @param DumperInternalsInterface $dumper The dumper being used for dumping.
|
||||
* @param Cursor $cursor A cursor used for tracking dumper state position.
|
||||
* @param array &$refs A map of all references discovered while dumping.
|
||||
* @param mixed $item A Stub object or the original value being dumped.
|
||||
* @param DumperInterface $dumper The dumper being used for dumping.
|
||||
* @param Cursor $cursor A cursor used for tracking dumper state position.
|
||||
* @param array &$refs A map of all references discovered while dumping.
|
||||
* @param mixed $item A Stub object or the original value being dumped.
|
||||
*/
|
||||
private function dumpItem($dumper, $cursor, &$refs, $item)
|
||||
{
|
||||
|
@ -157,12 +154,12 @@ class Data
|
|||
/**
|
||||
* Dumps children of hash structures.
|
||||
*
|
||||
* @param DumperInternalsInterface $dumper
|
||||
* @param Cursor $parentCursor The cursor of the parent hash.
|
||||
* @param array &$refs A map of all references discovered while dumping.
|
||||
* @param array $children The children to dump.
|
||||
* @param int $hashCut The number of items removed from the original hash.
|
||||
* @param string $hashType A Cursor::HASH_* const.
|
||||
* @param DumperInterface $dumper
|
||||
* @param Cursor $parentCursor The cursor of the parent hash.
|
||||
* @param array &$refs A map of all references discovered while dumping.
|
||||
* @param array $children The children to dump.
|
||||
* @param int $hashCut The number of items removed from the original hash.
|
||||
* @param string $hashType A Cursor::HASH_* const.
|
||||
*
|
||||
* @return int The final number of removed items.
|
||||
*/
|
||||
|
|
|
@ -9,14 +9,14 @@
|
|||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Dumper;
|
||||
namespace Symfony\Component\VarDumper\Cloner;
|
||||
|
||||
/**
|
||||
* DumperInterface used by Data objects.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
interface DumperInternalsInterface
|
||||
interface DumperInterface
|
||||
{
|
||||
/**
|
||||
* Dumps a scalar value.
|
|
@ -12,13 +12,14 @@
|
|||
namespace Symfony\Component\VarDumper\Dumper;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Data;
|
||||
use Symfony\Component\VarDumper\Cloner\DumperInterface;
|
||||
|
||||
/**
|
||||
* Abstract mechanism for dumping a Data object.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
abstract class AbstractDumper implements DataDumperInterface, DumperInternalsInterface
|
||||
abstract class AbstractDumper implements DataDumperInterface, DumperInterface
|
||||
{
|
||||
public static $defaultOutputStream = 'php://output';
|
||||
|
||||
|
@ -87,14 +88,22 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInternalsInt
|
|||
*/
|
||||
public function dump(Data $data, $lineDumper = null)
|
||||
{
|
||||
$this->decimalPoint = (string) 0.5;
|
||||
$this->decimalPoint = $this->decimalPoint[1];
|
||||
$dumper = clone $this;
|
||||
$exception = null;
|
||||
if ($lineDumper) {
|
||||
$dumper->setLineDumper($lineDumper);
|
||||
$prevLineDumper = $this->setLineDumper($lineDumper);
|
||||
}
|
||||
try {
|
||||
$data->dump($this);
|
||||
$this->dumpLine(-1);
|
||||
} catch (\Exception $exception) {
|
||||
// Re-thrown below
|
||||
}
|
||||
if ($lineDumper) {
|
||||
$this->setLineDumper($prevLineDumper);
|
||||
}
|
||||
if (null !== $exception) {
|
||||
throw $exception;
|
||||
}
|
||||
$data->dump($dumper);
|
||||
$dumper->dumpLine(false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,7 +125,7 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInternalsInt
|
|||
*/
|
||||
protected function echoLine($line, $depth)
|
||||
{
|
||||
if (false !== $depth) {
|
||||
if (-1 !== $depth) {
|
||||
fwrite($this->outputStream, str_repeat($this->indentPad, $depth).$line."\n");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
namespace Symfony\Component\VarDumper\Dumper;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Data;
|
||||
use Symfony\Component\VarDumper\Cloner\Cursor;
|
||||
|
||||
/**
|
||||
* CliDumper dumps variables for command line output.
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
namespace Symfony\Component\VarDumper\Dumper;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Cursor;
|
||||
|
||||
/**
|
||||
* HtmlDumper dumps variables as HTML.
|
||||
*
|
||||
|
@ -21,8 +23,8 @@ class HtmlDumper extends CliDumper
|
|||
public static $defaultOutputStream = 'php://output';
|
||||
|
||||
protected $dumpHeader;
|
||||
protected $dumpPrefix = '<pre class=sf-dump>';
|
||||
protected $dumpSuffix = '</pre>';
|
||||
protected $dumpPrefix = '<pre id=sf-dump>';
|
||||
protected $dumpSuffix = '</pre><script>Sfjs.dump.instrument()</script>';
|
||||
protected $colors = true;
|
||||
protected $headerIsDumped = false;
|
||||
protected $lastDepth = -1;
|
||||
|
@ -74,7 +76,7 @@ class HtmlDumper extends CliDumper
|
|||
* @param string $prefix The prepended HTML string.
|
||||
* @param string $suffix The appended HTML string.
|
||||
*/
|
||||
public function setDumpBoudaries($prefix, $suffix)
|
||||
public function setDumpBoundaries($prefix, $suffix)
|
||||
{
|
||||
$this->dumpPrefix = $prefix;
|
||||
$this->dumpSuffix = $suffix;
|
||||
|
@ -87,28 +89,104 @@ class HtmlDumper extends CliDumper
|
|||
{
|
||||
$this->headerIsDumped = true;
|
||||
|
||||
$p = 'sf-dump';
|
||||
$line = <<<EOHTML
|
||||
<!DOCTYPE html><style>
|
||||
pre.sf-dump {
|
||||
if (null !== $this->dumpHeader) {
|
||||
return $this->dumpHeader;
|
||||
}
|
||||
|
||||
$line = <<<'EOHTML'
|
||||
<script>
|
||||
Sfjs = window.Sfjs || {};
|
||||
Sfjs.dump = Sfjs.dump || {};
|
||||
Sfjs.dump.childElts = document.getElementsByName('sf-dump-child');
|
||||
Sfjs.dump.childLen = 0;
|
||||
Sfjs.dump.instrument = function () {
|
||||
var elt,
|
||||
i = this.childLen,
|
||||
aCompact = '▶</a><span class="sf-dump-compact">',
|
||||
aExpanded = '▼</a><span class="sf-dump-expanded">';
|
||||
|
||||
this.childLen= this.childElts.length;
|
||||
|
||||
while (i < this.childLen) {
|
||||
elt = this.childElts[i];
|
||||
if ("" == elt.className) {
|
||||
elt.className = "sf-dump-child";
|
||||
elt.innerHTML = '<a class=sf-dump-ref onclick="Sfjs.dump.toggle(this)">'+('sf-dump-0' == elt.parentNode.className ? aExpanded : aCompact)+elt.innerHTML+'</span>';
|
||||
}
|
||||
++i;
|
||||
}
|
||||
};
|
||||
Sfjs.dump.toggle = function(a) {
|
||||
var s = a.nextElementSibling;
|
||||
|
||||
if ('sf-dump-compact' == s.className) {
|
||||
a.innerHTML = '▼';
|
||||
s.className = 'sf-dump-expanded';
|
||||
} else {
|
||||
a.innerHTML = '▶';
|
||||
s.className = 'sf-dump-compact';
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
#sf-dump {
|
||||
display: block;
|
||||
background-color: #300a24;
|
||||
white-space: pre;
|
||||
line-height: 1.2em;
|
||||
color: #eee8d5;
|
||||
font-family: monospace, sans-serif;
|
||||
font: 12px monospace, sans-serif;
|
||||
padding: 5px;
|
||||
}
|
||||
.sf-dump span {
|
||||
#sf-dump span {
|
||||
display: inline;
|
||||
}
|
||||
#sf-dump .sf-dump-compact {
|
||||
display: none;
|
||||
}
|
||||
#sf-dump abbr {
|
||||
text-decoration: none;
|
||||
border: none;
|
||||
cursor: help;
|
||||
}
|
||||
#sf-dump a {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
#sf-dump a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
EOHTML;
|
||||
$line .= "a.$p-ref {{$this->styles['ref']}}";
|
||||
|
||||
foreach ($this->styles as $class => $style) {
|
||||
$line .= "span.$p-$class {{$style}}";
|
||||
$line .= "#sf-dump .sf-dump-$class {{$style}}";
|
||||
}
|
||||
|
||||
return preg_replace('/\s+/', ' ', $line).'</style>'.$this->dumpHeader;
|
||||
return $this->dumpHeader = preg_replace('/\s+/', ' ', $line).'</style>'.$this->dumpHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function enterHash(Cursor $cursor, $prefix, $hasChild)
|
||||
{
|
||||
if ($hasChild) {
|
||||
$prefix .= '<span name=sf-dump-child>';
|
||||
}
|
||||
|
||||
return parent::enterHash($cursor, $prefix, $hasChild);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function leaveHash(Cursor $cursor, $suffix, $hasChild, $cut)
|
||||
{
|
||||
if ($hasChild) {
|
||||
$suffix = '</span>'.$suffix;
|
||||
}
|
||||
|
||||
return parent::leaveHash($cursor, $suffix, $hasChild, $cut);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,6 +216,10 @@ EOHTML;
|
|||
$val = str_replace($c, "<span class=sf-dump-cchr>$r</span>", $val);
|
||||
}
|
||||
}
|
||||
} elseif ('note' === $style) {
|
||||
if (false !== $c = strrpos($val, '\\')) {
|
||||
$val = sprintf('<abbr title="%s" class=sf-dump-%s>%s</abbr>', $val, $style, substr($val, $c+1));
|
||||
}
|
||||
}
|
||||
|
||||
return "<span class=sf-dump-$style>$val</span>";
|
||||
|
@ -148,7 +230,6 @@ EOHTML;
|
|||
*/
|
||||
protected function dumpLine($depth)
|
||||
{
|
||||
|
||||
switch ($this->lastDepth - $depth) {
|
||||
case +1: $this->line = '</span>'.$this->line; break;
|
||||
case -1: $this->line = "<span class=sf-dump-$depth>$this->line"; break;
|
||||
|
@ -161,13 +242,11 @@ EOHTML;
|
|||
$this->line = $this->getDumpHeader().$this->line;
|
||||
}
|
||||
|
||||
if (false === $depth) {
|
||||
$this->lastDepth = -1;
|
||||
if (-1 === $depth) {
|
||||
$this->line .= $this->dumpSuffix;
|
||||
parent::dumpLine(0);
|
||||
} else {
|
||||
$this->lastDepth = $depth;
|
||||
}
|
||||
$this->lastDepth = $depth;
|
||||
|
||||
parent::dumpLine($depth);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
Symfony mechanim for exploring and dumping PHP variables
|
||||
========================================================
|
||||
Symfony mechanism for exploring and dumping PHP variables
|
||||
=========================================================
|
||||
|
||||
This component provides a mechanism that allows exploring then dumping
|
||||
any PHP variable.
|
||||
|
||||
It handles scalar, objects and resources properly, taking hard and soft
|
||||
It handles scalars, objects and resources properly, taking hard and soft
|
||||
references into account. More than being immune to inifinite recursion
|
||||
problems, it allows dumping where references link to each other.
|
||||
It explores recursive structures using a breadth-first algorithm.
|
||||
|
|
|
@ -26,6 +26,13 @@ class CliDumperTest extends \PHPUnit_Framework_TestCase
|
|||
$dumper = new CliDumper('php://output');
|
||||
$dumper->setColors(false);
|
||||
$cloner = new PhpCloner();
|
||||
$cloner->addCasters(array(
|
||||
':stream' => function ($res, $a) {
|
||||
unset($a['uri']);
|
||||
|
||||
return $a;
|
||||
}
|
||||
));
|
||||
$data = $cloner->cloneVar($var);
|
||||
|
||||
ob_start();
|
||||
|
@ -51,7 +58,7 @@ array:25 [
|
|||
"[]" => []
|
||||
"res" => resource:stream {
|
||||
wrapper_type: "plainfile"
|
||||
stream_type: "dir"
|
||||
stream_type: "STDIO"
|
||||
mode: "r"
|
||||
unread_bytes: 0
|
||||
seekable: true
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Component\VarDumper\Tests\Fixture;
|
||||
|
||||
if (!class_exists('Symfony\Component\VarDumper\Tests\Fixture\DumbFoo')) {
|
||||
class DumbFoo
|
||||
{
|
||||
public $foo = 'foo';
|
||||
}
|
||||
}
|
||||
|
||||
$foo = new DumbFoo();
|
||||
$foo->bar = 'bar';
|
||||
|
||||
$g = fopen(__FILE__, 'r');
|
||||
$h = fopen(__FILE__, 'r');
|
||||
fclose($h);
|
||||
|
||||
$var = array(
|
||||
'number' => 1, null,
|
||||
'const' => 1.1, true, false, NAN, INF, -INF, PHP_INT_MAX,
|
||||
'str' => "déjà", "\xE9",
|
||||
'[]' => array(),
|
||||
'res' => $g,
|
||||
$h,
|
||||
'obj' => $foo,
|
||||
'closure' => function ($a, \PDO &$b = null) {},
|
||||
'line' => __LINE__ - 1,
|
||||
'nobj' => array((object) array()),
|
||||
);
|
||||
|
||||
$r = array();
|
||||
$r[] =& $r;
|
||||
|
||||
$var['recurs'] =& $r;
|
||||
$var[] =& $var[0];
|
||||
$var['sobj'] = $var['obj'];
|
||||
$var['snobj'] =& $var['nobj'][0];
|
||||
$var['snobj2'] = $var['nobj'][0];
|
||||
$var['file'] = __FILE__;
|
||||
$var["bin-key-\xE9"] = "";
|
||||
|
||||
unset($g, $h, $r);
|
|
@ -25,7 +25,16 @@ class HtmlDumperTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
$dumper = new HtmlDumper('php://output');
|
||||
$dumper->setColors(false);
|
||||
$dumper->setDumpHeader('<foo></foo>');
|
||||
$dumper->setDumpBoundaries('<bar>', '</bar>');
|
||||
$cloner = new PhpCloner();
|
||||
$cloner->addCasters(array(
|
||||
':stream' => function ($res, $a) {
|
||||
unset($a['uri']);
|
||||
|
||||
return $a;
|
||||
}
|
||||
));
|
||||
$data = $cloner->cloneVar($var);
|
||||
|
||||
ob_start();
|
||||
|
@ -37,7 +46,7 @@ class HtmlDumperTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
$this->assertSame(
|
||||
<<<EOTXT
|
||||
<!DOCTYPE html><style> pre.sf-dump { background-color: #300a24; white-space: pre; line-height: 1.2em; color: #eee8d5; font-family: monospace, sans-serif; padding: 5px; } .sf-dump span { display: inline; }a.sf-dump-ref {color:#444444}span.sf-dump-num {font-weight:bold;color:#0087FF}span.sf-dump-const {font-weight:bold;color:#0087FF}span.sf-dump-str {font-weight:bold;color:#00D7FF}span.sf-dump-cchr {font-style: italic}span.sf-dump-note {color:#D7AF00}span.sf-dump-ref {color:#444444}span.sf-dump-public {color:#008700}span.sf-dump-protected {color:#D75F00}span.sf-dump-private {color:#D70000}span.sf-dump-meta {color:#005FFF}</style><pre class=sf-dump><span class=sf-dump-0><span class=sf-dump-note>array:25</span> [
|
||||
<foo></foo><bar><span class=sf-dump-0><span class=sf-dump-note>array:25</span> [<span name=sf-dump-child>
|
||||
<span class=sf-dump-1>"<span class=sf-dump-meta>number</span>" => <span class=sf-dump-num>1</span>
|
||||
<span class=sf-dump-meta>0</span> => <span class=sf-dump-const>null</span> <a class=sf-dump-ref name="sf-dump-ref1">#1</a>
|
||||
"<span class=sf-dump-meta>const</span>" => <span class=sf-dump-num>1.1</span>
|
||||
|
@ -50,9 +59,9 @@ class HtmlDumperTest extends \PHPUnit_Framework_TestCase
|
|||
"<span class=sf-dump-meta>str</span>" => "<span class=sf-dump-str>déjà</span>"
|
||||
<span class=sf-dump-meta>7</span> => b"<span class=sf-dump-str>é</span>"
|
||||
"<span class=sf-dump-meta>[]</span>" => []
|
||||
"<span class=sf-dump-meta>res</span>" => resource:<span class=sf-dump-note>stream</span> {
|
||||
"<span class=sf-dump-meta>res</span>" => resource:<span class=sf-dump-note>stream</span> {<span name=sf-dump-child>
|
||||
<span class=sf-dump-2><span class=sf-dump-meta>wrapper_type</span>: "<span class=sf-dump-str>plainfile</span>"
|
||||
<span class=sf-dump-meta>stream_type</span>: "<span class=sf-dump-str>dir</span>"
|
||||
<span class=sf-dump-meta>stream_type</span>: "<span class=sf-dump-str>STDIO</span>"
|
||||
<span class=sf-dump-meta>mode</span>: "<span class=sf-dump-str>r</span>"
|
||||
<span class=sf-dump-meta>unread_bytes</span>: <span class=sf-dump-num>0</span>
|
||||
<span class=sf-dump-meta>seekable</span>: <span class=sf-dump-const>true</span>
|
||||
|
@ -60,13 +69,13 @@ class HtmlDumperTest extends \PHPUnit_Framework_TestCase
|
|||
<span class=sf-dump-meta>blocked</span>: <span class=sf-dump-const>true</span>
|
||||
<span class=sf-dump-meta>eof</span>: <span class=sf-dump-const>false</span>
|
||||
<span class=sf-dump-meta>options</span>: []
|
||||
</span>}
|
||||
</span></span>}
|
||||
<span class=sf-dump-meta>8</span> => resource:<span class=sf-dump-note>Unknown</span> {}
|
||||
"<span class=sf-dump-meta>obj</span>" => <span class=sf-dump-note>Symfony\Component\VarDumper\Tests\Fixture\DumbFoo</span> { <a class=sf-dump-ref name="sf-dump-ref2">#2</a>
|
||||
"<span class=sf-dump-meta>obj</span>" => <span class=sf-dump-note><abbr title="Symfony\Component\VarDumper\Tests\Fixture\DumbFoo" class=sf-dump-note>DumbFoo</abbr></span> {<span name=sf-dump-child> <a class=sf-dump-ref name="sf-dump-ref2">#2</a>
|
||||
<span class=sf-dump-2><span class=sf-dump-public>foo</span>: "<span class=sf-dump-str>foo</span>"
|
||||
"<span class=sf-dump-public>bar</span>": "<span class=sf-dump-str>bar</span>"
|
||||
</span>}
|
||||
"<span class=sf-dump-meta>closure</span>" => <span class=sf-dump-note>Closure</span> {
|
||||
</span></span>}
|
||||
"<span class=sf-dump-meta>closure</span>" => <span class=sf-dump-note>Closure</span> {<span name=sf-dump-child>
|
||||
<span class=sf-dump-2><span class=sf-dump-meta>reflection</span>: """
|
||||
<span class=sf-dump-str>Closure [ <user> {$closureLabel} Symfony\Component\VarDumper\Tests\Fixture\{closure} ] {</span>
|
||||
<span class=sf-dump-str> @@ {$var['file']} {$var['line']} - {$var['line']}</span>
|
||||
|
@ -77,22 +86,22 @@ class HtmlDumperTest extends \PHPUnit_Framework_TestCase
|
|||
<span class=sf-dump-str> }</span>
|
||||
<span class=sf-dump-str>}</span>
|
||||
"""
|
||||
</span>}
|
||||
</span></span>}
|
||||
"<span class=sf-dump-meta>line</span>" => <span class=sf-dump-num>{$var['line']}</span>
|
||||
"<span class=sf-dump-meta>nobj</span>" => <span class=sf-dump-note>array:1</span> [
|
||||
"<span class=sf-dump-meta>nobj</span>" => <span class=sf-dump-note>array:1</span> [<span name=sf-dump-child>
|
||||
<span class=sf-dump-2><span class=sf-dump-meta>0</span> => {} <a class=sf-dump-ref name="sf-dump-ref3">#3</a>
|
||||
</span>]
|
||||
"<span class=sf-dump-meta>recurs</span>" => <span class=sf-dump-note>array:1</span> [ <a class=sf-dump-ref name="sf-dump-ref4">#4</a>
|
||||
</span></span>]
|
||||
"<span class=sf-dump-meta>recurs</span>" => <span class=sf-dump-note>array:1</span> [<span name=sf-dump-child> <a class=sf-dump-ref name="sf-dump-ref4">#4</a>
|
||||
<span class=sf-dump-2><span class=sf-dump-meta>0</span> => <a class=sf-dump-ref href="#sf-dump-ref4">&4</a> <span class=sf-dump-note>array:1</span> [<a class=sf-dump-ref href="#sf-dump-ref4">@4</a>]
|
||||
</span>]
|
||||
</span></span>]
|
||||
<span class=sf-dump-meta>9</span> => <a class=sf-dump-ref href="#sf-dump-ref1">&1</a> <span class=sf-dump-const>null</span>
|
||||
"<span class=sf-dump-meta>sobj</span>" => <span class=sf-dump-note>Symfony\Component\VarDumper\Tests\Fixture\DumbFoo</span> {<a class=sf-dump-ref href="#sf-dump-ref2">@2</a>}
|
||||
"<span class=sf-dump-meta>sobj</span>" => <span class=sf-dump-note><abbr title="Symfony\Component\VarDumper\Tests\Fixture\DumbFoo" class=sf-dump-note>DumbFoo</abbr></span> {<a class=sf-dump-ref href="#sf-dump-ref2">@2</a>}
|
||||
"<span class=sf-dump-meta>snobj</span>" => <a class=sf-dump-ref href="#sf-dump-ref3">&3</a> {<a class=sf-dump-ref href="#sf-dump-ref3">@3</a>}
|
||||
"<span class=sf-dump-meta>snobj2</span>" => {<a class=sf-dump-ref href="#sf-dump-ref3">@3</a>}
|
||||
"<span class=sf-dump-meta>file</span>" => "<span class=sf-dump-str>{$var['file']}</span>"
|
||||
b"<span class=sf-dump-meta>bin-key-é</span>" => ""
|
||||
</span>]
|
||||
</pre>
|
||||
</span></span>]
|
||||
</span></bar>
|
||||
|
||||
EOTXT
|
||||
,
|
||||
|
|
Reference in New Issue