Skip to content

Commit

Permalink
bug #23465 [HttpKernel][VarDumper] Truncate profiler data & optim per…
Browse files Browse the repository at this point in the history
…f (nicolas-grekas)

This PR was merged into the 3.3 branch.

Discussion
----------

[HttpKernel][VarDumper] Truncate profiler data & optim perf

| Q             | A
| ------------- | ---
| Branch?       | 3.3
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #23415, #21547 and hopefully #23110 and #23175
| License       | MIT
| Doc PR        | -

Commits
-------

754d3a7 [HttpKernel][VarDumper] Truncate profiler data & optim perf
  • Loading branch information
nicolas-grekas committed Jul 11, 2017
2 parents 22b67a4 + 754d3a7 commit 2b3afd2
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 85 deletions.
Expand Up @@ -20,11 +20,7 @@
use Symfony\Component\Validator\ConstraintViolationInterface;
use Symfony\Component\VarDumper\Caster\Caster;
use Symfony\Component\VarDumper\Caster\ClassStub;
use Symfony\Component\VarDumper\Caster\CutStub;
use Symfony\Component\VarDumper\Cloner\ClonerInterface;
use Symfony\Component\VarDumper\Cloner\Data;
use Symfony\Component\VarDumper\Cloner\Stub;
use Symfony\Component\VarDumper\Cloner\VarCloner;

/**
* Data collector for {@link FormInterface} instances.
Expand Down Expand Up @@ -77,11 +73,6 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf
*/
private $valueExporter;

/**
* @var ClonerInterface
*/
private $cloner;

private $hasVarDumper;

public function __construct(FormDataExtractorInterface $dataExtractor)
Expand Down Expand Up @@ -255,61 +246,33 @@ public function serialize()
/**
* {@inheritdoc}
*/
protected function cloneVar($var, $isClass = false)
protected function getCasters()
{
if ($var instanceof Data) {
return $var;
}
if (null === $this->cloner) {
if ($this->hasVarDumper) {
$this->cloner = new VarCloner();
$this->cloner->setMaxItems(-1);
$this->cloner->addCasters(array(
'*' => function ($v, array $a, Stub $s, $isNested) {
foreach ($a as &$v) {
if (is_object($v) && !$v instanceof \DateTimeInterface) {
$v = new CutStub($v);
}
}

return $a;
},
\Exception::class => function (\Exception $e, array $a, Stub $s) {
if (isset($a[$k = "\0Exception\0previous"])) {
unset($a[$k]);
++$s->cut;
}

return $a;
},
FormInterface::class => function (FormInterface $f, array $a) {
return array(
Caster::PREFIX_VIRTUAL.'name' => $f->getName(),
Caster::PREFIX_VIRTUAL.'type_class' => new ClassStub(get_class($f->getConfig()->getType()->getInnerType())),
);
},
ConstraintViolationInterface::class => function (ConstraintViolationInterface $v, array $a) {
return array(
Caster::PREFIX_VIRTUAL.'root' => $v->getRoot(),
Caster::PREFIX_VIRTUAL.'path' => $v->getPropertyPath(),
Caster::PREFIX_VIRTUAL.'value' => $v->getInvalidValue(),
);
},
));
} else {
@trigger_error(sprintf('Using the %s() method without the VarDumper component is deprecated since version 3.2 and won\'t be supported in 4.0. Install symfony/var-dumper version 3.2 or above.', __METHOD__), E_USER_DEPRECATED);
$this->cloner = false;
}
}
if (false !== $this->cloner) {
return $this->cloner->cloneVar($var, Caster::EXCLUDE_VERBOSE);
}

if (null === $this->valueExporter) {
$this->valueExporter = new ValueExporter();
}
return parent::getCasters() + array(
\Exception::class => function (\Exception $e, array $a, Stub $s) {
foreach (array("\0Exception\0previous", "\0Exception\0trace") as $k) {
if (isset($a[$k])) {
unset($a[$k]);
++$s->cut;
}
}

return $this->valueExporter->exportValue($var);
return $a;
},
FormInterface::class => function (FormInterface $f, array $a) {
return array(
Caster::PREFIX_VIRTUAL.'name' => $f->getName(),
Caster::PREFIX_VIRTUAL.'type_class' => new ClassStub(get_class($f->getConfig()->getType()->getInnerType())),
);
},
ConstraintViolationInterface::class => function (ConstraintViolationInterface $v, array $a) {
return array(
Caster::PREFIX_VIRTUAL.'root' => $v->getRoot(),
Caster::PREFIX_VIRTUAL.'path' => $v->getPropertyPath(),
Caster::PREFIX_VIRTUAL.'value' => $v->getInvalidValue(),
);
},
);
}

private function &recursiveBuildPreliminaryFormTree(FormInterface $form, array &$outputByHash)
Expand Down
6 changes: 3 additions & 3 deletions src/Symfony/Component/Form/composer.json
Expand Up @@ -29,7 +29,7 @@
"symfony/dependency-injection": "~3.3",
"symfony/config": "~2.7|~3.0",
"symfony/http-foundation": "~2.8|~3.0",
"symfony/http-kernel": "~2.8|~3.0",
"symfony/http-kernel": "^3.3.5",
"symfony/security-csrf": "~2.8|~3.0",
"symfony/translation": "~2.8|~3.0",
"symfony/var-dumper": "~3.3"
Expand All @@ -39,8 +39,8 @@
"symfony/dependency-injection": "<3.3",
"symfony/doctrine-bridge": "<2.7",
"symfony/framework-bundle": "<2.7",
"symfony/twig-bridge": "<2.7",
"symfony/var-dumper": "<3.3"
"symfony/http-kernel": "<3.3.5",
"symfony/twig-bridge": "<2.7"
},
"suggest": {
"symfony/validator": "For form validation.",
Expand Down
43 changes: 34 additions & 9 deletions src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php
Expand Up @@ -12,9 +12,10 @@
namespace Symfony\Component\HttpKernel\DataCollector;

use Symfony\Component\HttpKernel\DataCollector\Util\ValueExporter;
use Symfony\Component\VarDumper\Caster\ClassStub;
use Symfony\Component\VarDumper\Caster\CutStub;
use Symfony\Component\VarDumper\Cloner\ClonerInterface;
use Symfony\Component\VarDumper\Cloner\Data;
use Symfony\Component\VarDumper\Cloner\Stub;
use Symfony\Component\VarDumper\Cloner\VarCloner;

/**
Expand All @@ -37,7 +38,7 @@ abstract class DataCollector implements DataCollectorInterface, \Serializable
/**
* @var ClonerInterface
*/
private static $cloner;
private $cloner;

public function serialize()
{
Expand All @@ -61,24 +62,28 @@ public function unserialize($data)
*/
protected function cloneVar($var)
{
if (null === self::$cloner) {
if (class_exists(ClassStub::class)) {
self::$cloner = new VarCloner();
self::$cloner->setMaxItems(-1);
if ($var instanceof Data) {
return $var;
}
if (null === $this->cloner) {
if (class_exists(CutStub::class)) {
$this->cloner = new VarCloner();
$this->cloner->setMaxItems(-1);
$this->cloner->addCasters(self::getCasters());
} else {
@trigger_error(sprintf('Using the %s() method without the VarDumper component is deprecated since version 3.2 and won\'t be supported in 4.0. Install symfony/var-dumper version 3.2 or above.', __METHOD__), E_USER_DEPRECATED);
self::$cloner = false;
$this->cloner = false;
}
}
if (false === self::$cloner) {
if (false === $this->cloner) {
if (null === $this->valueExporter) {
$this->valueExporter = new ValueExporter();
}

return $this->valueExporter->exportValue($var);
}

return self::$cloner->cloneVar($var);
return $this->cloner->cloneVar($var);
}

/**
Expand All @@ -100,4 +105,24 @@ protected function varToString($var)

return $this->valueExporter->exportValue($var);
}

/**
* @return callable[] The casters to add to the cloner
*/
protected function getCasters()
{
return array(
'*' => function ($v, array $a, Stub $s, $isNested) {
if (!$v instanceof Stub) {
foreach ($a as $k => $v) {
if (is_object($v) && !$v instanceof \DateTimeInterface && !$v instanceof Stub) {
$a[$k] = new CutStub($v);
}
}
}

return $a;
},
);
}
}
13 changes: 11 additions & 2 deletions src/Symfony/Component/VarDumper/Caster/Caster.php
Expand Up @@ -65,11 +65,20 @@ public static function castObject($obj, $class, $hasDebugInfo = false)
}

if ($a) {
static $publicProperties = array();

$i = 0;
$prefixedKeys = array();
foreach ($a as $k => $v) {
if (isset($k[0]) && "\0" !== $k[0] && !property_exists($class, $k)) {
$prefixedKeys[$i] = self::PREFIX_DYNAMIC.$k;
if (isset($k[0]) && "\0" !== $k[0]) {
if (!isset($publicProperties[$class])) {
foreach (get_class_vars($class) as $prop => $v) {
$publicProperties[$class][$prop] = true;
}
}
if (!isset($publicProperties[$class][$k])) {
$prefixedKeys[$i] = self::PREFIX_DYNAMIC.$k;
}
} elseif (isset($k[16]) && "\0" === $k[16] && 0 === strpos($k, "\0class@anonymous\0")) {
$prefixedKeys[$i] = "\0".get_parent_class($class).'@anonymous'.strrchr($k, "\0");
}
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php
Expand Up @@ -102,7 +102,7 @@ public static function castSilencedErrorContext(SilencedErrorContext $e, array $
}

unset($a[$sPrefix.'file'], $a[$sPrefix.'line'], $a[$sPrefix.'trace']);
$a[Caster::PREFIX_VIRTUAL.'trace'] = new TraceStub($trace);
$a[Caster::PREFIX_VIRTUAL.'trace'] = new TraceStub($trace, self::$traceArgs);

return $a;
}
Expand Down Expand Up @@ -256,7 +256,7 @@ private static function filterExceptionArray($xClass, array $a, $xPrefix, $filte
$trace = array();
}

if (!($filter & Caster::EXCLUDE_VERBOSE)) {
if (!($filter & Caster::EXCLUDE_VERBOSE) && $trace) {
if (isset($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line'])) {
self::traceUnshift($trace, $xClass, $a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line']);
}
Expand Down
16 changes: 9 additions & 7 deletions src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php
Expand Up @@ -209,15 +209,17 @@ public function cloneVar($var, $filter = 0)
});
$this->filter = $filter;

if ($gc = gc_enabled()) {
gc_disable();
}
try {
$data = $this->doClone($var);
} catch (\Exception $e) {
}
restore_error_handler();
$this->prevErrorHandler = null;

if (isset($e)) {
throw $e;
} finally {
if ($gc) {
gc_enable();
}
restore_error_handler();
$this->prevErrorHandler = null;
}

return new Data($data);
Expand Down

0 comments on commit 2b3afd2

Please sign in to comment.