var_export

(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)

var_export输出或返回变量的可解析字符串表示

描述

var_export(混合类型 $value, 布尔值 $return = false): ?字符串

var_export() 获取给定变量的结构化信息。它类似于 var_dump(),只有一个例外:返回的表示是有效的 PHP 代码。

参数

value

要导出的变量。

return

如果使用并设置为 truevar_export() 将返回变量表示,而不是输出它。

返回值

return 参数使用并计算为 true 时,返回变量表示。否则,此函数将返回 null

变更日志

版本 描述
8.2.0 导出的类名现在是完全限定的;之前,省略了开头的反斜杠。
7.3.0 现在将 stdClass 对象导出为数组强制转换为对象 ((object) array( ... )),而不是使用不存在的方法 stdClass::__setState()。实际效果是,现在可以导出 stdClass,并且生成的代码甚至可以在早期版本的 PHP 上运行。

示例

示例 #1 var_export() 示例

<?php
$a
= array (1, 2, array ("a", "b", "c"));
var_export($a);
?>

上面的示例将输出

array (
  0 => 1,
  1 => 2,
  2 => 
  array (
    0 => 'a',
    1 => 'b',
    2 => 'c',
  ),
)
<?php

$b
= 3.1;
$v = var_export($b, true);
echo
$v;

?>

上面的示例将输出

3.1

示例 #2 导出 stdClass (自 PHP 7.3.0 起)

<?php
$person
= new stdClass;
$person->name = 'ElePHPant ElePHPantsdotter';
$person->website = 'https://php.net/elephpant.php';

var_export($person);

上面的示例将输出

(object) array(
   'name' => 'ElePHPant ElePHPantsdotter',
   'website' => 'https://php.net/elephpant.php',
)

示例 #3 导出类

<?php
class A { public $var; }
$a = new A;
$a->var = 5;
var_export($a);
?>

上面的示例将输出

A::__set_state(array(
   'var' => 5,
))

示例 #4 使用 __set_state()

<?php
class A
{
public
$var1;
public
$var2;

public static function
__set_state($an_array)
{
$obj = new A;
$obj->var1 = $an_array['var1'];
$obj->var2 = $an_array['var2'];
return
$obj;
}
}

$a = new A;
$a->var1 = 5;
$a->var2 = 'foo';

eval(
'$b = ' . var_export($a, true) . ';'); // $b = A::__set_state(array(
// 'var1' => 5,
// 'var2' => 'foo',
// ));
var_dump($b);
?>

上面的示例将输出

object(A)#2 (2) {
  ["var1"]=>
  int(5)
  ["var2"]=>
  string(3) "foo"
}

注释

注意:

类型为 资源 的变量无法被此函数导出。

注意:

var_export() 不处理循环引用,因为生成可解析的 PHP 代码几乎不可能。如果您想对数组或对象的完整表示进行操作,请使用 serialize()

警告

在 PHP 8.2.0 之前,当 var_export() 导出对象时,命名空间类的类名中不包含开头的反斜杠,以实现最大兼容性。

注意:

要能够评估由 var_export() 生成的 PHP,所有处理的对象必须实现魔术 __set_state 方法。唯一的例外是 stdClass,它使用数组强制转换为对象进行导出。

参见

添加注释

用户贡献的注释 27 个注释

steven at nevvix dot com
4 年前
我改进了我之前写的 varexport()。

<?php
/**
* 使用短数组语法(方括号)缩进 2 个空格的 PHP var_export()。
*
* 注意:当字符串值包含 `=>\n[`, 它将被转换为 `=> [`
* @link https://php.net/manual/en/function.var-export.php
*/
function varexport($expression, $return=FALSE) {
$export = var_export($expression, TRUE);
$patterns = [
"/array \(/" => '[',
"/^([ ]*)\)(,?)$/m" => '$1]$2',
"/=>[ ]?\n[ ]+\[/" => '=> [',
"/([ ]*)(\'[^\']+\') => ([\[\'])/" => '$1$2 => $3',
];
$export = preg_replace(array_keys($patterns), array_values($patterns), $export);
if ((bool)
$return) return $export; else echo $export;
}

$array = [
'str' => 'Test
spaces'
,
0 => 33,
1 => TRUE,
[
3,4,'d',[]],
'arr' => [
'text with spaces' => '[Tes\'t"s":
=> [
=>
[
{
spaces'
,
],
"str2" => "Test's'
} spaces"
,
'arr2' => [
'text with spaces' => [
'arr3' => [
'text with spaces' => 'Te": "st \' => [
spaces'
,
],
],
],
];
varexport($array);
// 结果:
```
[
'str' => 'Test
spaces',
0 => 33,
1 => true,
2 => [
0 => 3,
1 => 4,
2 => 'd',
3 => [
],
],
'arr' => [
'text with spaces' => '[Tes\'t"s":
=> [
=> [
{
spaces',
],
'str2' => 'Test\'s\'
} spaces',
'arr2' => [
'text with spaces' => [
'arr3' => [
'text with spaces' => 'Te": "st \' => [
spaces',
],
],
],
]
```
注意: 当字符串值包含 `=>\n[`, 它将被转换为 `=> [`
steven at nevvix dot com
6 年前
/**
* 使用方括号缩进 4 个空格的 var_export()。
*/
<?php
function varexport($expression, $return=FALSE) {
$export = var_export($expression, TRUE);
$export = preg_replace("/^([ ]*)(.*)/m", '$1$1$2', $export);
$array = preg_split("/\r\n|\n|\r/", $export);
$array = preg_replace(["/\s*array\s\($/", "/\)(,)?$/", "/\s=>\s$/"], [NULL, ']$1', ' => ['], $array);
$export = join(PHP_EOL, array_filter(["["] + $array));
if ((bool)
$return) return $export; else echo $export;
}
Mark P
8 年前
看起来没有记录,但在 PHP 7 中 `var_export()` 的行为发生了变化。

以前,`var_export(3.)` 返回 "3",现在它返回 "3.0"。
chudinov at yahoo dot com
10 年前
看起来从 5.4.22 版本开始,var_export 使用 serialize_precision ini 设置,而不是用于浮点数正常输出的 precision 设置。
因此,从 5.4.22 版本开始,例如 var_export(1.1) 将输出 1.1000000000000001(17 是默认精度值),而不是之前的 1.1。

<?php
// 输出 1.1000000000000001
var_export(1.1)
?>
4n4jmza02 at sneakemail dot com
14 年前
我通过苦涩的教训得知,如果 var_export 遇到一个资源句柄,它会将其导出为 "NULL",即使它是一个有效的句柄。文档指出句柄无法导出,但没有描述如果您尝试导出会发生什么。

我一直使用 var_export 在一些调试代码中,同时追踪一个资源句柄未生成的问题,最终我以为在问题修复很久后仍然在生成 null 句柄。
dan at coders dot co dot nz
10 年前
我发现我的复杂类型导出时包含
stdClass::__set_state()
在某些地方。这不仅奇怪而且很乱,而且根本无法使用 eval() 重新导入。致命错误!

但是对结果进行快速字符串替换清理使其再次有效。

$macro = var_export($data, TRUE);
$macro = str_replace("stdClass::__set_state", "(object)", $macro);
$macro = '$data = ' . $macro . ';';

现在我输出的字符串 *可以* 再次被评估导入。
laszlo dot heredy at gmail dot com
13 年前
尝试使用此函数来代替 var_export($GLOBALS) 或 var_dump($GLOBALS),当您只想了解在当前页面上设置的变量的值时。

<?php
function globalvars(){
$result=array();
$skip=array('GLOBALS','_ENV','HTTP_ENV_VARS',
'_POST','HTTP_POST_VARS','_GET',
'HTTP_GET_VARS',
'_COOKIE',
'HTTP_COOKIE_VARS','_SERVER',
'HTTP_SERVER_VARS',
'_FILES','HTTP_POST_FILES',
'_REQUEST','HTTP_SESSION_VARS',
'_SESSION');
foreach(
$GLOBALS as $k=>$v)
if(!
in_array($k,$skip))
$result[$k]=$v;
return
$result;
}
//functionglobalvars

var_export(globalvars());
?>
linus at flowingcreativity dot net
19 年前
<roman at DIESPAM dot feather dot org dot ru>,你的函数存在效率低下和问题。我代表所有用户要求你在添加内容到手册之前测试代码。

由于空格问题只在导出数组时出现,因此您可以对所有其他变量类型使用原始的 var_export()。此函数可以完成工作,并且从外部来看,与 var_export() 的工作方式相同。

<?php

function var_export_min($var, $return = false) {
if (
is_array($var)) {
$toImplode = array();
foreach (
$var as $key => $value) {
$toImplode[] = var_export($key, true).'=>'.var_export_min($value, true);
}
$code = 'array('.implode(',', $toImplode).')';
if (
$return) return $code;
else echo
$code;
} else {
return
var_export($var, $return);
}
}

?>
john dot risken at gmail dot com
14 年前
我在用户说明中找不到这个简单的项目。也许是我眼花了!

无论如何,var_export 和 print_r 都使用空格和回车符进行格式化。发送到 HTML 页面后,大多数格式都会丢失。这个简单的函数将格式化的数组打印到 HTML 屏幕上

<?php
function pretty_var($myArray){
print
str_replace(array("\n"," "),array("<br>","&nbsp;"), var_export($myArray,true))."<br>";
}
?>
NitPicker
11 年前
当涉及到 HTML 输出(如下所述)时,一切都很有趣,直到有人用 "<" 戳到他们的眼睛。

用 "<pre>" 包裹它,但请记住也要用 htmlspecialchars() 包裹它。
beverasrilakshmi at gmail dot com
5 年前
仅仅是为了好玩,试着理解 "返回可解析字符串" 的定义......任何传递给 var_export 的变量类型,返回值都将被类型转换为字符串......

<?php

$var
= 1;
var_dump($var); //类型如预期为 int
echo "<br>";
$var_after_export = var_export($var,true); //返回 $var 现在使其成为字符串
var_dump($var_after_export);

?>
Glen
17 年前
正如之前报道的那样,我发现 var_export() 在处理递归结构时令人沮丧。做个

<?php
var_export
($GLOBALS);
?>

失败了。有趣的是,var_dump() 有一些逻辑可以避免递归引用。所以

<?php
var_dump
($GLOBALS);
?>

工作(虽然更难看)。与 var_export() 不同,var_dump() 没有选项返回字符串,因此如果要重定向输出,则需要输出缓冲逻辑。
ravenswd at gmail dot com
15 年前
(这取代了我 2009 年 7 月 3 日的笔记。原始版本如果变量包含空数组或仅包含空数组的数组,则不会产生任何输出。例如,$bigarray['x'] = array(); 另外,我添加了函数的第二个版本。)

当查看具有多个级别和每个级别上多个元素的数组时,输出可能难以理解。例如

<?php
print ('$bigarray = ' . var_export($bigarray, true) . "\n");
?>

将返回

$bigarray = array(
... (跳过 500 行) ...
'mod' => 'charlie',

而下面的例程可以用

<?php
recursive_print
('$bigarray', $bigarray);
?>

调用,它将返回

$bigarray = array()
... (跳过 500 行) ...
$bigarray['foo']['bar']['0']['somethingelse']['mod'] = 'charlie'

这是函数

<?php
function recursive_print ($varname, $varval) {
if (!
is_array($varval)):
print
$varname . ' = ' . $varval . "<br>\n";
else:
print
$varname . " = array()<br>\n";
foreach (
$varval as $key => $val):
recursive_print ($varname . "['" . $key . "']", $val);
endforeach;
endif;
}
?>

对于那些想要产生有效 PHP 代码的版本的人,请使用这个版本

<?php
function recursive_print ($varname, $varval) {
if (!
is_array($varval)):
print
$varname . ' = ' . var_export($varval, true) . ";<br>\n";
else:
print
$varname . " = array();<br>\n";
foreach (
$varval as $key => $val):
recursive_print ($varname . "[" . var_export($key, true) . "]", $val);
endforeach;
endif;
}
?>

如果您的输出是到文本文件而不是 HTML 页面,请删除 <br>。
sergei dot solomonov at gmail dot com
11 年前
<?php
$closure
= function(){};

var_export($closure);

// output: Closure::__set_state(array())
?>
jodybrabec at gmail dot com
12 年前
错误 "嵌套级别太深 - 递归依赖" 的解决方法
ob_start();
var_dump($GLOBALS);
$dataDump = ob_get_clean();
echo $dataDump;
Anonymous
12 年前
在 HTML 页面中,有一个更简单的方法可以从 var_export 和 print_r 获取干净的输出

<?php
function pretty_var($myArray)
{
echo
"<pre>";
var_export($myArray);
echo
"</pre>";
}
?>
stangelanda at arrowquick dot com
17 年前
我一直都在寻找将数据存储在缓存文件中的最佳方法。

首先,我确定了 var_export 与 serialize 的两个限制。它不能存储数组内的内部引用,并且在 PHP 5.1.0 之前,它不能存储嵌套对象或包含对象的数组。

但是,我可以处理这两个问题,所以我创建了一个基准。我使用了一个包含 10 到 150 个索引的单个数组。我使用布尔值、空值、整数、浮点数和一些嵌套数组(嵌套数组更小,平均 5 个元素,但创建方式类似)随机生成元素的值。元素中最大的比例是大约 10-15 个字符的短字符串。虽然有一些长字符串(大约 500 个字符)。

基准测试返回了以下结果:1000 * [总时间] / [迭代次数(在本例中为 4000)]

serialize 3.656、3.575、3.68、3.933,平均值为 3.71
include 7.099、5.42、5.185、6.076,平均值为 5.95
eval 5.514、5.204、5.011、5.788,平均值为 5.38

这意味着 serialize 的速度大约是 var_export 的 1.5 倍,用于单个大型数组。include 和 eval 一直非常接近,但 eval 通常快了几十分之一(eval 在这组特定的试验中比平时表现更好)。像 APC 这样的操作码缓存可能会使 include 速度更快,但除此之外,serialize 是最佳选择。
paul at worldwithoutwalls dot co dot uk
19 年前
对于作为资源的变量,var_export() 与 print_r() 不同,如果您使用该函数进行调试,print_r() 会更有用。
例如
<?php
$res
= mysql_connect($dbhost, $dbuser, $dbpass);
print_r($res); //output: Resource id #14
var_export($res); //output: NULL
?>
php_manual_note at bigredspark dot com
20 年前
[john holmes]
没错,但这种方法需要您打开文件并将文件读入变量,然后将其反序列化到另一个变量中。

使用用 var_export() 创建的文件可以简单地用 include() 包含,这将减少代码量并提高速度。

[kaja]
如果您试图找到一种将变量临时保存到其他文件的方法,请检查 serialize() 和 unserialize() - 这种方法更适合其可读属性,在调试时非常方便。

[原始帖子]
如果您像我一样,您可能想知道为什么一个输出 "正确 PHP 语法" 的函数是有用的。这个函数可以用于实现缓存系统。您可以将数组 var_export() 到一个变量中并将其写入文件。写入像这样的字符串

<?php
$string
= '<?php $array = ' . $data . '; ?>';
?>

其中 $data 是 var_export() 的输出,可以创建一个可以轻松地用 include() 包含回脚本以重新创建 $array 的文件。

var_export() 的原始输出也可以用 eval() 来重新创建数组。

---John Holmes...
rarioj at gmail dot com
14 年前
注意:如果一个对象 Foo 有 __set_state() 方法,但该对象包含另一个没有实现 __set_state() 方法的 Bar 对象,那么生成的 PHP 表达式将无法通过 eval() 执行。

这是一个示例(包含 Exception 实例的 Test 对象)。

<?php

class Test
{
public
$one;
public
$two;
public function
__construct($one, $two)
{
$this->one = $one;
$this->two = $two;
}
public static function
__set_state(array $array)
{
return new
self($array['one'], $array['two']);
}
}

$test = new Test('one', new Exception('test'));

$string = var_export($test, true);

/* $string =
Test::__set_state(array(
'one' => 'one',
'two' =>
Exception::__set_state(array(
'message' => 'test',
'string' => '',
'code' => 0,
'file' => 'E:\\xampp\\htdocs\\test.Q.php',
'line' => 35,
'trace' =>
array (
),
'previous' => NULL,
)),
))
*/

eval('$test2 = '.$string.';'); // 致命错误:调用未定义的方法 Exception::__set_state

?>

因此,避免对包含其他对象的复杂数组/对象使用 var_export()。相反,请使用 serialize() 和 unserialize() 函数。

<?php

$string
= 'unserialize('.var_export(serialize($test), true).')';

eval(
'$test2 = '.$string.';');

var_dump($test == $test2); // bool(true)

?>
wyattstorch42 at outlook dot com
10 年前
如果您对 stdClass 实例调用 var_export(),它会尝试使用 ::__set_state() 来导出它,但出于某种原因,stdClass 中没有实现该方法。

但是,将关联数组强制转换为对象通常会产生相同的效果(至少在我的情况下是这样)。所以我编写了一个 improved_var_export() 函数,将 stdClass 实例转换为 (object) array () 调用。如果您选择导出其他任何类的对象,我建议您实现 ::__set_state()。

<?php
/**
* var_export() 的一个实现,与 stdClass 的实例兼容。
* @param mixed $variable 您要导出的变量
* @param bool $return 如果使用并设置为 true,improved_var_export()
* 将返回变量表示形式,而不是输出它。
* @return mixed|null 当 return 参数使用并评估为 TRUE 时,返回变量表示形式。否则,此
* 函数将返回 NULL。
*/
function improved_var_export ($variable, $return = false) {
if (
$variable instanceof stdClass) {
$result = '(object) '.improved_var_export(get_object_vars($variable), true);
} else if (
is_array($variable)) {
$array = array ();
foreach (
$variable as $key => $value) {
$array[] = var_export($key, true).' => '.improved_var_export($value, true);
}
$result = 'array ('.implode(', ', $array).')';
} else {
$result = var_export($variable, true);
}

if (!
$return) {
print
$result;
return
null;
} else {
return
$result;
}
}

// 示例用法:
$obj = new stdClass;
$obj->test = 'abc';
$obj->other = 6.2;
$obj->arr = array (1, 2, 3);

improved_var_export((object) array (
'prop1' => true,
'prop2' => $obj,
'assocArray' => array (
'apple' => 'good',
'orange' => 'great'
)
));

/* 输出:
(object) array ('prop1' => true, 'prop2' => (object) array ('test' => 'abc', 'other' => 6.2, 'arr' => array (0 => 1, 1 => 2, 2 => 3)), 'assocArray' => array ('apple' => 'good', 'orange' => 'great'))
*/
?>

注意:此函数会输出一行代码,这对于保存在缓存文件中以供包含/评估很有用。它没有为可读性而格式化。如果您想为调试目的打印一个可读的版本,那么我建议您使用 print_r() 或 var_dump()。
ravenswd at gmail dot com
15 年前
当查看具有多个级别和每个级别上多个元素的数组时,输出可能难以理解。例如

<?php
print ('$bigarray = ' . var_export($bigarray, true) . "\n");
?>

将返回

$bigarray = array(
... (跳过 500 行) ...
'mod' => 'charlie',

而下面的例程可以用

<?php
recursive_print
('$bigarray', $bigarray);
?>

调用,它将返回

$bigarray['firstelement'] = 'something'
... (跳过 500 行) ...
$bigarray['foo']['bar']['0']['somethingelse']['mod'] = 'charlie'

这是函数

<?php
function recursive_print ($varname, $varval) {
if (!
is_array($varval)):
print
$varname . ' = ' . $varval . "<br>\n";
else:
foreach (
$varval as $key => $val):
recursive_print ($varname . "['" . $key . "']", $val);
endforeach;
endif;
}
?>
cpmcgrat()uci ! edu
9 年前
当尝试使用 __set_state() 重新构建一个庞大而复杂的类时,请使用以下方法

类 Foo
{
public $a;
public $b;
public $c;
public $d;
public $e;
public $f;
public $g;
public $h;
public $i;

public function __set_state($array)
{
$obj = new ArrayConfig;
foreach($array as $k => $v) {
eval('$obj->'.$k.' = '.$v.';');
}
return $obj;
}
}

这将返回类的重建版本,而无需手动输入类中的每个单独对象(如 __set_state() 示例所示)。
cmusicfan (at) gmail (daught) com
15 年前
小心!var_export 会在单引号 (') 中添加反斜杠。

您可能想要使用 stripslashes() 来删除神秘添加的反斜杠。
Zorro
18 年前
此函数无法导出所有内容。此外,您可能会在简单的递归数组上遇到错误

$test = array();
$test["oops"] = & $test;

echo var_export($test);

=>

致命错误:嵌套级别过深 - 递归依赖?在 ??.php 的第 59 行
kexianbin at diyism dot com
11 年前
要使用 my_var_export(),它和 var_export() 一样漂亮,而且可以像 print_r() 一样处理递归引用。

<?php
function my_var_export($var, $is_str=false)
{
$rtn=preg_replace(array('/Array\s+\(/', '/\[(\d+)\] => (.*)\n/', '/\[([^\d].*)\] => (.*)\n/'), array('array (', '\1 => \'\2\''."\n", '\'\1\' => \'\2\''."\n"), substr(print_r($var, true), 0, -1));
$rtn=strtr($rtn, array("=> 'array ('"=>'=> array ('));
$rtn=strtr($rtn, array(")\n\n"=>")\n"));
$rtn=strtr($rtn, array("'\n"=>"',\n", ")\n"=>"),\n"));
$rtn=preg_replace(array('/\n +/e'), array('strtr(\'\0\', array(\' \'=>\' \'))'), $rtn);
$rtn=strtr($rtn, array(" Object',"=>" Object'<-"));
if (
$is_str)
{return
$rtn;
}
else
{echo
$rtn;
}
}

?>
php dot net at rupert-eibauer dot de
1 年前
警告:如果您在类中有一个私有属性,并且在父类中有一个相同名称的属性,则 var_export 无法创建不同的属性名称。

<?php
class TestParent {
private
$priv = "Parent Private";
protected
$prot = "Parent Protected";
public
$pub = "Parent Public";
}
class
Test extends TestParent {
private
$priv = "Private Info";
protected
$prot = "Protected Info";
public
$pub = "Public Info";
}
$t = new Test;
var_export($t);
Result:
Test::__set_state(array(
'priv' => 'Private Info',
'prot' => 'Protected Info',
'pub' => 'Public Info',
'priv' => 'Parent Private',
))
?>

为了解决这个问题,我创建了自己的 var_export,它也使用更紧凑的格式,并使用 [] 表示数组

<?php
function var_export3($var, $indent = '') {
if (
is_array($var)) {
$indent .= ' ';
$ret = '';
$i = 0;
$is_num = true;
foreach (
$var AS $idx => $value) {
if (
$ret != '')
$ret .= ",\n";
if (
$is_num && $idx === $i) {
$i++;
$ret .= $indent.var_export3($value, $indent);
} else {
$is_num = false;
$ret .= $indent.var_export3($idx).'=>'.var_export3($value, $indent);
}
}
if (
$ret == '')
return
"[]";
return
"[\n".$ret."]";
} else if (
is_bool($var)) {
return
$var ? 'true' : 'false';
} else if (
is_int($var) || is_float($var)) {
return
$var;
} else if (
is_string($var)) {
if (
$var === (string)(float)$var)
return
$var;
return
"'".str_replace(["\0", '\\', '\''], ["\\0", '\\', '\\\''], $var)."'";
} else if (
is_object($var)) {
$class = get_class($var);
if (
$class == 'stdClass') {
$prefix = ;
return
"(object)".var_export3((array)$var, $indent);
} else {
return
"$class::__set_state(".var_export3((array)$var, $indent).')';
}
}
}

echo
var_export3($t)."\n";
Result:
Test::__set_state([
'\0Test\0priv'=>'Private Info',
'\0*\0prot'=>'Protected Info',
'pub'=>'Public Info',
'\0TestParent\0priv'=>'Parent Private'])
?>
请注意,不可打印字符的替换并不完整。
To Top