123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- <?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\VarExporter;
- use Symfony\Component\VarExporter\Exception\ExceptionInterface;
- use Symfony\Component\VarExporter\Internal\Exporter;
- use Symfony\Component\VarExporter\Internal\Hydrator;
- use Symfony\Component\VarExporter\Internal\Registry;
- use Symfony\Component\VarExporter\Internal\Values;
- /**
- * Exports serializable PHP values to PHP code.
- *
- * VarExporter allows serializing PHP data structures to plain PHP code (like var_export())
- * while preserving all the semantics associated with serialize() (unlike var_export()).
- *
- * By leveraging OPcache, the generated PHP code is faster than doing the same with unserialize().
- *
- * @author Nicolas Grekas <p@tchwork.com>
- */
- final class VarExporter
- {
- /**
- * Exports a serializable PHP value to PHP code.
- *
- * @param mixed $value The value to export
- * @param bool &$isStaticValue Set to true after execution if the provided value is static, false otherwise
- * @param array &$foundClasses Classes found in the value are added to this list as both keys and values
- *
- * @throws ExceptionInterface When the provided value cannot be serialized
- */
- public static function export($value, ?bool &$isStaticValue = null, array &$foundClasses = []): string
- {
- $isStaticValue = true;
- if (!\is_object($value) && !(\is_array($value) && $value) && !\is_resource($value) || $value instanceof \UnitEnum) {
- return Exporter::export($value);
- }
- $objectsPool = new \SplObjectStorage();
- $refsPool = [];
- $objectsCount = 0;
- try {
- $value = Exporter::prepare([$value], $objectsPool, $refsPool, $objectsCount, $isStaticValue)[0];
- } finally {
- $references = [];
- foreach ($refsPool as $i => $v) {
- if ($v[0]->count) {
- $references[1 + $i] = $v[2];
- }
- $v[0] = $v[1];
- }
- }
- if ($isStaticValue) {
- return Exporter::export($value);
- }
- $classes = [];
- $values = [];
- $states = [];
- foreach ($objectsPool as $i => $v) {
- [, $class, $values[], $wakeup] = $objectsPool[$v];
- $foundClasses[$class] = $classes[] = $class;
- if (0 < $wakeup) {
- $states[$wakeup] = $i;
- } elseif (0 > $wakeup) {
- $states[-$wakeup] = [$i, array_pop($values)];
- $values[] = [];
- }
- }
- ksort($states);
- $wakeups = [null];
- foreach ($states as $v) {
- if (\is_array($v)) {
- $wakeups[-$v[0]] = $v[1];
- } else {
- $wakeups[] = $v;
- }
- }
- if (null === $wakeups[0]) {
- unset($wakeups[0]);
- }
- $properties = [];
- foreach ($values as $i => $vars) {
- foreach ($vars as $class => $values) {
- foreach ($values as $name => $v) {
- $properties[$class][$name][$i] = $v;
- }
- }
- }
- if ($classes || $references) {
- $value = new Hydrator(new Registry($classes), $references ? new Values($references) : null, $properties, $value, $wakeups);
- } else {
- $isStaticValue = true;
- }
- return Exporter::export($value);
- }
- }
|