Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
CRAP
100.00% covered (success)
100.00%
43 / 43
VarExporter
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
21
100.00% covered (success)
100.00%
43 / 43
 export
100.00% covered (success)
100.00%
1 / 1
21
100.00% covered (success)
100.00%
43 / 43
1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\VarExporter;
13
14use Symfony\Component\VarExporter\Exception\ExceptionInterface;
15use Symfony\Component\VarExporter\Internal\Exporter;
16use Symfony\Component\VarExporter\Internal\Hydrator;
17use Symfony\Component\VarExporter\Internal\Registry;
18use Symfony\Component\VarExporter\Internal\Values;
19
20/**
21 * Exports serializable PHP values to PHP code.
22 *
23 * VarExporter allows serializing PHP data structures to plain PHP code (like var_export())
24 * while preserving all the semantics associated with serialize() (unlike var_export()).
25 *
26 * By leveraging OPcache, the generated PHP code is faster than doing the same with unserialize().
27 *
28 * @author Nicolas Grekas <p@tchwork.com>
29 */
30final class VarExporter
31{
32    /**
33     * Exports a serializable PHP value to PHP code.
34     *
35     * @param mixed $value          The value to export
36     * @param bool  &$isStaticValue Set to true after execution if the provided value is static, false otherwise
37     * @param bool  &$classes       Classes found in the value are added to this list as both keys and values
38     *
39     * @return string The value exported as PHP code
40     *
41     * @throws ExceptionInterface When the provided value cannot be serialized
42     */
43    public static function export($value, bool &$isStaticValue = null, array &$foundClasses = []): string
44    {
45        $isStaticValue = true;
46
47        if (!\is_object($value) && !(\is_array($value) && $value) && !$value instanceof \__PHP_Incomplete_Class && !\is_resource($value)) {
48            return Exporter::export($value);
49        }
50
51        $objectsPool = new \SplObjectStorage();
52        $refsPool = [];
53        $objectsCount = 0;
54
55        try {
56            $value = Exporter::prepare([$value], $objectsPool, $refsPool, $objectsCount, $isStaticValue)[0];
57        } finally {
58            $references = [];
59            foreach ($refsPool as $i => $v) {
60                if ($v[0]->count) {
61                    $references[1 + $i] = $v[2];
62                }
63                $v[0] = $v[1];
64            }
65        }
66
67        if ($isStaticValue) {
68            return Exporter::export($value);
69        }
70
71        $classes = [];
72        $values = [];
73        $states = [];
74        foreach ($objectsPool as $i => $v) {
75            [, $class, $values[], $wakeup] = $objectsPool[$v];
76            $foundClasses[$class] = $classes[] = $class;
77
78            if (0 < $wakeup) {
79                $states[$wakeup] = $i;
80            } elseif (0 > $wakeup) {
81                $states[-$wakeup] = [$i, array_pop($values)];
82                $values[] = [];
83            }
84        }
85        ksort($states);
86
87        $wakeups = [null];
88        foreach ($states as $k => $v) {
89            if (\is_array($v)) {
90                $wakeups[-$v[0]] = $v[1];
91            } else {
92                $wakeups[] = $v;
93            }
94        }
95
96        if (null === $wakeups[0]) {
97            unset($wakeups[0]);
98        }
99
100        $properties = [];
101        foreach ($values as $i => $vars) {
102            foreach ($vars as $class => $values) {
103                foreach ($values as $name => $v) {
104                    $properties[$class][$name][$i] = $v;
105                }
106            }
107        }
108
109        if ($classes || $references) {
110            $value = new Hydrator(new Registry($classes), $references ? new Values($references) : null, $properties, $value, $wakeups);
111        } else {
112            $isStaticValue = true;
113        }
114
115        return Exporter::export($value);
116    }
117}