Contributed by
Nicolas Grekas
in #28231.

在 Symfony 程序中,VarDumper组件 提供了一个 dump() 功能,作为PHP原生 var_dump() 函数的替代。在 Symfony 4.2 中我们引入了全新的 VarExporter 组件,提供的是针对 PHP 原生 var_export() 函数的替代。

var_export() 函数输出或返回一个某变量的可解析的字符串描述。这很像 var_dump(),只有一处例外: 返回的描述信息是有效的PHP代码。Symfony的 export() 函数与之类似,但对其添加了许多有用功能。

思考下例,一个简单的数组被导出:

1
2
$data = array(123, array('abc'));
$result = VarExporter::export($data);

此输出与你预期的使用了 var_export() 的输出相类似,尽管 export() 生成了有效的并且兼容 PSR-2 的PHP代码:

1
2
3
4
5
6
7
8
<?php
 
return [
    123,
    [
        'abc',
    ],
];

主要的区别在于 export() 并不像 var_export() 那样保存了全部的同php的序列化架构(__wakeup, __sleep, Serializable)相关联的语义。思考下例,一个类实现了 Serializable 接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class MySerializable implements \Serializable
{
    public function serialize()
    {
        return '123';
    }
 
    public function unserialize($data)
    {
        // do nothing / 什么也不做
    }
}
 
$data = array(new MySerializable(), new MySerializable());
$result = VarExporter::export($data);

结果应该是下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
 
return \Symfony\Component\VarExporter\Internal\Configurator::pop(
    \Symfony\Component\VarExporter\Internal\Registry::push([], [], [
        'C:50:"Symfony\\Component\\VarExporter\\Tests\\MySerializable":3:{123}',
    ]),
    null,
    [],
    [
        \Symfony\Component\VarExporter\Internal\Registry::$objects[0],
        \Symfony\Component\VarExporter\Internal\Registry::$objects[0],
    ],
    []
);

除了产生更好的结果之外,如果你的程序使用了OPcache,Symfony的 export() 函数相对于 serialize() 甚至 igbinary 来说将会变得 更快、更省内存

最后,Symfony的 export() 相对于 var_export()serialize() 还增加了其他改进点:

  • 生成的输出,可以重新缩进,而不被数据中的 \r\n 所搞乱;

  • 缺少的类将抛出一个 ReflectionException,而不是被反序列化到 PHP_Incomplete_Class 对象;

  • 包含了 SplObjectStorage, ArrayObjectArrayIterator

    实例的引用将被保存;

  • Reflection*, IteratorIteratorRecursiveIteratorIterator

    在序列化时抛出一个异常。