var_export($data, true) 是导出变量为可执行 php 字符串的最准确方式,保留类型与结构、支持 eval(),但不处理资源和闭包,对象需 __set_state() 才能导出私有属性。

用 var_export() 导出变量为可执行的 PHP 字符串
这是最接近“导出为字符串”且保留类型、结构、可重新 eval() 的方式。它不是简单转成文本,而是生成合法 PHP 代码字符串,比如数组会带 array() 或 [],false 不会变成 "false",而是保持字面量。
常见错误:用 print_r($var, true) 替代——它输出的是人类可读格式(含缩进、省略号、无类型保证),不能直接 eval();而 var_export() 默认返回严格可复原的字符串。
- 加第二个参数
true才返回字符串,否则直接输出:var_export($data, true) - PHP 5.6+ 支持数组字面量语法(
[]),如需兼容老版本,设第三个参数$return = true后手动替换(不推荐) - 遇到资源(resource)、闭包(Closure)会抛出
E_WARNING并返回NULL,必须提前过滤或判断 - 对大数组或深层嵌套对象,性能下降明显,别在循环里无节制调用
为什么不用 serialize()?它和 var_export() 的关键区别
serialize() 产出的是二进制安全字符串,用于存储/传输,不是给人读或调试用的;var_export() 是纯文本、可读、可编辑、可 eval(),但只适用于 PHP 环境内部。
典型误用场景:想把配置数组存成文件供人修改,却用了 serialize() ——结果打开是乱码,改错一个字符就 unserialize() 失败。
立即学习“PHP免费学习笔记(深入)”;
-
serialize()保留对象类名与私有属性,var_export()默认不导出私有/受保护属性(除非手动实现__set_state()) -
unserialize()有反序列化漏洞风险,eval(var_export(...))虽也危险,但至少发生在可控代码段内 -
serialize()兼容跨 PHP 版本,var_export()输出格式在 PHP 7/8 间基本一致,但对象导出行为可能因魔术方法变化而不同
导出对象时私有属性丢失?得靠 __set_state() 配合
默认 var_export() 对对象只输出类名和公有属性,私有/受保护属性全被忽略——这不是 bug,是设计如此。要完整导出,类必须定义静态方法 __set_state()。
例如一个 User 类,若没实现 __set_state(),var_export(new User('Alice')) 可能只返回 User::__set_state(array()),根本没法还原。
-
__set_state()必须是public static,接收一个关联数组参数,返回新实例 - 该方法里要手动重建私有属性,通常用反射或构造函数绕过访问控制
- 如果只是临时调试,更简单的方法是先
get_object_vars()提取公有属性,再var_export()数组
遇到 Notice: Array to string conversion 怎么办
这个错误说明你把数组直接塞进了字符串拼接或 echo,比如 echo "data: " . $arr;。PHP 不会自动调用 var_export() 或 json_encode(),它只会硬转成字符串 "Array",然后报 Notice。
这不是导出问题,是类型误用。修复不是“找一个万能转字符串函数”,而是明确你要什么:
- 要日志调试 → 用
error_log(var_export($arr, true)); - 要前端展示 → 用
json_encode($arr)(注意中文编码、循环引用) - 要存进数据库字段 → 先确认字段类型,
TEXT可存var_export()结果,JSON类型字段则优先用json_encode() - 绝不要
(string) $arr或"" . $arr,那只会得到"Array"
真正麻烦的是嵌套对象里混着资源或闭包——这种变量本质上无法“安全导出”,得先剥离或替换掉不可序列化部分,不然任何函数都会卡住或报错。











