@@ -1,3 +0,0 @@
|
||||
composer.lock
|
||||
phpunit.xml
|
||||
vendor/
|
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Caster;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
|
||||
/**
|
||||
* Represents a PHP constant and its value.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ConstStub extends Stub
|
||||
{
|
||||
public function __construct($name, $value)
|
||||
{
|
||||
$this->class = $name;
|
||||
$this->value = $value;
|
||||
}
|
||||
}
|
@@ -1,56 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Caster;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
|
||||
/**
|
||||
* Represents the main properties of a PHP variable, pre-casted by a caster.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class CutStub extends Stub
|
||||
{
|
||||
public function __construct($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
|
||||
switch (gettype($value)) {
|
||||
case 'object':
|
||||
$this->type = self::TYPE_OBJECT;
|
||||
$this->class = get_class($value);
|
||||
$this->cut = -1;
|
||||
break;
|
||||
|
||||
case 'array':
|
||||
$this->type = self::TYPE_ARRAY;
|
||||
$this->class = self::ARRAY_ASSOC;
|
||||
$this->cut = $this->value = count($value);
|
||||
break;
|
||||
|
||||
case 'resource':
|
||||
case 'unknown type':
|
||||
$this->type = self::TYPE_RESOURCE;
|
||||
$this->handle = (int) $value;
|
||||
$this->class = @get_resource_type($value);
|
||||
$this->cut = -1;
|
||||
break;
|
||||
|
||||
case 'string':
|
||||
$this->type = self::TYPE_STRING;
|
||||
$this->class = preg_match('//u', $value) ? self::STRING_UTF8 : self::STRING_BINARY;
|
||||
$this->cut = self::STRING_BINARY === $this->class ? strlen($value) : (function_exists('iconv_strlen') ? iconv_strlen($value, 'UTF-8') : -1);
|
||||
$this->value = '';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,300 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Caster;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
|
||||
/**
|
||||
* Casts DOM related classes to array representation.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class DOMCaster
|
||||
{
|
||||
private static $errorCodes = array(
|
||||
DOM_PHP_ERR => 'DOM_PHP_ERR',
|
||||
DOM_INDEX_SIZE_ERR => 'DOM_INDEX_SIZE_ERR',
|
||||
DOMSTRING_SIZE_ERR => 'DOMSTRING_SIZE_ERR',
|
||||
DOM_HIERARCHY_REQUEST_ERR => 'DOM_HIERARCHY_REQUEST_ERR',
|
||||
DOM_WRONG_DOCUMENT_ERR => 'DOM_WRONG_DOCUMENT_ERR',
|
||||
DOM_INVALID_CHARACTER_ERR => 'DOM_INVALID_CHARACTER_ERR',
|
||||
DOM_NO_DATA_ALLOWED_ERR => 'DOM_NO_DATA_ALLOWED_ERR',
|
||||
DOM_NO_MODIFICATION_ALLOWED_ERR => 'DOM_NO_MODIFICATION_ALLOWED_ERR',
|
||||
DOM_NOT_FOUND_ERR => 'DOM_NOT_FOUND_ERR',
|
||||
DOM_NOT_SUPPORTED_ERR => 'DOM_NOT_SUPPORTED_ERR',
|
||||
DOM_INUSE_ATTRIBUTE_ERR => 'DOM_INUSE_ATTRIBUTE_ERR',
|
||||
DOM_INVALID_STATE_ERR => 'DOM_INVALID_STATE_ERR',
|
||||
DOM_SYNTAX_ERR => 'DOM_SYNTAX_ERR',
|
||||
DOM_INVALID_MODIFICATION_ERR => 'DOM_INVALID_MODIFICATION_ERR',
|
||||
DOM_NAMESPACE_ERR => 'DOM_NAMESPACE_ERR',
|
||||
DOM_INVALID_ACCESS_ERR => 'DOM_INVALID_ACCESS_ERR',
|
||||
DOM_VALIDATION_ERR => 'DOM_VALIDATION_ERR',
|
||||
);
|
||||
|
||||
private static $nodeTypes = array(
|
||||
XML_ELEMENT_NODE => 'XML_ELEMENT_NODE',
|
||||
XML_ATTRIBUTE_NODE => 'XML_ATTRIBUTE_NODE',
|
||||
XML_TEXT_NODE => 'XML_TEXT_NODE',
|
||||
XML_CDATA_SECTION_NODE => 'XML_CDATA_SECTION_NODE',
|
||||
XML_ENTITY_REF_NODE => 'XML_ENTITY_REF_NODE',
|
||||
XML_ENTITY_NODE => 'XML_ENTITY_NODE',
|
||||
XML_PI_NODE => 'XML_PI_NODE',
|
||||
XML_COMMENT_NODE => 'XML_COMMENT_NODE',
|
||||
XML_DOCUMENT_NODE => 'XML_DOCUMENT_NODE',
|
||||
XML_DOCUMENT_TYPE_NODE => 'XML_DOCUMENT_TYPE_NODE',
|
||||
XML_DOCUMENT_FRAG_NODE => 'XML_DOCUMENT_FRAG_NODE',
|
||||
XML_NOTATION_NODE => 'XML_NOTATION_NODE',
|
||||
XML_HTML_DOCUMENT_NODE => 'XML_HTML_DOCUMENT_NODE',
|
||||
XML_DTD_NODE => 'XML_DTD_NODE',
|
||||
XML_ELEMENT_DECL_NODE => 'XML_ELEMENT_DECL_NODE',
|
||||
XML_ATTRIBUTE_DECL_NODE => 'XML_ATTRIBUTE_DECL_NODE',
|
||||
XML_ENTITY_DECL_NODE => 'XML_ENTITY_DECL_NODE',
|
||||
XML_NAMESPACE_DECL_NODE => 'XML_NAMESPACE_DECL_NODE',
|
||||
);
|
||||
|
||||
public static function castException(\DOMException $e, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
if (isset($a["\0*\0code"], self::$errorCodes[$a["\0*\0code"]])) {
|
||||
$a["\0*\0code"] = new ConstStub(self::$errorCodes[$a["\0*\0code"]], $a["\0*\0code"]);
|
||||
}
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castLength($dom, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
'length' => $dom->length,
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castImplementation($dom, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
"\0~\0Core" => '1.0',
|
||||
"\0~\0XML" => '2.0',
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castNode(\DOMNode $dom, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
'nodeName' => $dom->nodeName,
|
||||
'nodeValue' => new CutStub($dom->nodeValue),
|
||||
'nodeType' => new ConstStub(self::$nodeTypes[$dom->nodeType], $dom->nodeType),
|
||||
'parentNode' => new CutStub($dom->parentNode),
|
||||
'childNodes' => $dom->childNodes,
|
||||
'firstChild' => new CutStub($dom->firstChild),
|
||||
'lastChild' => new CutStub($dom->lastChild),
|
||||
'previousSibling' => new CutStub($dom->previousSibling),
|
||||
'nextSibling' => new CutStub($dom->nextSibling),
|
||||
'attributes' => $dom->attributes,
|
||||
'ownerDocument' => new CutStub($dom->ownerDocument),
|
||||
'namespaceURI' => $dom->namespaceURI,
|
||||
'prefix' => $dom->prefix,
|
||||
'localName' => $dom->localName,
|
||||
'baseURI' => $dom->baseURI,
|
||||
'textContent' => new CutStub($dom->textContent),
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castNameSpaceNode(\DOMNameSpaceNode $dom, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
'nodeName' => $dom->nodeName,
|
||||
'nodeValue' => new CutStub($dom->nodeValue),
|
||||
'nodeType' => new ConstStub(self::$nodeTypes[$dom->nodeType], $dom->nodeType),
|
||||
'prefix' => $dom->prefix,
|
||||
'localName' => $dom->localName,
|
||||
'namespaceURI' => $dom->namespaceURI,
|
||||
'ownerDocument' => new CutStub($dom->ownerDocument),
|
||||
'parentNode' => new CutStub($dom->parentNode),
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castDocument(\DOMDocument $dom, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$formatOutput = $dom->formatOutput;
|
||||
$dom->formatOutput = true;
|
||||
|
||||
$a += array(
|
||||
'doctype' => $dom->doctype,
|
||||
'implementation' => $dom->implementation,
|
||||
'documentElement' => new CutStub($dom->documentElement),
|
||||
'actualEncoding' => $dom->actualEncoding,
|
||||
'encoding' => $dom->encoding,
|
||||
'xmlEncoding' => $dom->xmlEncoding,
|
||||
'standalone' => $dom->standalone,
|
||||
'xmlStandalone' => $dom->xmlStandalone,
|
||||
'version' => $dom->version,
|
||||
'xmlVersion' => $dom->xmlVersion,
|
||||
'strictErrorChecking' => $dom->strictErrorChecking,
|
||||
'documentURI' => $dom->documentURI,
|
||||
'config' => $dom->config,
|
||||
'formatOutput' => $formatOutput,
|
||||
'validateOnParse' => $dom->validateOnParse,
|
||||
'resolveExternals' => $dom->resolveExternals,
|
||||
'preserveWhiteSpace' => $dom->preserveWhiteSpace,
|
||||
'recover' => $dom->recover,
|
||||
'substituteEntities' => $dom->substituteEntities,
|
||||
"\0~\0xml" => $dom->saveXML(),
|
||||
);
|
||||
|
||||
$dom->formatOutput = $formatOutput;
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castCharacterData(\DOMCharacterData $dom, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
'data' => $dom->data,
|
||||
'length' => $dom->length,
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castAttr(\DOMAttr $dom, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
'name' => $dom->name,
|
||||
'specified' => $dom->specified,
|
||||
'value' => $dom->value,
|
||||
'ownerElement' => $dom->ownerElement,
|
||||
'schemaTypeInfo' => $dom->schemaTypeInfo,
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castElement(\DOMElement $dom, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
'tagName' => $dom->tagName,
|
||||
'schemaTypeInfo' => $dom->schemaTypeInfo,
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castText(\DOMText $dom, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
'wholeText' => $dom->wholeText,
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castTypeinfo(\DOMTypeinfo $dom, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
'typeName' => $dom->typeName,
|
||||
'typeNamespace' => $dom->typeNamespace,
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castDomError(\DOMDomError $dom, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
'severity' => $dom->severity,
|
||||
'message' => $dom->message,
|
||||
'type' => $dom->type,
|
||||
'relatedException' => $dom->relatedException,
|
||||
'related_data' => $dom->related_data,
|
||||
'location' => $dom->location,
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castLocator(\DOMLocator $dom, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
'lineNumber' => $dom->lineNumber,
|
||||
'columnNumber' => $dom->columnNumber,
|
||||
'offset' => $dom->offset,
|
||||
'relatedNode' => $dom->relatedNode,
|
||||
'uri' => $dom->uri,
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castDocumentType(\DOMDocumentType $dom, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
'name' => $dom->name,
|
||||
'entities' => $dom->entities,
|
||||
'notations' => $dom->notations,
|
||||
'publicId' => $dom->publicId,
|
||||
'systemId' => $dom->systemId,
|
||||
'internalSubset' => $dom->internalSubset,
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castNotation(\DOMNotation $dom, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
'publicId' => $dom->publicId,
|
||||
'systemId' => $dom->systemId,
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castEntity(\DOMEntity $dom, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
'publicId' => $dom->publicId,
|
||||
'systemId' => $dom->systemId,
|
||||
'notationName' => $dom->notationName,
|
||||
'actualEncoding' => $dom->actualEncoding,
|
||||
'encoding' => $dom->encoding,
|
||||
'version' => $dom->version,
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castProcessingInstruction(\DOMProcessingInstruction $dom, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
'target' => $dom->target,
|
||||
'data' => $dom->data,
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castXPath(\DOMXPath $dom, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
'document' => $dom->document,
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
}
|
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Caster;
|
||||
|
||||
use Doctrine\Common\Proxy\Proxy as CommonProxy;
|
||||
use Doctrine\ORM\Proxy\Proxy as OrmProxy;
|
||||
use Doctrine\ORM\PersistentCollection;
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
|
||||
/**
|
||||
* Casts Doctrine related classes to array representation.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class DoctrineCaster
|
||||
{
|
||||
public static function castCommonProxy(CommonProxy $proxy, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
unset(
|
||||
$a['__cloner__'],
|
||||
$a['__initializer__']
|
||||
);
|
||||
$stub->cut += 2;
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castOrmProxy(OrmProxy $proxy, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$prefix = "\0Doctrine\\ORM\\Proxy\\Proxy\0";
|
||||
unset(
|
||||
$a[$prefix.'_entityPersister'],
|
||||
$a[$prefix.'_identifier']
|
||||
);
|
||||
$stub->cut += 2;
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castPersistentCollection(PersistentCollection $coll, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$prefix = "\0Doctrine\\ORM\\PersistentCollection\0";
|
||||
|
||||
$a[$prefix.'snapshot'] = new CutStub($a[$prefix.'snapshot']);
|
||||
$a[$prefix.'association'] = new CutStub($a[$prefix.'association']);
|
||||
$a[$prefix.'typeClass'] = new CutStub($a[$prefix.'typeClass']);
|
||||
|
||||
return $a;
|
||||
}
|
||||
}
|
@@ -1,123 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Caster;
|
||||
|
||||
use Symfony\Component\VarDumper\Exception\ThrowingCasterException;
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
|
||||
/**
|
||||
* Casts common Exception classes to array representation.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ExceptionCaster
|
||||
{
|
||||
public static $traceArgs = true;
|
||||
public static $errorTypes = array(
|
||||
E_DEPRECATED => 'E_DEPRECATED',
|
||||
E_USER_DEPRECATED => 'E_USER_DEPRECATED',
|
||||
E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
|
||||
E_ERROR => 'E_ERROR',
|
||||
E_WARNING => 'E_WARNING',
|
||||
E_PARSE => 'E_PARSE',
|
||||
E_NOTICE => 'E_NOTICE',
|
||||
E_CORE_ERROR => 'E_CORE_ERROR',
|
||||
E_CORE_WARNING => 'E_CORE_WARNING',
|
||||
E_COMPILE_ERROR => 'E_COMPILE_ERROR',
|
||||
E_COMPILE_WARNING => 'E_COMPILE_WARNING',
|
||||
E_USER_ERROR => 'E_USER_ERROR',
|
||||
E_USER_WARNING => 'E_USER_WARNING',
|
||||
E_USER_NOTICE => 'E_USER_NOTICE',
|
||||
E_STRICT => 'E_STRICT',
|
||||
);
|
||||
|
||||
public static function castException(\Exception $e, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$trace = $a["\0Exception\0trace"];
|
||||
unset($a["\0Exception\0trace"]); // Ensures the trace is always last
|
||||
|
||||
static::filterTrace($trace, static::$traceArgs);
|
||||
|
||||
if (null !== $trace) {
|
||||
$a["\0Exception\0trace"] = $trace;
|
||||
}
|
||||
if (empty($a["\0Exception\0previous"])) {
|
||||
unset($a["\0Exception\0previous"]);
|
||||
}
|
||||
unset($a["\0Exception\0string"], $a["\0+\0xdebug_message"], $a["\0+\0__destructorException"]);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castErrorException(\ErrorException $e, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
if (isset($a[$s = "\0*\0severity"], self::$errorTypes[$a[$s]])) {
|
||||
$a[$s] = new ConstStub(self::$errorTypes[$a[$s]], $a[$s]);
|
||||
}
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castThrowingCasterException(ThrowingCasterException $e, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$b = (array) $a["\0Exception\0previous"];
|
||||
|
||||
if (isset($b["\0*\0message"])) {
|
||||
$a["\0~\0message"] = $b["\0*\0message"];
|
||||
}
|
||||
|
||||
if (isset($a["\0Exception\0trace"])) {
|
||||
$b["\0Exception\0trace"][0] += array(
|
||||
'file' => $b["\0*\0file"],
|
||||
'line' => $b["\0*\0line"],
|
||||
);
|
||||
array_splice($b["\0Exception\0trace"], -1 - count($a["\0Exception\0trace"]));
|
||||
static::filterTrace($b["\0Exception\0trace"], false);
|
||||
$a["\0~\0trace"] = $b["\0Exception\0trace"];
|
||||
}
|
||||
|
||||
unset($a["\0Exception\0trace"], $a["\0Exception\0previous"], $a["\0*\0code"], $a["\0*\0file"], $a["\0*\0line"]);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function filterTrace(&$trace, $dumpArgs, $offset = 0)
|
||||
{
|
||||
if (0 > $offset || empty($trace[$offset])) {
|
||||
return $trace = null;
|
||||
}
|
||||
|
||||
$t = $trace[$offset];
|
||||
|
||||
if (empty($t['class']) && isset($t['function'])) {
|
||||
if ('user_error' === $t['function'] || 'trigger_error' === $t['function']) {
|
||||
++$offset;
|
||||
}
|
||||
}
|
||||
|
||||
if ($offset) {
|
||||
array_splice($trace, 0, $offset);
|
||||
}
|
||||
|
||||
foreach ($trace as &$t) {
|
||||
$t = array(
|
||||
'call' => (isset($t['class']) ? $t['class'].$t['type'] : '').$t['function'].'()',
|
||||
'file' => isset($t['line']) ? "{$t['file']}:{$t['line']}" : '',
|
||||
'args' => &$t['args'],
|
||||
);
|
||||
|
||||
if (!isset($t['args']) || !$dumpArgs) {
|
||||
unset($t['args']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,114 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Caster;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
|
||||
/**
|
||||
* Casts PDO related classes to array representation.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class PdoCaster
|
||||
{
|
||||
private static $pdoAttributes = array(
|
||||
'CASE' => array(
|
||||
\PDO::CASE_LOWER => 'LOWER',
|
||||
\PDO::CASE_NATURAL => 'NATURAL',
|
||||
\PDO::CASE_UPPER => 'UPPER',
|
||||
),
|
||||
'ERRMODE' => array(
|
||||
\PDO::ERRMODE_SILENT => 'SILENT',
|
||||
\PDO::ERRMODE_WARNING => 'WARNING',
|
||||
\PDO::ERRMODE_EXCEPTION => 'EXCEPTION',
|
||||
),
|
||||
'TIMEOUT',
|
||||
'PREFETCH',
|
||||
'AUTOCOMMIT',
|
||||
'PERSISTENT',
|
||||
'DRIVER_NAME',
|
||||
'SERVER_INFO',
|
||||
'ORACLE_NULLS' => array(
|
||||
\PDO::NULL_NATURAL => 'NATURAL',
|
||||
\PDO::NULL_EMPTY_STRING => 'EMPTY_STRING',
|
||||
\PDO::NULL_TO_STRING => 'TO_STRING',
|
||||
),
|
||||
'CLIENT_VERSION',
|
||||
'SERVER_VERSION',
|
||||
'STATEMENT_CLASS',
|
||||
'EMULATE_PREPARES',
|
||||
'CONNECTION_STATUS',
|
||||
'STRINGIFY_FETCHES',
|
||||
'DEFAULT_FETCH_MODE' => array(
|
||||
\PDO::FETCH_ASSOC => 'ASSOC',
|
||||
\PDO::FETCH_BOTH => 'BOTH',
|
||||
\PDO::FETCH_LAZY => 'LAZY',
|
||||
\PDO::FETCH_NUM => 'NUM',
|
||||
\PDO::FETCH_OBJ => 'OBJ',
|
||||
),
|
||||
);
|
||||
|
||||
public static function castPdo(\PDO $c, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$attr = array();
|
||||
$errmode = $c->getAttribute(\PDO::ATTR_ERRMODE);
|
||||
$c->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
foreach (self::$pdoAttributes as $k => $v) {
|
||||
if (!isset($k[0])) {
|
||||
$k = $v;
|
||||
$v = array();
|
||||
}
|
||||
|
||||
try {
|
||||
$attr[$k] = 'ERRMODE' === $k ? $errmode : $c->getAttribute(constant('PDO::ATTR_'.$k));
|
||||
if ($v && isset($v[$attr[$k]])) {
|
||||
$attr[$k] = new ConstStub($v[$attr[$k]], $attr[$k]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
$m = "\0~\0";
|
||||
$a += array(
|
||||
$m.'inTransaction' => method_exists($c, 'inTransaction'),
|
||||
$m.'errorInfo' => $c->errorInfo(),
|
||||
$m.'attributes' => $attr,
|
||||
);
|
||||
|
||||
if ($a[$m.'inTransaction']) {
|
||||
$a[$m.'inTransaction'] = $c->inTransaction();
|
||||
} else {
|
||||
unset($a[$m.'inTransaction']);
|
||||
}
|
||||
|
||||
if (!isset($a[$m.'errorInfo'][1], $a[$m.'errorInfo'][2])) {
|
||||
unset($a[$m.'errorInfo']);
|
||||
}
|
||||
|
||||
$c->setAttribute(\PDO::ATTR_ERRMODE, $errmode);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castPdoStatement(\PDOStatement $c, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$m = "\0~\0";
|
||||
$a[$m.'errorInfo'] = $c->errorInfo();
|
||||
|
||||
if (!isset($a[$m.'errorInfo'][1], $a[$m.'errorInfo'][2])) {
|
||||
unset($a[$m.'errorInfo']);
|
||||
}
|
||||
|
||||
return $a;
|
||||
}
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Caster;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
|
||||
/**
|
||||
* Casts Reflector related classes to array representation.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ReflectionCaster
|
||||
{
|
||||
public static function castReflector(\Reflector $c, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a["\0~\0reflection"] = $c->__toString();
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
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'], $a["\0+\0this"], $a["\0+\0parameter"]);
|
||||
|
||||
return $a;
|
||||
}
|
||||
}
|
@@ -1,67 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Caster;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
|
||||
/**
|
||||
* Casts common resource types to array representation.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ResourceCaster
|
||||
{
|
||||
public static function castCurl($h, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
return curl_getinfo($h);
|
||||
}
|
||||
|
||||
public static function castDba($dba, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$list = dba_list();
|
||||
$a['file'] = $list[(int) $dba];
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castProcess($process, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
return proc_get_status($process);
|
||||
}
|
||||
|
||||
public static function castStream($stream, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
return stream_get_meta_data($stream) + static::castStreamContext($stream, $a, $stub, $isNested);
|
||||
}
|
||||
|
||||
public static function castStreamContext($stream, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
return stream_context_get_params($stream);
|
||||
}
|
||||
|
||||
public static function castGd($gd, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a['size'] = imagesx($gd).'x'.imagesy($gd);
|
||||
$a['trueColor'] = imageistruecolor($gd);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castMysqlLink($h, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a['host'] = mysql_get_host_info($h);
|
||||
$a['protocol'] = mysql_get_proto_info($h);
|
||||
$a['server'] = mysql_get_server_info($h);
|
||||
|
||||
return $a;
|
||||
}
|
||||
}
|
@@ -1,110 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Caster;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
|
||||
/**
|
||||
* Casts SPL related classes to array representation.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class SplCaster
|
||||
{
|
||||
public static function castArrayObject(\ArrayObject $c, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$class = $stub->class;
|
||||
$flags = $c->getFlags();
|
||||
|
||||
$b = array(
|
||||
"\0~\0flag::STD_PROP_LIST" => (bool) ($flags & \ArrayObject::STD_PROP_LIST),
|
||||
"\0~\0flag::ARRAY_AS_PROPS" => (bool) ($flags & \ArrayObject::ARRAY_AS_PROPS),
|
||||
"\0~\0iteratorClass" => $c->getIteratorClass(),
|
||||
"\0~\0storage" => $c->getArrayCopy(),
|
||||
);
|
||||
|
||||
if ($class === 'ArrayObject') {
|
||||
$a = $b;
|
||||
} else {
|
||||
if (!($flags & \ArrayObject::STD_PROP_LIST)) {
|
||||
$c->setFlags(\ArrayObject::STD_PROP_LIST);
|
||||
|
||||
if ($a = (array) $c) {
|
||||
$class = new \ReflectionClass($class);
|
||||
foreach ($a as $k => $p) {
|
||||
if (!isset($k[0]) || ("\0" !== $k[0] && !$class->hasProperty($k))) {
|
||||
unset($a[$k]);
|
||||
$a["\0+\0".$k] = $p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$c->setFlags($flags);
|
||||
}
|
||||
|
||||
$a += $b;
|
||||
}
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castHeap(\Iterator $c, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
"\0~\0heap" => iterator_to_array(clone $c),
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castDoublyLinkedList(\SplDoublyLinkedList $c, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$mode = $c->getIteratorMode();
|
||||
$c->setIteratorMode(\SplDoublyLinkedList::IT_MODE_KEEP | $mode & ~\SplDoublyLinkedList::IT_MODE_DELETE);
|
||||
|
||||
$a += array(
|
||||
"\0~\0mode" => new ConstStub((($mode & \SplDoublyLinkedList::IT_MODE_LIFO) ? 'IT_MODE_LIFO' : 'IT_MODE_FIFO').' | '.(($mode & \SplDoublyLinkedList::IT_MODE_KEEP) ? 'IT_MODE_KEEP' : 'IT_MODE_DELETE'), $mode),
|
||||
"\0~\0dllist" => iterator_to_array($c),
|
||||
);
|
||||
$c->setIteratorMode($mode);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castFixedArray(\SplFixedArray $c, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$a += array(
|
||||
"\0~\0storage" => $c->toArray(),
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castObjectStorage(\SplObjectStorage $c, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$storage = array();
|
||||
unset($a["\0+\0\0gcdata"]); // Don't hit https://bugs.php.net/65967
|
||||
|
||||
foreach ($c as $obj) {
|
||||
$storage[spl_object_hash($obj)] = array(
|
||||
'object' => $obj,
|
||||
'info' => $c->getInfo(),
|
||||
);
|
||||
}
|
||||
|
||||
$a += array(
|
||||
"\0~\0storage" => $storage,
|
||||
);
|
||||
|
||||
return $a;
|
||||
}
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Caster;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
|
||||
/**
|
||||
* Casts a caster's Stub.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class StubCaster
|
||||
{
|
||||
public static function castStub(Stub $c, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
if ($isNested) {
|
||||
$stub->type = $c->type;
|
||||
$stub->class = $c->class;
|
||||
$stub->value = $c->value;
|
||||
$stub->handle = $c->handle;
|
||||
$stub->cut = $c->cut;
|
||||
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
public static function cutInternals($obj, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
if ($isNested) {
|
||||
$stub->cut += count($a);
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
return $a;
|
||||
}
|
||||
}
|
@@ -1,295 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Cloner;
|
||||
|
||||
use Symfony\Component\VarDumper\Exception\ThrowingCasterException;
|
||||
|
||||
/**
|
||||
* AbstractCloner implements a generic caster mechanism for objects and resources.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
abstract class AbstractCloner implements ClonerInterface
|
||||
{
|
||||
public static $defaultCasters = array(
|
||||
'Symfony\Component\VarDumper\Caster\CutStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castStub',
|
||||
'Symfony\Component\VarDumper\Caster\ConstStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castStub',
|
||||
|
||||
'Closure' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClosure',
|
||||
'Reflector' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castReflector',
|
||||
|
||||
'Doctrine\Common\Persistence\ObjectManager' => 'Symfony\Component\VarDumper\Caster\StubCaster::cutInternals',
|
||||
'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',
|
||||
|
||||
'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',
|
||||
|
||||
'ErrorException' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castErrorException',
|
||||
'Exception' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castException',
|
||||
'Symfony\Component\DependencyInjection\ContainerInterface' => 'Symfony\Component\VarDumper\Caster\StubCaster::cutInternals',
|
||||
'Symfony\Component\VarDumper\Exception\ThrowingCasterException' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castThrowingCasterException',
|
||||
|
||||
'PDO' => 'Symfony\Component\VarDumper\Caster\PdoCaster::castPdo',
|
||||
'PDOStatement' => 'Symfony\Component\VarDumper\Caster\PdoCaster::castPdoStatement',
|
||||
|
||||
'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',
|
||||
|
||||
':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 = 2500;
|
||||
protected $maxString = -1;
|
||||
protected $useExt;
|
||||
|
||||
private $casters = array();
|
||||
private $prevErrorHandler;
|
||||
private $classInfo = array();
|
||||
|
||||
/**
|
||||
* @param callable[]|null $casters A map of casters.
|
||||
*
|
||||
* @see addCasters
|
||||
*/
|
||||
public function __construct(array $casters = null)
|
||||
{
|
||||
if (null === $casters) {
|
||||
$casters = static::$defaultCasters;
|
||||
}
|
||||
$this->addCasters($casters);
|
||||
$this->useExt = extension_loaded('symfony_debug');
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds casters for resources and objects.
|
||||
*
|
||||
* Maps resources or objects types to a callback.
|
||||
* Types are in the key, with a callable caster for value.
|
||||
* Resource types are to be prefixed with a `:`,
|
||||
* see e.g. static::$defaultCasters.
|
||||
*
|
||||
* @param callable[] $casters A map of casters.
|
||||
*/
|
||||
public function addCasters(array $casters)
|
||||
{
|
||||
foreach ($casters as $type => $callback) {
|
||||
$this->casters[strtolower($type)][] = $callback;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum number of items to clone past the first level in nested structures.
|
||||
*
|
||||
* @param int $maxItems
|
||||
*/
|
||||
public function setMaxItems($maxItems)
|
||||
{
|
||||
$this->maxItems = (int) $maxItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum cloned length for strings.
|
||||
*
|
||||
* @param int $maxString
|
||||
*/
|
||||
public function setMaxString($maxString)
|
||||
{
|
||||
$this->maxString = (int) $maxString;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function cloneVar($var)
|
||||
{
|
||||
$this->prevErrorHandler = set_error_handler(array($this, 'handleError'));
|
||||
try {
|
||||
if (!function_exists('iconv')) {
|
||||
$this->maxString = -1;
|
||||
}
|
||||
$data = $this->doClone($var);
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
restore_error_handler();
|
||||
$this->prevErrorHandler = null;
|
||||
|
||||
if (isset($e)) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return new Data($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Effectively clones the PHP variable.
|
||||
*
|
||||
* @param mixed $var Any PHP variable.
|
||||
*
|
||||
* @return array The cloned variable represented in an array.
|
||||
*/
|
||||
abstract protected function doClone($var);
|
||||
|
||||
/**
|
||||
* Casts an object to an array representation.
|
||||
*
|
||||
* @param Stub $stub The Stub for the casted object.
|
||||
* @param bool $isNested True if the object is nested in the dumped structure.
|
||||
*
|
||||
* @return array The object casted as array.
|
||||
*/
|
||||
protected function castObject(Stub $stub, $isNested)
|
||||
{
|
||||
$obj = $stub->value;
|
||||
$class = $stub->class;
|
||||
|
||||
if (isset($this->classInfo[$class])) {
|
||||
$classInfo = $this->classInfo[$class];
|
||||
$stub->class = $classInfo[0];
|
||||
} else {
|
||||
$classInfo = array(
|
||||
$class,
|
||||
method_exists($class, '__debugInfo'),
|
||||
new \ReflectionClass($class),
|
||||
array_reverse(array($class => $class) + class_parents($class) + class_implements($class)),
|
||||
);
|
||||
|
||||
$this->classInfo[$class] = $classInfo;
|
||||
}
|
||||
|
||||
if ($classInfo[1]) {
|
||||
$a = $this->callCaster(function ($obj) {return $obj->__debugInfo();}, $obj, array(), null, $isNested);
|
||||
} else {
|
||||
$a = (array) $obj;
|
||||
}
|
||||
|
||||
if ($a) {
|
||||
$p = array_keys($a);
|
||||
foreach ($p as $i => $k) {
|
||||
if (!isset($k[0]) || ("\0" !== $k[0] && !$classInfo[2]->hasProperty($k))) {
|
||||
$p[$i] = "\0+\0".$k;
|
||||
}
|
||||
}
|
||||
$a = array_combine($p, $a);
|
||||
}
|
||||
|
||||
foreach ($classInfo[3] as $p) {
|
||||
if (!empty($this->casters[$p = strtolower($p)])) {
|
||||
foreach ($this->casters[$p] as $p) {
|
||||
$a = $this->callCaster($p, $obj, $a, $stub, $isNested);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts a resource to an array representation.
|
||||
*
|
||||
* @param Stub $stub The Stub for the casted resource.
|
||||
* @param bool $isNested True if the object is nested in the dumped structure.
|
||||
*
|
||||
* @return array The resource casted as array.
|
||||
*/
|
||||
protected function castResource(Stub $stub, $isNested)
|
||||
{
|
||||
$a = array();
|
||||
$res = $stub->value;
|
||||
$type = $stub->class;
|
||||
|
||||
if (!empty($this->casters[':'.$type])) {
|
||||
foreach ($this->casters[':'.$type] as $c) {
|
||||
$a = $this->callCaster($c, $res, $a, $stub, $isNested);
|
||||
}
|
||||
}
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a custom caster.
|
||||
*
|
||||
* @param callable $callback The caster.
|
||||
* @param object|resource $obj The object/resource being casted.
|
||||
* @param array $a The result of the previous cast for chained casters.
|
||||
* @param Stub $stub The Stub for the casted object/resource.
|
||||
* @param bool $isNested True if $obj is nested in the dumped structure.
|
||||
*
|
||||
* @return array The casted object/resource.
|
||||
*/
|
||||
private function callCaster($callback, $obj, $a, $stub, $isNested)
|
||||
{
|
||||
try {
|
||||
$cast = call_user_func($callback, $obj, $a, $stub, $isNested);
|
||||
|
||||
if (is_array($cast)) {
|
||||
$a = $cast;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$a[(Stub::TYPE_OBJECT === $stub->type ? "\0~\0" : '').'⚠'] = new ThrowingCasterException($callback, $e);
|
||||
}
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Special handling for errors: cloning must be fail-safe.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function handleError($type, $msg, $file, $line, $context)
|
||||
{
|
||||
if (E_RECOVERABLE_ERROR === $type || E_USER_ERROR === $type) {
|
||||
// Cloner never dies
|
||||
throw new \ErrorException($msg, 0, $type, $file, $line);
|
||||
}
|
||||
|
||||
if ($this->prevErrorHandler) {
|
||||
return call_user_func($this->prevErrorHandler, $type, $msg, $file, $line, $context);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* 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 <p@tchwork.com>
|
||||
*/
|
||||
interface ClonerInterface
|
||||
{
|
||||
/**
|
||||
* Clones a PHP variable.
|
||||
*
|
||||
* @param mixed $var Any PHP variable.
|
||||
*
|
||||
* @return Data The cloned variable represented by a Data object.
|
||||
*/
|
||||
public function cloneVar($var);
|
||||
}
|
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Cloner;
|
||||
|
||||
/**
|
||||
* Represents the current state of a dumper while dumping.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class Cursor
|
||||
{
|
||||
const HASH_INDEXED = Stub::ARRAY_INDEXED;
|
||||
const HASH_ASSOC = Stub::ARRAY_ASSOC;
|
||||
const HASH_OBJECT = Stub::TYPE_OBJECT;
|
||||
const HASH_RESOURCE = Stub::TYPE_RESOURCE;
|
||||
|
||||
public $depth = 0;
|
||||
public $refIndex = 0;
|
||||
public $softRefTo = 0;
|
||||
public $softRefCount = 0;
|
||||
public $softRefHandle = 0;
|
||||
public $hardRefTo = 0;
|
||||
public $hardRefCount = 0;
|
||||
public $hardRefHandle = 0;
|
||||
public $hashType;
|
||||
public $hashKey;
|
||||
public $hashKeyIsBinary;
|
||||
public $hashIndex = 0;
|
||||
public $hashLength = 0;
|
||||
public $hashCut = 0;
|
||||
public $stop = false;
|
||||
}
|
@@ -1,194 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* 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 <p@tchwork.com>
|
||||
*/
|
||||
class Data
|
||||
{
|
||||
private $data;
|
||||
private $maxDepth = 20;
|
||||
private $maxItemsPerDepth = -1;
|
||||
private $useRefHandles = -1;
|
||||
|
||||
/**
|
||||
* @param array $data A array as returned by ClonerInterface::cloneVar().
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array The raw data structure.
|
||||
*/
|
||||
public function getRawData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a depth limited clone of $this.
|
||||
*
|
||||
* @param int $maxDepth The max dumped depth level.
|
||||
* @param int $maxItemsPerDepth The max number of items dumped per depth level.
|
||||
* @param bool $useRefHandles False to hide ref. handles.
|
||||
*
|
||||
* @return self A depth limited clone of $this.
|
||||
*/
|
||||
public function getLimitedClone($maxDepth, $maxItemsPerDepth, $useRefHandles = true)
|
||||
{
|
||||
$data = clone $this;
|
||||
$data->maxDepth = (int) $maxDepth;
|
||||
$data->maxItemsPerDepth = (int) $maxItemsPerDepth;
|
||||
$data->useRefHandles = $useRefHandles ? -1 : 0;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps data with a DumperInterface dumper.
|
||||
*/
|
||||
public function dump(DumperInterface $dumper)
|
||||
{
|
||||
$refs = array(0);
|
||||
$this->dumpItem($dumper, new Cursor(), $refs, $this->data[0][0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Depth-first dumping of items.
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
$cursor->refIndex = 0;
|
||||
$cursor->softRefTo = $cursor->softRefHandle = $cursor->softRefCount = 0;
|
||||
$cursor->hardRefTo = $cursor->hardRefHandle = $cursor->hardRefCount = 0;
|
||||
$firstSeen = true;
|
||||
|
||||
if (!$item instanceof Stub) {
|
||||
$type = gettype($item);
|
||||
} elseif (Stub::TYPE_REF === $item->type) {
|
||||
if ($item->handle) {
|
||||
if (!isset($refs[$r = $item->handle - (PHP_INT_MAX >> 1)])) {
|
||||
$cursor->refIndex = $refs[$r] = $cursor->refIndex ?: ++$refs[0];
|
||||
} else {
|
||||
$firstSeen = false;
|
||||
}
|
||||
$cursor->hardRefTo = $refs[$r];
|
||||
$cursor->hardRefHandle = $this->useRefHandles & $item->handle;
|
||||
$cursor->hardRefCount = $item->refCount;
|
||||
}
|
||||
$type = $item->class ?: gettype($item->value);
|
||||
$item = $item->value;
|
||||
}
|
||||
if ($item instanceof Stub) {
|
||||
if ($item->refCount) {
|
||||
if (!isset($refs[$r = $item->handle])) {
|
||||
$cursor->refIndex = $refs[$r] = $cursor->refIndex ?: ++$refs[0];
|
||||
} else {
|
||||
$firstSeen = false;
|
||||
}
|
||||
$cursor->softRefTo = $refs[$r];
|
||||
}
|
||||
$cursor->softRefHandle = $this->useRefHandles & $item->handle;
|
||||
$cursor->softRefCount = $item->refCount;
|
||||
$cut = $item->cut;
|
||||
|
||||
if ($item->position && $firstSeen) {
|
||||
$children = $this->data[$item->position];
|
||||
|
||||
if ($cursor->stop) {
|
||||
if ($cut >= 0) {
|
||||
$cut += count($children);
|
||||
}
|
||||
$children = array();
|
||||
}
|
||||
} else {
|
||||
$children = array();
|
||||
}
|
||||
switch ($item->type) {
|
||||
case Stub::TYPE_STRING:
|
||||
$dumper->dumpString($cursor, $item->value, Stub::STRING_BINARY === $item->class, $cut);
|
||||
break;
|
||||
|
||||
case Stub::TYPE_ARRAY:
|
||||
$dumper->enterHash($cursor, $item->class, $item->value, (bool) $children);
|
||||
$cut = $this->dumpChildren($dumper, $cursor, $refs, $children, $cut, $item->class);
|
||||
$dumper->leaveHash($cursor, $item->class, $item->value, (bool) $children, $cut);
|
||||
break;
|
||||
|
||||
case Stub::TYPE_OBJECT:
|
||||
case Stub::TYPE_RESOURCE:
|
||||
$dumper->enterHash($cursor, $item->type, $item->class, (bool) $children);
|
||||
$cut = $this->dumpChildren($dumper, $cursor, $refs, $children, $cut, $item->type);
|
||||
$dumper->leaveHash($cursor, $item->type, $item->class, (bool) $children, $cut);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \RuntimeException(sprintf('Unexpected Stub type: %s', $item->type));
|
||||
}
|
||||
} elseif ('array' === $type) {
|
||||
$dumper->enterHash($cursor, Cursor::HASH_INDEXED, 0, false);
|
||||
$dumper->leaveHash($cursor, Cursor::HASH_INDEXED, 0, false, 0);
|
||||
} elseif ('string' === $type) {
|
||||
$dumper->dumpString($cursor, $item, false, 0);
|
||||
} else {
|
||||
$dumper->dumpScalar($cursor, $type, $item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps children of hash structures.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
private function dumpChildren($dumper, $parentCursor, &$refs, $children, $hashCut, $hashType)
|
||||
{
|
||||
if ($children) {
|
||||
if ($parentCursor->depth !== $this->maxDepth && $this->maxItemsPerDepth) {
|
||||
$cursor = clone $parentCursor;
|
||||
++$cursor->depth;
|
||||
$cursor->hashType = $hashType;
|
||||
$cursor->hashIndex = 0;
|
||||
$cursor->hashLength = count($children);
|
||||
$cursor->hashCut = $hashCut;
|
||||
foreach ($children as $key => $child) {
|
||||
$cursor->hashKeyIsBinary = isset($key[0]) && !preg_match('//u', $key);
|
||||
$cursor->hashKey = $key;
|
||||
$this->dumpItem($dumper, $cursor, $refs, $child);
|
||||
if (++$cursor->hashIndex === $this->maxItemsPerDepth || $cursor->stop) {
|
||||
$parentCursor->stop = true;
|
||||
|
||||
return $hashCut >= 0 ? $hashCut + $cursor->hashLength - $cursor->hashIndex : $hashCut;
|
||||
}
|
||||
}
|
||||
} elseif ($hashCut >= 0) {
|
||||
$hashCut += count($children);
|
||||
}
|
||||
}
|
||||
|
||||
return $hashCut;
|
||||
}
|
||||
}
|
@@ -1,60 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Cloner;
|
||||
|
||||
/**
|
||||
* DumperInterface used by Data objects.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
interface DumperInterface
|
||||
{
|
||||
/**
|
||||
* Dumps a scalar value.
|
||||
*
|
||||
* @param Cursor $cursor The Cursor position in the dump.
|
||||
* @param string $type The PHP type of the value being dumped.
|
||||
* @param scalar $value The scalar value being dumped.
|
||||
*/
|
||||
public function dumpScalar(Cursor $cursor, $type, $value);
|
||||
|
||||
/**
|
||||
* Dumps a string.
|
||||
*
|
||||
* @param Cursor $cursor The Cursor position in the dump.
|
||||
* @param string $str The string being dumped.
|
||||
* @param bool $bin Whether $str is UTF-8 or binary encoded.
|
||||
* @param int $cut The number of characters $str has been cut by.
|
||||
*/
|
||||
public function dumpString(Cursor $cursor, $str, $bin, $cut);
|
||||
|
||||
/**
|
||||
* Dumps while entering an hash.
|
||||
*
|
||||
* @param Cursor $cursor The Cursor position in the dump.
|
||||
* @param int $type A Cursor::HASH_* const for the type of hash.
|
||||
* @param string $class The object class, resource type or array count.
|
||||
* @param bool $hasChild When the dump of the hash has child item.
|
||||
*/
|
||||
public function enterHash(Cursor $cursor, $type, $class, $hasChild);
|
||||
|
||||
/**
|
||||
* Dumps while leaving an hash.
|
||||
*
|
||||
* @param Cursor $cursor The Cursor position in the dump.
|
||||
* @param int $type A Cursor::HASH_* const for the type of hash.
|
||||
* @param string $class The object class, resource type or array count.
|
||||
* @param bool $hasChild When the dump of the hash has child item.
|
||||
* @param int $cut The number of items the hash has been cut by.
|
||||
*/
|
||||
public function leaveHash(Cursor $cursor, $type, $class, $hasChild, $cut);
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Cloner;
|
||||
|
||||
/**
|
||||
* Represents the main properties of a PHP variable.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class Stub
|
||||
{
|
||||
const TYPE_REF = 'ref';
|
||||
const TYPE_STRING = 'string';
|
||||
const TYPE_ARRAY = 'array';
|
||||
const TYPE_OBJECT = 'object';
|
||||
const TYPE_RESOURCE = 'resource';
|
||||
|
||||
const STRING_BINARY = 'bin';
|
||||
const STRING_UTF8 = 'utf8';
|
||||
|
||||
const ARRAY_ASSOC = 'assoc';
|
||||
const ARRAY_INDEXED = 'indexed';
|
||||
|
||||
public $type = self::TYPE_REF;
|
||||
public $class = '';
|
||||
public $value;
|
||||
public $cut = 0;
|
||||
public $handle = 0;
|
||||
public $refCount = 0;
|
||||
public $position = 0;
|
||||
}
|
@@ -1,300 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* 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 <p@tchwork.com>
|
||||
*/
|
||||
class VarCloner extends AbstractCloner
|
||||
{
|
||||
private static $hashMask = 0;
|
||||
private static $hashOffset = 0;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doClone($var)
|
||||
{
|
||||
$useExt = $this->useExt;
|
||||
$i = 0; // Current iteration position in $queue
|
||||
$len = 1; // Length of $queue
|
||||
$pos = 0; // Number of cloned items past the first level
|
||||
$refs = 0; // Hard references counter
|
||||
$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
|
||||
$objRefs = array(); // Map of original object handles to their stub object couterpart
|
||||
$resRefs = array(); // Map of original resource handles 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
|
||||
$gid = uniqid(mt_rand(), true); // Unique string used to detect the special $GLOBALS variable
|
||||
$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,
|
||||
'zval_hash' => null,
|
||||
'array_count' => null,
|
||||
'object_class' => null,
|
||||
'object_handle' => null,
|
||||
'resource_type' => null,
|
||||
);
|
||||
if (!self::$hashMask) {
|
||||
self::initHashMask();
|
||||
}
|
||||
$hashMask = self::$hashMask;
|
||||
$hashOffset = self::$hashOffset;
|
||||
|
||||
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;
|
||||
}
|
||||
if ($useExt) {
|
||||
$zval = symfony_zval_info($k, $step);
|
||||
} else {
|
||||
$step[$k] = $cookie;
|
||||
if ($zval['zval_isref'] = $queue[$i][$k] === $cookie) {
|
||||
$zval['zval_hash'] = $v instanceof Stub ? spl_object_hash($v) : null;
|
||||
}
|
||||
$zval['type'] = gettype($v);
|
||||
}
|
||||
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[$zval['zval_hash']])) {
|
||||
$queue[$i][$k] = $useExt ? ($v = $hardRefs[$zval['zval_hash']]) : ($step[$k] = $v);
|
||||
if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) {
|
||||
++$v->value->refCount;
|
||||
}
|
||||
++$v->refCount;
|
||||
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;
|
||||
$stub->value = substr($v, 0, -$cut);
|
||||
} else {
|
||||
$stub->value = $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'] ?: count($v);
|
||||
|
||||
$a = $v;
|
||||
|
||||
// Copies of $GLOBALS have very strange behavior,
|
||||
// let's detect them with some black magic
|
||||
$a[$gid] = true;
|
||||
|
||||
// Happens with copies of $GLOBALS
|
||||
if (isset($v[$gid])) {
|
||||
unset($v[$gid]);
|
||||
$a = array();
|
||||
foreach ($v as $gk => &$gv) {
|
||||
$a[$gk] =& $gv;
|
||||
}
|
||||
} else {
|
||||
$a = $v;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'object':
|
||||
if (empty($objRefs[$h = $zval['object_handle'] ?: ($hashMask ^ hexdec(substr(spl_object_hash($v), $hashOffset, PHP_INT_SIZE)))])) {
|
||||
$stub = new Stub();
|
||||
$stub->type = Stub::TYPE_OBJECT;
|
||||
$stub->class = $zval['object_class'] ?: get_class($v);
|
||||
$stub->value = $v;
|
||||
$stub->handle = $h;
|
||||
$a = $this->castObject($stub, 0 < $i);
|
||||
if ($v !== $stub->value) {
|
||||
if (Stub::TYPE_OBJECT !== $stub->type) {
|
||||
break;
|
||||
}
|
||||
if ($useExt) {
|
||||
$zval['type'] = $stub->value;
|
||||
$zval = symfony_zval_info('type', $zval);
|
||||
$h = $zval['object_handle'];
|
||||
} else {
|
||||
$h = $hashMask ^ hexdec(substr(spl_object_hash($stub->value), $hashOffset, PHP_INT_SIZE));
|
||||
}
|
||||
$stub->handle = $h;
|
||||
}
|
||||
$stub->value = null;
|
||||
if (0 <= $maxItems && $maxItems <= $pos) {
|
||||
$stub->cut = count($a);
|
||||
$a = null;
|
||||
}
|
||||
}
|
||||
if (empty($objRefs[$h])) {
|
||||
$objRefs[$h] = $stub;
|
||||
} else {
|
||||
$stub = $objRefs[$h];
|
||||
++$stub->refCount;
|
||||
$a = null;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'resource':
|
||||
case 'unknown type':
|
||||
if (empty($resRefs[$h = (int) $v])) {
|
||||
$stub = new Stub();
|
||||
$stub->type = Stub::TYPE_RESOURCE;
|
||||
$stub->class = $zval['resource_type'] ?: get_resource_type($v);
|
||||
$stub->value = $v;
|
||||
$stub->handle = $h;
|
||||
$a = $this->castResource($stub, 0 < $i);
|
||||
$stub->value = null;
|
||||
if (0 <= $maxItems && $maxItems <= $pos) {
|
||||
$stub->cut = count($a);
|
||||
$a = null;
|
||||
}
|
||||
}
|
||||
if (empty($resRefs[$h])) {
|
||||
$resRefs[$h] = $stub;
|
||||
} else {
|
||||
$stub = $resRefs[$h];
|
||||
++$stub->refCount;
|
||||
$a = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (isset($stub)) {
|
||||
if ($zval['zval_isref']) {
|
||||
if ($useExt) {
|
||||
$queue[$i][$k] = $hardRefs[$zval['zval_hash']] = $v = new Stub();
|
||||
$v->value = $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;
|
||||
}
|
||||
$queue[$i][$k]->handle = ++$refs;
|
||||
} 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']) {
|
||||
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;
|
||||
}
|
||||
$queue[$i][$k]->handle = ++$refs;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($arrayRefs[$i])) {
|
||||
if ($indexed) {
|
||||
$arrayRefs[$i]->class = Stub::ARRAY_INDEXED;
|
||||
}
|
||||
unset($arrayRefs[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($values as $h => $v) {
|
||||
$hardRefs[$h] = $v;
|
||||
}
|
||||
|
||||
return $queue;
|
||||
}
|
||||
|
||||
private static function initHashMask()
|
||||
{
|
||||
$obj = (object) array();
|
||||
self::$hashOffset = 16 - PHP_INT_SIZE;
|
||||
self::$hashMask = -1;
|
||||
|
||||
if (defined('HHVM_VERSION')) {
|
||||
self::$hashOffset += 16;
|
||||
} else {
|
||||
// check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below
|
||||
$obFuncs = array('ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush');
|
||||
foreach (debug_backtrace(PHP_VERSION_ID >= 50400 ? DEBUG_BACKTRACE_IGNORE_ARGS : false) as $frame) {
|
||||
if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && in_array($frame['function'], $obFuncs)) {
|
||||
$frame['line'] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!empty($frame['line'])) {
|
||||
ob_start();
|
||||
debug_zval_dump($obj);
|
||||
self::$hashMask = substr(ob_get_clean(), 17);
|
||||
}
|
||||
}
|
||||
|
||||
self::$hashMask ^= hexdec(substr(spl_object_hash($obj), self::$hashOffset, PHP_INT_SIZE));
|
||||
}
|
||||
}
|
@@ -1,222 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
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, DumperInterface
|
||||
{
|
||||
public static $defaultOutput = 'php://output';
|
||||
|
||||
protected $line = '';
|
||||
protected $lineDumper;
|
||||
protected $outputStream;
|
||||
protected $decimalPoint; // This is locale dependent
|
||||
protected $indentPad = ' ';
|
||||
|
||||
private $charset;
|
||||
private $charsetConverter;
|
||||
|
||||
/**
|
||||
* @param callable|resource|string|null $output A line dumper callable, an opened stream or an output path, defaults to static::$defaultOutput.
|
||||
* @param string $charset The default character encoding to use for non-UTF8 strings.
|
||||
*/
|
||||
public function __construct($output = null, $charset = null)
|
||||
{
|
||||
$this->setCharset($charset ?: ini_get('php.output_encoding') ?: ini_get('default_charset') ?: 'UTF-8');
|
||||
$this->decimalPoint = (string) 0.5;
|
||||
$this->decimalPoint = $this->decimalPoint[1];
|
||||
$this->setOutput($output ?: static::$defaultOutput);
|
||||
if (!$output && is_string(static::$defaultOutput)) {
|
||||
static::$defaultOutput = $this->outputStream;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the output destination of the dumps.
|
||||
*
|
||||
* @param callable|resource|string $output A line dumper callable, an opened stream or an output path.
|
||||
*
|
||||
* @return callable|resource|string The previous output destination.
|
||||
*/
|
||||
public function setOutput($output)
|
||||
{
|
||||
$prev = null !== $this->outputStream ? $this->outputStream : $this->lineDumper;
|
||||
|
||||
if (is_callable($output)) {
|
||||
$this->outputStream = null;
|
||||
$this->lineDumper = $output;
|
||||
} else {
|
||||
if (is_string($output)) {
|
||||
$output = fopen($output, 'wb');
|
||||
}
|
||||
$this->outputStream = $output;
|
||||
$this->lineDumper = array($this, 'echoLine');
|
||||
}
|
||||
|
||||
return $prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default character encoding to use for non-UTF8 strings.
|
||||
*
|
||||
* @param string $charset The default character encoding to use for non-UTF8 strings.
|
||||
*
|
||||
* @return string The previous charset.
|
||||
*/
|
||||
public function setCharset($charset)
|
||||
{
|
||||
$prev = $this->charset;
|
||||
$this->charsetConverter = 'fallback';
|
||||
|
||||
$charset = strtoupper($charset);
|
||||
$charset = null === $charset || 'UTF-8' === $charset || 'UTF8' === $charset ? 'CP1252' : $charset;
|
||||
|
||||
$supported = true;
|
||||
set_error_handler(function () use (&$supported) {$supported = false;});
|
||||
|
||||
if (function_exists('mb_encoding_aliases') && mb_encoding_aliases($charset)) {
|
||||
$this->charset = $charset;
|
||||
$this->charsetConverter = 'mbstring';
|
||||
} elseif (function_exists('iconv')) {
|
||||
$supported = true;
|
||||
iconv($charset, 'UTF-8', '');
|
||||
if ($supported) {
|
||||
$this->charset = $charset;
|
||||
$this->charsetConverter = 'iconv';
|
||||
}
|
||||
}
|
||||
if ('fallback' === $this->charsetConverter) {
|
||||
$this->charset = 'ISO-8859-1';
|
||||
}
|
||||
restore_error_handler();
|
||||
|
||||
return $prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the indentation pad string.
|
||||
*
|
||||
* @param string $pad A string the will be prepended to dumped lines, repeated by nesting level.
|
||||
*
|
||||
* @return string The indent pad.
|
||||
*/
|
||||
public function setIndentPad($pad)
|
||||
{
|
||||
$prev = $this->indentPad;
|
||||
$this->indentPad = $pad;
|
||||
|
||||
return $prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps a Data object.
|
||||
*
|
||||
* @param Data $data A Data object.
|
||||
* @param callable|resource|string|null $output A line dumper callable, an opened stream or an output path.
|
||||
*/
|
||||
public function dump(Data $data, $output = null)
|
||||
{
|
||||
$exception = null;
|
||||
if ($output) {
|
||||
$prevOutput = $this->setOutput($output);
|
||||
}
|
||||
try {
|
||||
$data->dump($this);
|
||||
$this->dumpLine(-1);
|
||||
} catch (\Exception $exception) {
|
||||
// Re-thrown below
|
||||
}
|
||||
if ($output) {
|
||||
$this->setOutput($prevOutput);
|
||||
}
|
||||
if (null !== $exception) {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the current line.
|
||||
*
|
||||
* @param int $depth The recursive depth in the dumped structure for the line being dumped.
|
||||
*/
|
||||
protected function dumpLine($depth)
|
||||
{
|
||||
call_user_func($this->lineDumper, $this->line, $depth, $this->indentPad);
|
||||
$this->line = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic line dumper callback.
|
||||
*
|
||||
* @param string $line The line to write.
|
||||
* @param int $depth The recursive depth in the dumped structure.
|
||||
*/
|
||||
protected function echoLine($line, $depth, $indentPad)
|
||||
{
|
||||
if (-1 !== $depth) {
|
||||
fwrite($this->outputStream, str_repeat($indentPad, $depth).$line."\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a non-UTF-8 string to UTF-8.
|
||||
*
|
||||
* @param string $s The non-UTF-8 string to convert.
|
||||
*
|
||||
* @return string The string converted to UTF-8.
|
||||
*/
|
||||
protected function utf8Encode($s)
|
||||
{
|
||||
if ('mbstring' === $this->charsetConverter) {
|
||||
return mb_convert_encoding($s, 'UTF-8', mb_check_encoding($s, $this->charset) ? $this->charset : '8bit');
|
||||
}
|
||||
if ('iconv' === $this->charsetConverter) {
|
||||
$valid = true;
|
||||
set_error_handler(function () use (&$valid) {$valid = false;});
|
||||
$c = iconv($this->charset, 'UTF-8', $s);
|
||||
restore_error_handler();
|
||||
if ($valid) {
|
||||
return $c;
|
||||
}
|
||||
}
|
||||
|
||||
$s .= $s;
|
||||
$len = strlen($s);
|
||||
|
||||
for ($i = $len >> 1, $j = 0; $i < $len; ++$i, ++$j) {
|
||||
switch (true) {
|
||||
case $s[$i] < "\x80":
|
||||
$s[$j] = $s[$i];
|
||||
break;
|
||||
|
||||
case $s[$i] < "\xC0":
|
||||
$s[$j] = "\xC2";
|
||||
$s[++$j] = $s[$i];
|
||||
break;
|
||||
|
||||
default:
|
||||
$s[$j] = "\xC3";
|
||||
$s[++$j] = chr(ord($s[$i]) - 64);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return substr($s, 0, $j);
|
||||
}
|
||||
}
|
@@ -1,428 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Dumper;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Cursor;
|
||||
|
||||
/**
|
||||
* CliDumper dumps variables for command line output.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class CliDumper extends AbstractDumper
|
||||
{
|
||||
public static $defaultColors;
|
||||
public static $defaultOutput = 'php://stdout';
|
||||
|
||||
protected $colors;
|
||||
protected $maxStringWidth = 0;
|
||||
protected $styles = array(
|
||||
// See http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
|
||||
'default' => '38;5;208',
|
||||
'num' => '1;38;5;38',
|
||||
'const' => '1;38;5;208',
|
||||
'str' => '1;38;5;113',
|
||||
'cchr' => '7',
|
||||
'note' => '38;5;38',
|
||||
'ref' => '38;5;247',
|
||||
'public' => '',
|
||||
'protected' => '',
|
||||
'private' => '',
|
||||
'meta' => '38;5;170',
|
||||
'key' => '38;5;113',
|
||||
'index' => '38;5;38',
|
||||
);
|
||||
|
||||
protected static $controlCharsRx = '/[\x00-\x1F\x7F]/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct($output = null, $charset = null)
|
||||
{
|
||||
parent::__construct($output, $charset);
|
||||
|
||||
if ('\\' === DIRECTORY_SEPARATOR && false !== @getenv('ANSICON')) {
|
||||
// Use only the base 16 xterm colors when using ANSICON
|
||||
$this->setStyles(array(
|
||||
'default' => '31',
|
||||
'num' => '1;34',
|
||||
'const' => '1;31',
|
||||
'str' => '1;32',
|
||||
'note' => '34',
|
||||
'ref' => '1;30',
|
||||
'meta' => '35',
|
||||
'key' => '32',
|
||||
'index' => '34',
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables/disables colored output.
|
||||
*
|
||||
* @param bool $colors
|
||||
*/
|
||||
public function setColors($colors)
|
||||
{
|
||||
$this->colors = (bool) $colors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum number of characters per line for dumped strings.
|
||||
*
|
||||
* @param int $maxStringWidth
|
||||
*/
|
||||
public function setMaxStringWidth($maxStringWidth)
|
||||
{
|
||||
if (function_exists('iconv')) {
|
||||
$this->maxStringWidth = (int) $maxStringWidth;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures styles.
|
||||
*
|
||||
* @param array $styles A map of style names to style definitions.
|
||||
*/
|
||||
public function setStyles(array $styles)
|
||||
{
|
||||
$this->styles = $styles + $this->styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dumpScalar(Cursor $cursor, $type, $value)
|
||||
{
|
||||
$this->dumpKey($cursor);
|
||||
|
||||
$style = 'const';
|
||||
$attr = array();
|
||||
|
||||
switch ($type) {
|
||||
case 'integer':
|
||||
$style = 'num';
|
||||
break;
|
||||
|
||||
case 'double':
|
||||
$style = 'num';
|
||||
|
||||
switch (true) {
|
||||
case INF === $value: $value = 'INF'; break;
|
||||
case -INF === $value: $value = '-INF'; break;
|
||||
case is_nan($value): $value = 'NAN'; break;
|
||||
default:
|
||||
$value = (string) $value;
|
||||
if (false === strpos($value, $this->decimalPoint)) {
|
||||
$value .= $this->decimalPoint.'0';
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'NULL':
|
||||
$value = 'null';
|
||||
break;
|
||||
|
||||
case 'boolean':
|
||||
$value = $value ? 'true' : 'false';
|
||||
break;
|
||||
|
||||
default:
|
||||
$attr['value'] = isset($value[0]) && !preg_match('//u', $value) ? $this->utf8Encode($value) : $value;
|
||||
$value = isset($type[0]) && !preg_match('//u', $type) ? $this->utf8Encode($type) : $type;
|
||||
break;
|
||||
}
|
||||
|
||||
$this->line .= $this->style($style, $value, $attr);
|
||||
|
||||
$this->dumpLine($cursor->depth);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dumpString(Cursor $cursor, $str, $bin, $cut)
|
||||
{
|
||||
$this->dumpKey($cursor);
|
||||
|
||||
if ($bin) {
|
||||
$str = $this->utf8Encode($str);
|
||||
}
|
||||
if ('' === $str) {
|
||||
$this->line .= '""';
|
||||
$this->dumpLine($cursor->depth);
|
||||
} else {
|
||||
$attr = array(
|
||||
'length' => function_exists('iconv_strlen') && 0 <= $cut ? iconv_strlen($str, 'UTF-8') + $cut : 0,
|
||||
'binary' => $bin,
|
||||
);
|
||||
$str = explode("\n", $str);
|
||||
$m = count($str) - 1;
|
||||
$i = $lineCut = 0;
|
||||
|
||||
if ($bin) {
|
||||
$this->line .= 'b';
|
||||
}
|
||||
|
||||
if ($m) {
|
||||
$this->line .= '"""';
|
||||
$this->dumpLine($cursor->depth);
|
||||
} else {
|
||||
$this->line .= '"';
|
||||
}
|
||||
|
||||
foreach ($str as $str) {
|
||||
if (0 < $this->maxStringWidth && $this->maxStringWidth < $len = iconv_strlen($str, 'UTF-8')) {
|
||||
$str = iconv_substr($str, 0, $this->maxStringWidth, 'UTF-8');
|
||||
$lineCut = $len - $this->maxStringWidth;
|
||||
}
|
||||
|
||||
if ($m) {
|
||||
$this->line .= $this->indentPad;
|
||||
}
|
||||
$this->line .= $this->style('str', $str, $attr);
|
||||
|
||||
if ($i++ == $m) {
|
||||
$this->line .= '"';
|
||||
if ($m) {
|
||||
$this->line .= '""';
|
||||
}
|
||||
if ($cut < 0) {
|
||||
$this->line .= '…';
|
||||
$lineCut = 0;
|
||||
} elseif ($cut) {
|
||||
$lineCut += $cut;
|
||||
}
|
||||
}
|
||||
if ($lineCut) {
|
||||
$this->line .= '…'.$lineCut;
|
||||
$lineCut = 0;
|
||||
}
|
||||
|
||||
$this->dumpLine($cursor->depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function enterHash(Cursor $cursor, $type, $class, $hasChild)
|
||||
{
|
||||
$this->dumpKey($cursor);
|
||||
|
||||
if (!preg_match('//u', $class)) {
|
||||
$class = $this->utf8Encode($class);
|
||||
}
|
||||
if (Cursor::HASH_OBJECT === $type) {
|
||||
$prefix = 'stdClass' !== $class ? $this->style('note', $class).' {' : '{';
|
||||
} elseif (Cursor::HASH_RESOURCE === $type) {
|
||||
$prefix = $this->style('note', ':'.$class).' {';
|
||||
} else {
|
||||
$prefix = $class ? $this->style('note', 'array:'.$class).' [' : '[';
|
||||
}
|
||||
|
||||
if ($cursor->softRefCount || 0 < $cursor->softRefHandle) {
|
||||
$prefix .= $this->style('ref', (Cursor::HASH_RESOURCE === $type ? '@' : '#').(0 < $cursor->softRefHandle ? $cursor->softRefHandle : $cursor->softRefTo), array('count' => $cursor->softRefCount));
|
||||
} elseif ($cursor->hardRefTo && !$cursor->refIndex && $class) {
|
||||
$prefix .= $this->style('ref', '&'.$cursor->hardRefTo, array('count' => $cursor->hardRefCount));
|
||||
}
|
||||
|
||||
$this->line .= $prefix;
|
||||
|
||||
if ($hasChild) {
|
||||
$this->dumpLine($cursor->depth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function leaveHash(Cursor $cursor, $type, $class, $hasChild, $cut)
|
||||
{
|
||||
$this->dumpEllipsis($cursor, $hasChild, $cut);
|
||||
$this->line .= Cursor::HASH_OBJECT === $type || Cursor::HASH_RESOURCE === $type ? '}' : ']';
|
||||
$this->dumpLine($cursor->depth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps an ellipsis for cut children.
|
||||
*
|
||||
* @param Cursor $cursor The Cursor position in the dump.
|
||||
* @param bool $hasChild When the dump of the hash has child item.
|
||||
* @param int $cut The number of items the hash has been cut by.
|
||||
*/
|
||||
protected function dumpEllipsis(Cursor $cursor, $hasChild, $cut)
|
||||
{
|
||||
if ($cut) {
|
||||
$this->line .= ' …';
|
||||
if (0 < $cut) {
|
||||
$this->line .= $cut;
|
||||
}
|
||||
if ($hasChild) {
|
||||
$this->dumpLine($cursor->depth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps a key in a hash structure.
|
||||
*
|
||||
* @param Cursor $cursor The Cursor position in the dump.
|
||||
*/
|
||||
protected function dumpKey(Cursor $cursor)
|
||||
{
|
||||
if (null !== $key = $cursor->hashKey) {
|
||||
if ($cursor->hashKeyIsBinary) {
|
||||
$key = $this->utf8Encode($key);
|
||||
}
|
||||
$attr = array('binary' => $cursor->hashKeyIsBinary);
|
||||
$bin = $cursor->hashKeyIsBinary ? 'b' : '';
|
||||
$style = 'key';
|
||||
switch ($cursor->hashType) {
|
||||
default:
|
||||
case Cursor::HASH_INDEXED:
|
||||
$style = 'index';
|
||||
case Cursor::HASH_ASSOC:
|
||||
if (is_int($key)) {
|
||||
$this->line .= $this->style($style, $key).' => ';
|
||||
} else {
|
||||
$this->line .= $bin.'"'.$this->style($style, $key).'" => ';
|
||||
}
|
||||
break;
|
||||
|
||||
case Cursor::HASH_RESOURCE:
|
||||
$key = "\0~\0".$key;
|
||||
// No break;
|
||||
case Cursor::HASH_OBJECT:
|
||||
if (!isset($key[0]) || "\0" !== $key[0]) {
|
||||
$this->line .= '+'.$bin.$this->style('public', $key).': ';
|
||||
} elseif (0 < strpos($key, "\0", 1)) {
|
||||
$key = explode("\0", substr($key, 1), 2);
|
||||
|
||||
switch ($key[0]) {
|
||||
case '+': // User inserted keys
|
||||
$attr['dynamic'] = true;
|
||||
$this->line .= '+'.$bin.'"'.$this->style('public', $key[1], $attr).'": ';
|
||||
break 2;
|
||||
case '~':
|
||||
$style = 'meta';
|
||||
break;
|
||||
case '*':
|
||||
$style = 'protected';
|
||||
$bin = '#'.$bin;
|
||||
break;
|
||||
default:
|
||||
$attr['class'] = $key[0];
|
||||
$style = 'private';
|
||||
$bin = '-'.$bin;
|
||||
break;
|
||||
}
|
||||
|
||||
$this->line .= $bin.$this->style($style, $key[1], $attr).': ';
|
||||
} else {
|
||||
// This case should not happen
|
||||
$this->line .= '-'.$bin.'"'.$this->style('private', $key, array('class' => '')).'": ';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ($cursor->hardRefTo) {
|
||||
$this->line .= $this->style('ref', '&'.($cursor->hardRefCount ? $cursor->hardRefTo : ''), array('count' => $cursor->hardRefCount)).' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorates a value with some style.
|
||||
*
|
||||
* @param string $style The type of style being applied.
|
||||
* @param string $value The value being styled.
|
||||
* @param array $attr Optional context information.
|
||||
*
|
||||
* @return string The value with style decoration.
|
||||
*/
|
||||
protected function style($style, $value, $attr = array())
|
||||
{
|
||||
if (null === $this->colors) {
|
||||
$this->colors = $this->supportsColors();
|
||||
}
|
||||
|
||||
$style = $this->styles[$style];
|
||||
$cchr = $this->colors ? "\033[m\033[{$style};{$this->styles['cchr']}m%s\033[m\033[{$style}m" : '%s';
|
||||
$value = preg_replace_callback(self::$controlCharsRx, function ($r) use ($cchr) {
|
||||
return sprintf($cchr, "\x7F" === $r[0] ? '?' : chr(64 + ord($r[0])));
|
||||
}, $value);
|
||||
|
||||
return $this->colors ? sprintf("\033[%sm%s\033[m\033[%sm", $style, $value, $this->styles['default']) : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool Tells if the current output stream supports ANSI colors or not.
|
||||
*/
|
||||
protected function supportsColors()
|
||||
{
|
||||
if ($this->outputStream !== static::$defaultOutput) {
|
||||
return @(is_resource($this->outputStream) && function_exists('posix_isatty') && posix_isatty($this->outputStream));
|
||||
}
|
||||
if (null !== static::$defaultColors) {
|
||||
return static::$defaultColors;
|
||||
}
|
||||
if (isset($_SERVER['argv'][1])) {
|
||||
$colors = $_SERVER['argv'];
|
||||
$i = count($colors);
|
||||
while (--$i > 0) {
|
||||
if (isset($colors[$i][5])) {
|
||||
switch ($colors[$i]) {
|
||||
case '--ansi':
|
||||
case '--color':
|
||||
case '--color=yes':
|
||||
case '--color=force':
|
||||
case '--color=always':
|
||||
return static::$defaultColors = true;
|
||||
|
||||
case '--no-ansi':
|
||||
case '--color=no':
|
||||
case '--color=none':
|
||||
case '--color=never':
|
||||
return static::$defaultColors = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ('\\' === DIRECTORY_SEPARATOR) {
|
||||
static::$defaultColors = @(false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI'));
|
||||
} elseif (function_exists('posix_isatty')) {
|
||||
$h = stream_get_meta_data($this->outputStream) + array('wrapper_type' => null);
|
||||
$h = 'Output' === $h['stream_type'] && 'PHP' === $h['wrapper_type'] ? fopen('php://stdout', 'wb') : $this->outputStream;
|
||||
static::$defaultColors = @posix_isatty($h);
|
||||
} else {
|
||||
static::$defaultColors = false;
|
||||
}
|
||||
|
||||
return static::$defaultColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function dumpLine($depth)
|
||||
{
|
||||
if ($this->colors) {
|
||||
$this->line = sprintf("\033[%sm%s\033[m", $this->styles['default'], $this->line);
|
||||
}
|
||||
parent::dumpLine($depth);
|
||||
}
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Dumper;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Data;
|
||||
|
||||
/**
|
||||
* DataDumperInterface for dumping Data objects.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
interface DataDumperInterface
|
||||
{
|
||||
/**
|
||||
* Dumps a Data object.
|
||||
*
|
||||
* @param Data $data A Data object.
|
||||
*/
|
||||
public function dump(Data $data);
|
||||
}
|
@@ -1,405 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Dumper;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Cursor;
|
||||
use Symfony\Component\VarDumper\Cloner\Data;
|
||||
|
||||
/**
|
||||
* HtmlDumper dumps variables as HTML.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class HtmlDumper extends CliDumper
|
||||
{
|
||||
public static $defaultOutput = 'php://output';
|
||||
|
||||
protected $dumpHeader;
|
||||
protected $dumpPrefix = '<pre class=sf-dump id=%s data-indent-pad="%s">';
|
||||
protected $dumpSuffix = '</pre><script>Sfdump("%s")</script>';
|
||||
protected $dumpId = 'sf-dump';
|
||||
protected $colors = true;
|
||||
protected $headerIsDumped = false;
|
||||
protected $lastDepth = -1;
|
||||
protected $styles = array(
|
||||
'default' => 'background-color:#18171B; color:#FF8400; line-height:1.2em; font:12px Menlo, Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:100000',
|
||||
'num' => 'font-weight:bold; color:#1299DA',
|
||||
'const' => 'font-weight:bold',
|
||||
'str' => 'font-weight:bold; color:#56DB3A',
|
||||
'cchr' => 'color:#FF8400',
|
||||
'note' => 'color:#1299DA',
|
||||
'ref' => 'color:#A0A0A0',
|
||||
'public' => 'color:#FFFFFF',
|
||||
'protected' => 'color:#FFFFFF',
|
||||
'private' => 'color:#FFFFFF',
|
||||
'meta' => 'color:#B729D9',
|
||||
'key' => 'color:#56DB3A',
|
||||
'index' => 'color:#1299DA',
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setOutput($output)
|
||||
{
|
||||
if ($output !== $prev = parent::setOutput($output)) {
|
||||
$this->headerIsDumped = false;
|
||||
}
|
||||
|
||||
return $prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setStyles(array $styles)
|
||||
{
|
||||
$this->headerIsDumped = false;
|
||||
$this->styles = $styles + $this->styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an HTML header that will be dumped once in the output stream.
|
||||
*
|
||||
* @param string $header An HTML string.
|
||||
*/
|
||||
public function setDumpHeader($header)
|
||||
{
|
||||
$this->dumpHeader = $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an HTML prefix and suffix that will encapse every single dump.
|
||||
*
|
||||
* @param string $prefix The prepended HTML string.
|
||||
* @param string $suffix The appended HTML string.
|
||||
*/
|
||||
public function setDumpBoundaries($prefix, $suffix)
|
||||
{
|
||||
$this->dumpPrefix = $prefix;
|
||||
$this->dumpSuffix = $suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dump(Data $data, $output = null)
|
||||
{
|
||||
$this->dumpId = 'sf-dump-'.mt_rand();
|
||||
parent::dump($data, $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the HTML header.
|
||||
*/
|
||||
protected function getDumpHeader()
|
||||
{
|
||||
$this->headerIsDumped = true;
|
||||
|
||||
if (null !== $this->dumpHeader) {
|
||||
return $this->dumpHeader;
|
||||
}
|
||||
|
||||
$line = <<<'EOHTML'
|
||||
<script>
|
||||
Sfdump = window.Sfdump || (function (doc) {
|
||||
|
||||
var refStyle = doc.createElement('style'),
|
||||
rxEsc = /([.*+?^${}()|\[\]\/\\])/g,
|
||||
idRx = /\bsf-dump-\d+-ref[012]\w+\b/;
|
||||
|
||||
doc.documentElement.firstChild.appendChild(refStyle);
|
||||
|
||||
function toggle(a) {
|
||||
var s = a.nextSibling || {};
|
||||
|
||||
if ('sf-dump-compact' == s.className) {
|
||||
a.lastChild.innerHTML = '▼';
|
||||
s.className = 'sf-dump-expanded';
|
||||
} else if ('sf-dump-expanded' == s.className) {
|
||||
a.lastChild.innerHTML = '▶';
|
||||
s.className = 'sf-dump-compact';
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
return function (root) {
|
||||
root = doc.getElementById(root);
|
||||
|
||||
function a(e, f) {
|
||||
root.addEventListener(e, function (e) {
|
||||
if ('A' == e.target.tagName) {
|
||||
f(e.target, e);
|
||||
} else if ('A' == e.target.parentNode.tagName) {
|
||||
f(e.target.parentNode, e);
|
||||
}
|
||||
});
|
||||
};
|
||||
root.addEventListener('mouseover', function (e) {
|
||||
if ('' != refStyle.innerHTML) {
|
||||
refStyle.innerHTML = '';
|
||||
}
|
||||
});
|
||||
a('mouseover', function (a) {
|
||||
if (a = idRx.exec(a.className)) {
|
||||
refStyle.innerHTML = 'pre.sf-dump .'+a[0]+'{background-color: #B729D9; color: #FFF !important; border-radius: 2px}';
|
||||
}
|
||||
});
|
||||
a('click', function (a, e) {
|
||||
if (/\bsf-dump-toggle\b/.test(a.className)) {
|
||||
e.preventDefault();
|
||||
if (!toggle(a)) {
|
||||
var r = doc.getElementById(a.getAttribute('href').substr(1)),
|
||||
s = r.previousSibling,
|
||||
f = r.parentNode,
|
||||
t = a.parentNode;
|
||||
t.replaceChild(r, a);
|
||||
f.replaceChild(a, s);
|
||||
t.insertBefore(s, r);
|
||||
f = f.firstChild.nodeValue.match(indentRx);
|
||||
t = t.firstChild.nodeValue.match(indentRx);
|
||||
if (f && t && f[0] !== t[0]) {
|
||||
r.innerHTML = r.innerHTML.replace(new RegExp('^'+f[0].replace(rxEsc, '\\$1'), 'mg'), t[0]);
|
||||
}
|
||||
if ('sf-dump-compact' == r.className) {
|
||||
toggle(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var indentRx = new RegExp('^('+(root.getAttribute('data-indent-pad') || ' ').replace(rxEsc, '\\$1')+')+', 'm'),
|
||||
elt = root.getElementsByTagName('A'),
|
||||
len = elt.length,
|
||||
i = 0,
|
||||
t = [];
|
||||
|
||||
while (i < len) t.push(elt[i++]);
|
||||
|
||||
elt = root.getElementsByTagName('SAMP');
|
||||
len = elt.length;
|
||||
i = 0;
|
||||
|
||||
while (i < len) t.push(elt[i++]);
|
||||
|
||||
root = t;
|
||||
len = t.length;
|
||||
i = t = 0;
|
||||
|
||||
while (i < len) {
|
||||
elt = root[i];
|
||||
if ("SAMP" == elt.tagName) {
|
||||
elt.className = "sf-dump-expanded";
|
||||
a = elt.previousSibling || {};
|
||||
if ('A' != a.tagName) {
|
||||
a = doc.createElement('A');
|
||||
a.className = 'sf-dump-ref';
|
||||
elt.parentNode.insertBefore(a, elt);
|
||||
} else {
|
||||
a.innerHTML += ' ';
|
||||
}
|
||||
a.innerHTML += '<span>▼</span>';
|
||||
a.className += ' sf-dump-toggle';
|
||||
if ('sf-dump' != elt.parentNode.className) {
|
||||
toggle(a);
|
||||
}
|
||||
} else if ("sf-dump-ref" == elt.className && (a = elt.getAttribute('href'))) {
|
||||
a = a.substr(1);
|
||||
elt.className += ' '+a;
|
||||
|
||||
if (/[\[{]$/.test(elt.previousSibling.nodeValue)) {
|
||||
a = a != elt.nextSibling.id && doc.getElementById(a);
|
||||
try {
|
||||
t = a.nextSibling;
|
||||
elt.appendChild(a);
|
||||
t.parentNode.insertBefore(a, t);
|
||||
if (/^[@#]/.test(elt.innerHTML)) {
|
||||
elt.innerHTML += ' <span>▶</span>';
|
||||
} else {
|
||||
elt.innerHTML = '<span>▶</span>';
|
||||
elt.className = 'sf-dump-ref';
|
||||
}
|
||||
elt.className += ' sf-dump-toggle';
|
||||
} catch (e) {
|
||||
if ('&' == elt.innerHTML.charAt(0)) {
|
||||
elt.innerHTML = '…';
|
||||
elt.className = 'sf-dump-ref';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
};
|
||||
|
||||
})(document);
|
||||
</script>
|
||||
<style>
|
||||
pre.sf-dump {
|
||||
display: block;
|
||||
white-space: pre;
|
||||
padding: 5px;
|
||||
}
|
||||
pre.sf-dump span {
|
||||
display: inline;
|
||||
}
|
||||
pre.sf-dump .sf-dump-compact {
|
||||
display: none;
|
||||
}
|
||||
pre.sf-dump abbr {
|
||||
text-decoration: none;
|
||||
border: none;
|
||||
cursor: help;
|
||||
}
|
||||
pre.sf-dump a {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
outline: none;
|
||||
}
|
||||
EOHTML;
|
||||
|
||||
foreach ($this->styles as $class => $style) {
|
||||
$line .= 'pre.sf-dump'.('default' !== $class ? ' .sf-dump-'.$class : '').'{'.$style.'}';
|
||||
}
|
||||
|
||||
return $this->dumpHeader = preg_replace('/\s+/', ' ', $line).'</style>'.$this->dumpHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function enterHash(Cursor $cursor, $type, $class, $hasChild)
|
||||
{
|
||||
parent::enterHash($cursor, $type, $class, false);
|
||||
|
||||
if ($hasChild) {
|
||||
if ($cursor->refIndex) {
|
||||
$r = Cursor::HASH_OBJECT !== $type ? 1 - (Cursor::HASH_RESOURCE !== $type) : 2;
|
||||
$r .= $r && 0 < $cursor->softRefHandle ? $cursor->softRefHandle : $cursor->refIndex;
|
||||
|
||||
$this->line .= sprintf('<samp id=%s-ref%s>', $this->dumpId, $r);
|
||||
} else {
|
||||
$this->line .= '<samp>';
|
||||
}
|
||||
$this->dumpLine($cursor->depth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function leaveHash(Cursor $cursor, $type, $class, $hasChild, $cut)
|
||||
{
|
||||
$this->dumpEllipsis($cursor, $hasChild, $cut);
|
||||
if ($hasChild) {
|
||||
$this->line .= '</samp>';
|
||||
}
|
||||
parent::leaveHash($cursor, $type, $class, $hasChild, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function style($style, $value, $attr = array())
|
||||
{
|
||||
if ('' === $value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$v = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
|
||||
$v = preg_replace_callback(self::$controlCharsRx, function ($r) {
|
||||
// Use Unicode Control Pictures - see http://www.unicode.org/charts/PDF/U2400.pdf
|
||||
return sprintf('<span class=sf-dump-cchr title=\\x%02X>&#%d;</span>', ord($r[0]), "\x7F" !== $r[0] ? 0x2400 + ord($r[0]) : 0x2421);
|
||||
}, $v);
|
||||
|
||||
if ('ref' === $style) {
|
||||
if (empty($attr['count'])) {
|
||||
return sprintf('<a class=sf-dump-ref>%s</a>', $v);
|
||||
}
|
||||
$r = ('#' !== $v[0] ? 1 - ('@' !== $v[0]) : 2).substr($value, 1);
|
||||
|
||||
return sprintf('<a class=sf-dump-ref href=#%s-ref%s title="%d occurrences">%s</a>', $this->dumpId, $r, 1 + $attr['count'], $v);
|
||||
}
|
||||
|
||||
if ('const' === $style && array_key_exists('value', $attr)) {
|
||||
$style .= sprintf(' title="%s"', htmlspecialchars(json_encode($attr['value']), ENT_QUOTES, 'UTF-8'));
|
||||
} elseif ('public' === $style) {
|
||||
$style .= sprintf(' title="%s"', empty($attr['dynamic']) ? 'Public property' : 'Runtime added dynamic property');
|
||||
} elseif ('str' === $style && 1 < $attr['length']) {
|
||||
$style .= sprintf(' title="%s%s characters"', $attr['length'], $attr['binary'] ? ' binary or non-UTF-8' : '');
|
||||
} elseif ('note' === $style) {
|
||||
if (false !== $c = strrpos($v, '\\')) {
|
||||
return sprintf('<abbr title="%s" class=sf-dump-%s>%s</abbr>', $v, $style, substr($v, $c+1));
|
||||
} elseif (':' === $v[0]) {
|
||||
return sprintf('<abbr title="`%s` resource" class=sf-dump-%s>%s</abbr>', substr($v, 1), $style, $v);
|
||||
}
|
||||
} elseif ('protected' === $style) {
|
||||
$style .= ' title="Protected property"';
|
||||
} elseif ('private' === $style) {
|
||||
$style .= sprintf(' title="Private property defined in class: `%s`"', $attr['class']);
|
||||
}
|
||||
|
||||
return "<span class=sf-dump-$style>$v</span>";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function dumpLine($depth)
|
||||
{
|
||||
if (-1 === $this->lastDepth) {
|
||||
$this->line = sprintf($this->dumpPrefix, $this->dumpId, $this->indentPad).$this->line;
|
||||
}
|
||||
if (!$this->headerIsDumped) {
|
||||
$this->line = $this->getDumpHeader().$this->line;
|
||||
}
|
||||
|
||||
if (-1 === $depth) {
|
||||
$this->line .= sprintf($this->dumpSuffix, $this->dumpId);
|
||||
}
|
||||
$this->lastDepth = $depth;
|
||||
|
||||
// Replaces non-ASCII UTF-8 chars by numeric HTML entities
|
||||
$this->line = preg_replace_callback(
|
||||
'/[\x80-\xFF]+/',
|
||||
function ($m) {
|
||||
$m = unpack('C*', $m[0]);
|
||||
$i = 1;
|
||||
$entities = '';
|
||||
|
||||
while (isset($m[$i])) {
|
||||
if (0xF0 <= $m[$i]) {
|
||||
$c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
|
||||
} elseif (0xE0 <= $m[$i]) {
|
||||
$c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
|
||||
} else {
|
||||
$c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
|
||||
}
|
||||
|
||||
$entities .= '&#'.$c.';';
|
||||
}
|
||||
|
||||
return $entities;
|
||||
},
|
||||
$this->line
|
||||
);
|
||||
|
||||
if (-1 === $depth) {
|
||||
AbstractDumper::dumpLine(0);
|
||||
}
|
||||
AbstractDumper::dumpLine($depth);
|
||||
}
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Exception;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ThrowingCasterException extends \Exception
|
||||
{
|
||||
/**
|
||||
* @param callable $caster The failing caster
|
||||
* @param \Exception $prev The exception thrown from the caster
|
||||
*/
|
||||
public function __construct($caster, \Exception $prev)
|
||||
{
|
||||
parent::__construct('Unexpected exception thrown from a caster: '.get_class($prev), 0, $prev);
|
||||
}
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
Copyright (c) 2014-2015 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
@@ -1,14 +0,0 @@
|
||||
Symfony mechanism for exploring and dumping PHP variables
|
||||
=========================================================
|
||||
|
||||
This component provides a mechanism that allows exploring then dumping
|
||||
any PHP variable.
|
||||
|
||||
It handles scalars, objects and resources properly, taking hard and soft
|
||||
references into account. More than being immune to infinite recursion
|
||||
problems, it allows dumping where references link to each other.
|
||||
It explores recursive structures using a breadth-first algorithm.
|
||||
|
||||
The component exposes all the parts involved in the different steps of
|
||||
cloning then dumping a PHP variable, while applying size limits and having
|
||||
specialized output formats and methods.
|
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Symfony\Component\VarDumper\VarDumper;
|
||||
|
||||
if (!function_exists('dump')) {
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
function dump($var)
|
||||
{
|
||||
foreach (func_get_args() as $var) {
|
||||
VarDumper::dump($var);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,58 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Tests\Caster;
|
||||
|
||||
use Symfony\Component\VarDumper\Caster\PdoCaster;
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class PdoCasterTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testCastPdo()
|
||||
{
|
||||
if (!extension_loaded('pdo_sqlite')) {
|
||||
$this->markTestSkipped('pdo_sqlite extension is required');
|
||||
}
|
||||
|
||||
$pdo = new \PDO('sqlite::memory:');
|
||||
$pdo->setAttribute(\PDO::ATTR_STATEMENT_CLASS, array('PDOStatement', array($pdo)));
|
||||
|
||||
$cast = PdoCaster::castPdo($pdo, array(), new Stub(), false);
|
||||
$attr = $cast["\0~\0attributes"];
|
||||
|
||||
$this->assertInstanceOf('Symfony\Component\VarDumper\Caster\ConstStub', $attr['CASE']);
|
||||
$this->assertSame('NATURAL', $attr['CASE']->class);
|
||||
$this->assertSame('BOTH', $attr['DEFAULT_FETCH_MODE']->class);
|
||||
|
||||
$xCast = array(
|
||||
"\0~\0inTransaction" => $pdo->inTransaction(),
|
||||
"\0~\0attributes" => array(
|
||||
'CASE' => $attr['CASE'],
|
||||
'ERRMODE' => $attr['ERRMODE'],
|
||||
'PERSISTENT' => false,
|
||||
'DRIVER_NAME' => 'sqlite',
|
||||
'ORACLE_NULLS' => $attr['ORACLE_NULLS'],
|
||||
'CLIENT_VERSION' => $pdo->getAttribute(\PDO::ATTR_CLIENT_VERSION),
|
||||
'SERVER_VERSION' => $pdo->getAttribute(\PDO::ATTR_SERVER_VERSION),
|
||||
'STATEMENT_CLASS' => array(
|
||||
'PDOStatement',
|
||||
array($pdo),
|
||||
),
|
||||
'DEFAULT_FETCH_MODE' => $attr['DEFAULT_FETCH_MODE'],
|
||||
),
|
||||
);
|
||||
|
||||
$this->assertSame($xCast, $cast);
|
||||
}
|
||||
}
|
@@ -1,337 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Tests;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\VarCloner;
|
||||
use Symfony\Component\VarDumper\Dumper\CliDumper;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class CliDumperTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testGet()
|
||||
{
|
||||
require __DIR__.'/Fixtures/dumb-var.php';
|
||||
|
||||
$dumper = new CliDumper('php://output');
|
||||
$dumper->setColors(false);
|
||||
$cloner = new VarCloner();
|
||||
$cloner->addCasters(array(
|
||||
':stream' => function ($res, $a) {
|
||||
unset($a['uri']);
|
||||
|
||||
return $a;
|
||||
},
|
||||
));
|
||||
$data = $cloner->cloneVar($var);
|
||||
|
||||
ob_start();
|
||||
$dumper->dump($data);
|
||||
$out = ob_get_clean();
|
||||
$closureLabel = PHP_VERSION_ID >= 50400 ? 'public method' : 'function';
|
||||
$out = preg_replace('/[ \t]+$/m', '', $out);
|
||||
$intMax = PHP_INT_MAX;
|
||||
$res1 = (int) $var['res'];
|
||||
$res2 = (int) $var[8];
|
||||
|
||||
$this->assertStringMatchesFormat(
|
||||
<<<EOTXT
|
||||
array:25 [
|
||||
"number" => 1
|
||||
0 => &1 null
|
||||
"const" => 1.1
|
||||
1 => true
|
||||
2 => false
|
||||
3 => NAN
|
||||
4 => INF
|
||||
5 => -INF
|
||||
6 => {$intMax}
|
||||
"str" => "déjà"
|
||||
7 => b"é@"
|
||||
"[]" => []
|
||||
"res" => :stream {@{$res1}
|
||||
wrapper_type: "plainfile"
|
||||
stream_type: "STDIO"
|
||||
mode: "r"
|
||||
unread_bytes: 0
|
||||
seekable: true
|
||||
timed_out: false
|
||||
blocked: true
|
||||
eof: false
|
||||
options: []
|
||||
}
|
||||
8 => :Unknown {@{$res2}}
|
||||
"obj" => Symfony\Component\VarDumper\Tests\Fixture\DumbFoo {#%d
|
||||
+foo: "foo"
|
||||
+"bar": "bar"
|
||||
}
|
||||
"closure" => Closure {#%d
|
||||
reflection: """
|
||||
Closure [ <user> {$closureLabel} Symfony\Component\VarDumper\Tests\Fixture\{closure} ] {
|
||||
@@ {$var['file']} {$var['line']} - {$var['line']}
|
||||
|
||||
- Parameters [2] {
|
||||
Parameter #0 [ <required> \$a ]
|
||||
Parameter #1 [ <optional> PDO or NULL &\$b = NULL ]
|
||||
}
|
||||
}
|
||||
"""
|
||||
}
|
||||
"line" => {$var['line']}
|
||||
"nobj" => array:1 [
|
||||
0 => &3 {#%d}
|
||||
]
|
||||
"recurs" => &4 array:1 [
|
||||
0 => &4 array:1 [&4]
|
||||
]
|
||||
9 => &1 null
|
||||
"sobj" => Symfony\Component\VarDumper\Tests\Fixture\DumbFoo {#%d}
|
||||
"snobj" => &3 {#%d}
|
||||
"snobj2" => {#%d}
|
||||
"file" => "{$var['file']}"
|
||||
b"bin-key-é" => ""
|
||||
]
|
||||
|
||||
EOTXT
|
||||
,
|
||||
$out
|
||||
);
|
||||
}
|
||||
|
||||
public function testThrowingCaster()
|
||||
{
|
||||
$out = fopen('php://memory', 'r+b');
|
||||
|
||||
$dumper = new CliDumper();
|
||||
$dumper->setColors(false);
|
||||
$cloner = new VarCloner();
|
||||
$cloner->addCasters(array(
|
||||
':stream' => function () {
|
||||
throw new \Exception('Foobar');
|
||||
},
|
||||
));
|
||||
$line = __LINE__ - 3;
|
||||
$file = __FILE__;
|
||||
$ref = (int) $out;
|
||||
|
||||
$data = $cloner->cloneVar($out);
|
||||
$dumper->dump($data, $out);
|
||||
rewind($out);
|
||||
$out = stream_get_contents($out);
|
||||
|
||||
$this->assertStringMatchesFormat(
|
||||
<<<EOTXT
|
||||
:stream {@{$ref}
|
||||
wrapper_type: "PHP"
|
||||
stream_type: "MEMORY"
|
||||
mode: "w+b"
|
||||
unread_bytes: 0
|
||||
seekable: true
|
||||
uri: "php://memory"
|
||||
timed_out: false
|
||||
blocked: true
|
||||
eof: false
|
||||
options: []
|
||||
⚠: Symfony\Component\VarDumper\Exception\ThrowingCasterException {#%d
|
||||
#message: "Unexpected exception thrown from a caster: Exception"
|
||||
message: "Foobar"
|
||||
trace: array:1 [
|
||||
0 => array:2 [
|
||||
"call" => "%s{closure}()"
|
||||
"file" => "{$file}:{$line}"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
EOTXT
|
||||
,
|
||||
$out
|
||||
);
|
||||
}
|
||||
|
||||
public function testRefsInProperties()
|
||||
{
|
||||
$var = (object) array('foo' => 'foo');
|
||||
$var->bar =& $var->foo;
|
||||
|
||||
$dumper = new CliDumper();
|
||||
$dumper->setColors(false);
|
||||
$cloner = new VarCloner();
|
||||
|
||||
$out = fopen('php://memory', 'r+b');
|
||||
$data = $cloner->cloneVar($var);
|
||||
$dumper->dump($data, $out);
|
||||
rewind($out);
|
||||
$out = stream_get_contents($out);
|
||||
|
||||
$this->assertStringMatchesFormat(
|
||||
<<<EOTXT
|
||||
{#%d
|
||||
+"foo": &1 "foo"
|
||||
+"bar": &1 "foo"
|
||||
}
|
||||
|
||||
EOTXT
|
||||
,
|
||||
$out
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
*/
|
||||
public function testSpecialVars56()
|
||||
{
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
$this->markTestSkipped('PHP 5.6 is required');
|
||||
}
|
||||
|
||||
$var = $this->getSpecialVars();
|
||||
|
||||
$dumper = new CliDumper();
|
||||
$dumper->setColors(false);
|
||||
$cloner = new VarCloner();
|
||||
|
||||
$data = $cloner->cloneVar($var);
|
||||
$out = fopen('php://memory', 'r+b');
|
||||
$dumper->dump($data, $out);
|
||||
rewind($out);
|
||||
$out = stream_get_contents($out);
|
||||
|
||||
$this->assertSame(
|
||||
<<<EOTXT
|
||||
array:3 [
|
||||
0 => array:1 [
|
||||
0 => &1 array:1 [
|
||||
0 => &1 array:1 [&1]
|
||||
]
|
||||
]
|
||||
1 => array:1 [
|
||||
"GLOBALS" => &2 array:1 [
|
||||
"GLOBALS" => &2 array:1 [&2]
|
||||
]
|
||||
]
|
||||
2 => &2 array:1 [&2]
|
||||
]
|
||||
|
||||
EOTXT
|
||||
,
|
||||
$out
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
*/
|
||||
public function testGlobalsNoExt()
|
||||
{
|
||||
$var = $this->getSpecialVars();
|
||||
unset($var[0]);
|
||||
$out = '';
|
||||
|
||||
$dumper = new CliDumper(function ($line, $depth) use (&$out) {
|
||||
if ($depth >= 0) {
|
||||
$out .= str_repeat(' ', $depth).$line."\n";
|
||||
}
|
||||
});
|
||||
$dumper->setColors(false);
|
||||
$cloner = new VarCloner();
|
||||
|
||||
$refl = new \ReflectionProperty($cloner, 'useExt');
|
||||
$refl->setAccessible(true);
|
||||
$refl->setValue($cloner, false);
|
||||
|
||||
$data = $cloner->cloneVar($var);
|
||||
$dumper->dump($data);
|
||||
|
||||
$this->assertSame(
|
||||
<<<EOTXT
|
||||
array:2 [
|
||||
1 => array:1 [
|
||||
"GLOBALS" => &1 array:1 [
|
||||
"GLOBALS" => &1 array:1 [&1]
|
||||
]
|
||||
]
|
||||
2 => &1 array:1 [&1]
|
||||
]
|
||||
|
||||
EOTXT
|
||||
,
|
||||
$out
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
*/
|
||||
public function testBuggyRefs()
|
||||
{
|
||||
if (PHP_VERSION_ID >= 50600) {
|
||||
$this->markTestSkipped('PHP 5.6 fixed refs counting');
|
||||
}
|
||||
|
||||
$var = $this->getSpecialVars();
|
||||
$var = $var[0];
|
||||
|
||||
$dumper = new CliDumper();
|
||||
$dumper->setColors(false);
|
||||
$cloner = new VarCloner();
|
||||
|
||||
$data = $cloner->cloneVar($var)->getLimitedClone(3, -1);
|
||||
$out = '';
|
||||
$dumper->dump($data, function ($line, $depth) use (&$out) {
|
||||
if ($depth >= 0) {
|
||||
$out .= str_repeat(' ', $depth).$line."\n";
|
||||
}
|
||||
});
|
||||
|
||||
$this->assertSame(
|
||||
<<<EOTXT
|
||||
array:1 [
|
||||
0 => array:1 [
|
||||
0 => array:1 [
|
||||
0 => array:1 [
|
||||
…1
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
EOTXT
|
||||
,
|
||||
$out
|
||||
);
|
||||
}
|
||||
|
||||
private function getSpecialVars()
|
||||
{
|
||||
foreach (array_keys($GLOBALS) as $var) {
|
||||
if ('GLOBALS' !== $var) {
|
||||
unset($GLOBALS[$var]);
|
||||
}
|
||||
}
|
||||
|
||||
$var = function &() {
|
||||
$var = array();
|
||||
$var[] =& $var;
|
||||
|
||||
return $var;
|
||||
};
|
||||
|
||||
return array($var(), $GLOBALS, &$GLOBALS);
|
||||
}
|
||||
}
|
@@ -1,43 +0,0 @@
|
||||
<?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\x00",
|
||||
'[]' => 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);
|
@@ -1,146 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Tests;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\VarCloner;
|
||||
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class HtmlDumperTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testGet()
|
||||
{
|
||||
require __DIR__.'/Fixtures/dumb-var.php';
|
||||
|
||||
$dumper = new HtmlDumper('php://output');
|
||||
$dumper->setDumpHeader('<foo></foo>');
|
||||
$dumper->setDumpBoundaries('<bar>', '</bar>');
|
||||
$cloner = new VarCloner();
|
||||
$cloner->addCasters(array(
|
||||
':stream' => function ($res, $a) {
|
||||
unset($a['uri']);
|
||||
|
||||
return $a;
|
||||
},
|
||||
));
|
||||
$data = $cloner->cloneVar($var);
|
||||
|
||||
ob_start();
|
||||
$dumper->dump($data);
|
||||
$out = ob_get_clean();
|
||||
$closureLabel = PHP_VERSION_ID >= 50400 ? 'public method' : 'function';
|
||||
$out = preg_replace('/[ \t]+$/m', '', $out);
|
||||
$var['file'] = htmlspecialchars($var['file'], ENT_QUOTES, 'UTF-8');
|
||||
$intMax = PHP_INT_MAX;
|
||||
preg_match('/sf-dump-\d+/', $out, $dumpId);
|
||||
$dumpId = $dumpId[0];
|
||||
$res1 = (int) $var['res'];
|
||||
$res2 = (int) $var[8];
|
||||
|
||||
$this->assertStringMatchesFormat(
|
||||
<<<EOTXT
|
||||
<foo></foo><bar><span class=sf-dump-note>array:25</span> [<samp>
|
||||
"<span class=sf-dump-key>number</span>" => <span class=sf-dump-num>1</span>
|
||||
<span class=sf-dump-key>0</span> => <a class=sf-dump-ref href=#{$dumpId}-ref01 title="2 occurrences">&1</a> <span class=sf-dump-const>null</span>
|
||||
"<span class=sf-dump-key>const</span>" => <span class=sf-dump-num>1.1</span>
|
||||
<span class=sf-dump-key>1</span> => <span class=sf-dump-const>true</span>
|
||||
<span class=sf-dump-key>2</span> => <span class=sf-dump-const>false</span>
|
||||
<span class=sf-dump-key>3</span> => <span class=sf-dump-num>NAN</span>
|
||||
<span class=sf-dump-key>4</span> => <span class=sf-dump-num>INF</span>
|
||||
<span class=sf-dump-key>5</span> => <span class=sf-dump-num>-INF</span>
|
||||
<span class=sf-dump-key>6</span> => <span class=sf-dump-num>{$intMax}</span>
|
||||
"<span class=sf-dump-key>str</span>" => "<span class=sf-dump-str title="4 characters">déjà</span>"
|
||||
<span class=sf-dump-key>7</span> => b"<span class=sf-dump-str title="2 binary or non-UTF-8 characters">é<span class=sf-dump-cchr title=\\x00>␀</span></span>"
|
||||
"<span class=sf-dump-key>[]</span>" => []
|
||||
"<span class=sf-dump-key>res</span>" => <abbr title="`stream` resource" class=sf-dump-note>:stream</abbr> {<a class=sf-dump-ref>@{$res1}</a><samp>
|
||||
<span class=sf-dump-meta>wrapper_type</span>: "<span class=sf-dump-str title="9 characters">plainfile</span>"
|
||||
<span class=sf-dump-meta>stream_type</span>: "<span class=sf-dump-str title="5 characters">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>
|
||||
<span class=sf-dump-meta>timed_out</span>: <span class=sf-dump-const>false</span>
|
||||
<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>: []
|
||||
</samp>}
|
||||
<span class=sf-dump-key>8</span> => <abbr title="`Unknown` resource" class=sf-dump-note>:Unknown</abbr> {<a class=sf-dump-ref>@{$res2}</a>}
|
||||
"<span class=sf-dump-key>obj</span>" => <abbr title="Symfony\Component\VarDumper\Tests\Fixture\DumbFoo" class=sf-dump-note>DumbFoo</abbr> {<a class=sf-dump-ref href=#{$dumpId}-ref2%d title="2 occurrences">#%d</a><samp id={$dumpId}-ref2%d>
|
||||
+<span class=sf-dump-public title="Public property">foo</span>: "<span class=sf-dump-str title="3 characters">foo</span>"
|
||||
+"<span class=sf-dump-public title="Runtime added dynamic property">bar</span>": "<span class=sf-dump-str title="3 characters">bar</span>"
|
||||
</samp>}
|
||||
"<span class=sf-dump-key>closure</span>" => <span class=sf-dump-note>Closure</span> {<a class=sf-dump-ref>#%d</a><samp>
|
||||
<span class=sf-dump-meta>reflection</span>: """
|
||||
<span class=sf-dump-str title="%d characters">Closure [ <user> {$closureLabel} Symfony\Component\VarDumper\Tests\Fixture\{closure} ] {</span>
|
||||
<span class=sf-dump-str title="%d characters"> @@ {$var['file']} {$var['line']} - {$var['line']}</span>
|
||||
|
||||
<span class=sf-dump-str title="%d characters"> - Parameters [2] {</span>
|
||||
<span class=sf-dump-str title="%d characters"> Parameter #0 [ <required> \$a ]</span>
|
||||
<span class=sf-dump-str title="%d characters"> Parameter #1 [ <optional> PDO or NULL &\$b = NULL ]</span>
|
||||
<span class=sf-dump-str title="%d characters"> }</span>
|
||||
<span class=sf-dump-str title="%d characters">}</span>
|
||||
"""
|
||||
</samp>}
|
||||
"<span class=sf-dump-key>line</span>" => <span class=sf-dump-num>{$var['line']}</span>
|
||||
"<span class=sf-dump-key>nobj</span>" => <span class=sf-dump-note>array:1</span> [<samp>
|
||||
<span class=sf-dump-index>0</span> => <a class=sf-dump-ref href=#{$dumpId}-ref03 title="2 occurrences">&3</a> {<a class=sf-dump-ref href=#{$dumpId}-ref2%d title="3 occurrences">#%d</a>}
|
||||
</samp>]
|
||||
"<span class=sf-dump-key>recurs</span>" => <a class=sf-dump-ref href=#{$dumpId}-ref04 title="2 occurrences">&4</a> <span class=sf-dump-note>array:1</span> [<samp id={$dumpId}-ref04>
|
||||
<span class=sf-dump-index>0</span> => <a class=sf-dump-ref href=#{$dumpId}-ref04 title="2 occurrences">&4</a> <span class=sf-dump-note>array:1</span> [<a class=sf-dump-ref href=#{$dumpId}-ref04 title="2 occurrences">&4</a>]
|
||||
</samp>]
|
||||
<span class=sf-dump-key>9</span> => <a class=sf-dump-ref href=#{$dumpId}-ref01 title="2 occurrences">&1</a> <span class=sf-dump-const>null</span>
|
||||
"<span class=sf-dump-key>sobj</span>" => <abbr title="Symfony\Component\VarDumper\Tests\Fixture\DumbFoo" class=sf-dump-note>DumbFoo</abbr> {<a class=sf-dump-ref href=#{$dumpId}-ref2%d title="2 occurrences">#%d</a>}
|
||||
"<span class=sf-dump-key>snobj</span>" => <a class=sf-dump-ref href=#{$dumpId}-ref03 title="2 occurrences">&3</a> {<a class=sf-dump-ref href=#{$dumpId}-ref2%d title="3 occurrences">#%d</a>}
|
||||
"<span class=sf-dump-key>snobj2</span>" => {<a class=sf-dump-ref href=#{$dumpId}-ref2%d title="3 occurrences">#%d</a>}
|
||||
"<span class=sf-dump-key>file</span>" => "<span class=sf-dump-str title="%d characters">{$var['file']}</span>"
|
||||
b"<span class=sf-dump-key>bin-key-é</span>" => ""
|
||||
</samp>]
|
||||
</bar>
|
||||
|
||||
EOTXT
|
||||
,
|
||||
|
||||
$out
|
||||
);
|
||||
}
|
||||
|
||||
public function testCharset()
|
||||
{
|
||||
if (!extension_loaded('mbstring')) {
|
||||
$this->markTestSkipped('This test requires mbstring.');
|
||||
}
|
||||
$var = mb_convert_encoding('Словарь', 'CP1251', 'UTF-8');
|
||||
|
||||
$dumper = new HtmlDumper('php://output', 'CP1251');
|
||||
$dumper->setDumpHeader('<foo></foo>');
|
||||
$dumper->setDumpBoundaries('<bar>', '</bar>');
|
||||
$cloner = new VarCloner();
|
||||
|
||||
$data = $cloner->cloneVar($var);
|
||||
$out = fopen('php://memory', 'r+b');
|
||||
$dumper->dump($data, $out);
|
||||
rewind($out);
|
||||
$out = stream_get_contents($out);
|
||||
|
||||
$this->assertStringMatchesFormat(
|
||||
<<<EOTXT
|
||||
<foo></foo><bar>b"<span class=sf-dump-str title="7 binary or non-UTF-8 characters">Словарь</span>"
|
||||
</bar>
|
||||
|
||||
EOTXT
|
||||
,
|
||||
|
||||
$out
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,137 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Tests;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\VarCloner;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class VarClonerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testMaxIntBoundary()
|
||||
{
|
||||
$data = array(PHP_INT_MAX => 123);
|
||||
|
||||
$cloner = new VarCloner();
|
||||
$clone = $cloner->cloneVar($data);
|
||||
|
||||
$expected = <<<EOTXT
|
||||
Symfony\Component\VarDumper\Cloner\Data Object
|
||||
(
|
||||
[data:Symfony\Component\VarDumper\Cloner\Data:private] => Array
|
||||
(
|
||||
[0] => Array
|
||||
(
|
||||
[0] => Symfony\Component\VarDumper\Cloner\Stub Object
|
||||
(
|
||||
[type] => array
|
||||
[class] => assoc
|
||||
[value] => 1
|
||||
[cut] => 0
|
||||
[handle] => 0
|
||||
[refCount] => 0
|
||||
[position] => 1
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
[1] => Array
|
||||
(
|
||||
[%s] => 123
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
[maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20
|
||||
[maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1
|
||||
[useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1
|
||||
)
|
||||
|
||||
EOTXT;
|
||||
$this->assertSame(sprintf($expected, PHP_INT_MAX), print_r($clone, true));
|
||||
}
|
||||
|
||||
public function testClone()
|
||||
{
|
||||
$json = json_decode('{"1":{"var":"val"},"2":{"var":"val"}}');
|
||||
|
||||
$cloner = new VarCloner();
|
||||
$clone = $cloner->cloneVar($json);
|
||||
|
||||
$expected = <<<EOTXT
|
||||
Symfony\Component\VarDumper\Cloner\Data Object
|
||||
(
|
||||
[data:Symfony\Component\VarDumper\Cloner\Data:private] => Array
|
||||
(
|
||||
[0] => Array
|
||||
(
|
||||
[0] => Symfony\Component\VarDumper\Cloner\Stub Object
|
||||
(
|
||||
[type] => object
|
||||
[class] => stdClass
|
||||
[value] =>
|
||||
[cut] => 0
|
||||
[handle] => %d
|
||||
[refCount] => 0
|
||||
[position] => 1
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
[1] => Array
|
||||
(
|
||||
[\000+\0001] => Symfony\Component\VarDumper\Cloner\Stub Object
|
||||
(
|
||||
[type] => object
|
||||
[class] => stdClass
|
||||
[value] =>
|
||||
[cut] => 0
|
||||
[handle] => %d
|
||||
[refCount] => 0
|
||||
[position] => 2
|
||||
)
|
||||
|
||||
[\000+\0002] => Symfony\Component\VarDumper\Cloner\Stub Object
|
||||
(
|
||||
[type] => object
|
||||
[class] => stdClass
|
||||
[value] =>
|
||||
[cut] => 0
|
||||
[handle] => %d
|
||||
[refCount] => 0
|
||||
[position] => 3
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
[2] => Array
|
||||
(
|
||||
[\000+\000var] => val
|
||||
)
|
||||
|
||||
[3] => Array
|
||||
(
|
||||
[\000+\000var] => val
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
[maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20
|
||||
[maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1
|
||||
[useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1
|
||||
)
|
||||
|
||||
EOTXT;
|
||||
$this->assertStringMatchesFormat($expected, print_r($clone, true));
|
||||
}
|
||||
}
|
@@ -1,52 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\VarCloner;
|
||||
use Symfony\Component\VarDumper\Dumper\CliDumper;
|
||||
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
|
||||
|
||||
// Load the global dump() function
|
||||
require_once __DIR__.'/Resources/functions/dump.php';
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class VarDumper
|
||||
{
|
||||
private static $handler;
|
||||
|
||||
public static function dump($var)
|
||||
{
|
||||
if (null === self::$handler) {
|
||||
$cloner = new VarCloner();
|
||||
$dumper = 'cli' === PHP_SAPI ? new CliDumper() : new HtmlDumper();
|
||||
self::$handler = function ($var) use ($cloner, $dumper) {
|
||||
$dumper->dump($cloner->cloneVar($var));
|
||||
};
|
||||
}
|
||||
|
||||
return call_user_func(self::$handler, $var);
|
||||
}
|
||||
|
||||
public static function setHandler($callable)
|
||||
{
|
||||
if (null !== $callable && !is_callable($callable, true)) {
|
||||
throw new \InvalidArgumentException('Invalid PHP callback.');
|
||||
}
|
||||
|
||||
$prevHandler = self::$handler;
|
||||
self::$handler = $callable;
|
||||
|
||||
return $prevHandler;
|
||||
}
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"type": "library",
|
||||
"description": "Symfony mechanism for exploring and dumping PHP variables",
|
||||
"keywords": ["dump", "debug"],
|
||||
"homepage": "http://symfony.com",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "~2.7"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-symfony_debug": ""
|
||||
},
|
||||
"autoload": {
|
||||
"files": [ "Resources/functions/dump.php" ],
|
||||
"psr-0": { "Symfony\\Component\\VarDumper\\": "" }
|
||||
},
|
||||
"target-dir": "Symfony/Component/VarDumper",
|
||||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
|
||||
backupGlobals="false"
|
||||
colors="true"
|
||||
bootstrap="vendor/autoload.php"
|
||||
>
|
||||
<php>
|
||||
<ini name="error_reporting" value="-1" />
|
||||
</php>
|
||||
<testsuites>
|
||||
<testsuite name="Symfony VarDumper Component Test Suite">
|
||||
<directory>./Tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./</directory>
|
||||
<exclude>
|
||||
<directory>./Tests</directory>
|
||||
<directory>./Resources</directory>
|
||||
<directory>./vendor</directory>
|
||||
</exclude>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
Reference in New Issue
Block a user