如何将var_export格式化为PHP5.4数组语法

31

有很多问题和答案涉及从变量输出中获取有效的php语法,我想要的是一种快速而清晰的方法来获取var_export的输出并使用有效的php5.4数组语法。

鉴于以上情况

$arr = [
    'key' => 'value',
    'mushroom' => [
        'badger' => 1
    ]
];


var_export($arr);

输出

array (
  'key' => 'value',
  'mushroom' => 
  array (
    'badger' => 1,
  ),
)
有没有快速简单的方法,可以按照定义输出这个数组,使用方括号语法?
[
    'key' => 'value',
    'mushroom' => [
        'badger' => 1
    ]
]

普遍共识是使用正则表达式解析吗?如果是,有没有人找到一个不错的正则表达式?我将使用的数组的值级内容都是scalararray,没有对象或类。


1
你真的不能回到源代码而不使用 var_export 吗? - user557846
4
你知道那句古老的中国谚语:“如果你不喜欢默认的 var_export 语法,就写一个自己的。” - mario
嗯,这就是我所要求的... 我真的不知道该从哪里开始 ;) - designermonkey
但是你真的需要编写这种非标准格式吗?为什么要支持一种非标准的配置格式,而你必须本质上编写自己的解析器呢? - Mike Brant
我想这是可以理解的,但对于用户来说,使用JSON而不是配置文件真的有那么难吗?本质上,你所要做的就是将[]改为{}=>改为:'改为" - Mike Brant
显示剩余5条评论
5个回答

37

我有类似的东西放在旁边。

function var_export54($var, $indent="") {
    switch (gettype($var)) {
        case "string":
            return '"' . addcslashes($var, "\\\$\"\r\n\t\v\f") . '"';
        case "array":
            $indexed = array_keys($var) === range(0, count($var) - 1);
            $r = [];
            foreach ($var as $key => $value) {
                $r[] = "$indent    "
                     . ($indexed ? "" : var_export54($key) . " => ")
                     . var_export54($value, "$indent    ");
            }
            return "[\n" . implode(",\n", $r) . "\n" . $indent . "]";
        case "boolean":
            return $var ? "TRUE" : "FALSE";
        default:
            return var_export($var, TRUE);
    }
}

这并不是非常美观,但对于您的情况可能足够。

除了指定类型之外的任何类型都由常规的var_export处理。因此,对于单引号字符串,只需注释掉string的情况即可。


我喜欢这个。不知道是否有任何方法可以使其仅输出像 var_export 一样,而不仅仅是字符串。虽然这不是必须的,因为这正是我想要的,但找到这个方法会很有趣。 - designermonkey
只需要自己使用 echo 命令输出结果即可。 - mario
我正要发表同样的评论,但是在发布后意识到了。非常感谢! - designermonkey
这只是破坏了我的数据,并在最左边的列上放了很多1。 - Felix Eve
1
为了防止通过 var_export($var, TRUE); 返回不正确的值,添加以下代码: case 'integer': case 'double': return $var; - vee

20

对于任何寻求更现代解决方案的人,使用Symfony变量导出器,它也可作为一个独立的库在Composer上使用,但在Symfony中默认包括。

composer require symfony/var-exporter
use Symfony\Component\VarExporter\VarExporter;

// ...

echo VarExporter::export($arr)

完美的答案! - Hossein

12

我知道这个问题很古老,但是我的搜索结果就指向了这里。我并不想使用完整的迭代或者 json_decode,所以这里有一个基于 preg_replacevar_export 替换器可以完成工作。

function var_export_short($data, $return=true)
{
    $dump = var_export($data, true);

    $dump = preg_replace('#(?:\A|\n)([ ]*)array \(#i', '[', $dump); // Starts
    $dump = preg_replace('#\n([ ]*)\),#', "\n$1],", $dump); // Ends
    $dump = preg_replace('#=> \[\n\s+\],\n#', "=> [],\n", $dump); // Empties

    if (gettype($data) == 'object') { // Deal with object states
        $dump = str_replace('__set_state(array(', '__set_state([', $dump);
        $dump = preg_replace('#\)\)$#', "])", $dump);
    } else { 
        $dump = preg_replace('#\)$#', "]", $dump);
    }

    if ($return===true) {
        return $dump;
    } else {
        echo $dump;
    }
}

我已经在几个数组和对象上进行了测试。虽然并不是全面的测试,但它似乎工作得很好。我还通过压缩额外的换行符和空数组使输出更紧凑。如果您在使用此代码时遇到任何意外的数据损坏,请让我知道。我还没有与上述解决方案进行基准测试,但我认为它会快得多。享受阅读您的数组!


免责声明:如果在不同的PHP版本或平台上,var_export输出格式存在差异,那么这可能会导致一些问题。我无法找到任何相关信息,因此我认为不存在这种情况。在W7x64上测试通过了PHP 5.6.2和7.0.2。 - Markus AO
嵌套数组方面表现良好,感谢分享。 - Mahn

12

使用https://github.com/zendframework/zend-code

<?php
use Zend\Code\Generator\ValueGenerator;
$generator = new ValueGenerator($myArray, ValueGenerator::TYPE_ARRAY_SHORT);
$generator->setIndentation('  '); // 2 spaces
echo $generator->generate();

2

正如评论所指出的那样,这只是一种附加语法。如果键或值中没有 ),则使用 str_replacevar_export 转换回括号样式非常有效。但是,使用 JSON 作为中介仍然很简单:

$output = json_decode(str_replace(array('(',')'), array('&#40','&#41'), json_encode($arr)), true);
$output = var_export($output, true);
$output = str_replace(array('array (',')','&#40','&#41'), array('[',']','(',')'), $output);

我使用了HTML实体来表示()。您可以使用转义序列或其他方式。

4
这个解决方法似乎有些不稳定,因为它也会在字符串环境中替换普通的 ) 括号。 - mario
1
我喜欢这种简单的方式,可能会用它来开始,但我已经知道,正如“草率法则”所述,有人会在他们的字符串中添加 ) - designermonkey
1
同意。用一个简单的解决方案进行了编辑。 - AbraCadaver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接