PHP Conference Japan 2024

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,它使用转换为对象的数组导出。

参见

添加注释

用户贡献的注释 21 条注释

steven at nevvix dot com
5 年前
我改进了我之前的 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 年前
虽然没有记录在案,但 `var_export()` 的行为在 PHP 7 中发生了变化。

以前,`var_export(3.)` 返回 "3",现在它返回 "3.0"。
chudinov at yahoo dot com
11 年前
看起来从 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 来跟踪资源句柄未生成的问题,结果却错误地认为在问题解决很久之后仍然生成了空句柄。
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
14 年前
当您只想了解在当前页面上设置的变量的值时,请尝试使用此函数代替 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);
}
}

?>
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);

?>
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>";
}
?>
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
12 年前
<?php
$closure
= function(){};

var_export($closure);

// 输出:Closure::__set_state(array())
?>
jodybrabec at gmail dot com
12 年前
针对错误“嵌套级别过深 - 递归依赖”的解决方法
ob_start();
var_dump($GLOBALS);
$dataDump = ob_get_clean();
echo $dataDump;
Anonymous
13 年前
在 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
20 年前
对于作为资源的变量,var_export() 与 print_r() 不同,如果将该函数用于调试目的,则 print_r() 更有用。
例如
<?php
$res
= mysql_connect($dbhost, $dbuser, $dbpass);
print_r($res); //输出:Resource id #14
var_export($res); //输出:NULL
?>
me at peterkooi dot com
28 天前
一个用于将变量导出为字符串的小函数,支持嵌套数组,具有缩进输出、块引用和双引号,可以粘贴回代码中。



<?php
function dump($value) {
function
_dump($value, $indent = 0) {
if (!
is_array($value)) return json_encode($value, JSON_NUMERIC_CHECK);
foreach(
$value as $key => $item) $result .= (ifset($result) ? ",\r\n" . str_repeat(" ", $indent + 2) : "") . json_encode($key) . " => " . _dump($item, $indent + 2);
return
"[\r\n" . str_repeat(" ", $indent + 2) . "$result\r\n" . str_repeat(" ", $indent) . "]";
}
return
"<pre>" . htmlspecialchars(_dump($value)) . "</pre>";
}
[email protected]
21 年前
[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...
[email protected]
15 年前
注意:如果对象 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)

?>
To Top