将php数组代码写入文件而不评估表达式

时间:2015-07-15 14:10:39

标签: php arrays

我试图编写一些代码来生成带有数组的{php}文件{。3}}。

但是,为了创建正确的配置文件,我需要能够保留表达式'在数组内。这是因为该文件将被许多用户使用,并且表达式基于用户已设置的环境变量等进行评估。

所以,假设我们在数组中有这个键/值,我最终想要输出到文件中:

[
    ...
    'connection' => $isFork ? $sourceArray['connection'] : config('database.default'),
    ...
]

当这个数组最终被写入php文件时(现在使用var_exportfile_put_contents)我会看到

'connection' => config('database.default')

成为

'connection' => 'default_connection',

因为表达式已被评估。我需要的是一种方法来防止表达式作为数组中的值被评估确保

'connection' => $isFork ? $sourceArray['connection']

评估为

'connection' => 'my_connection'

有没有办法做到这一点?

编辑:我基本上想做like this,但反过来和表达式。

2 个答案:

答案 0 :(得分:1)

使用var_export无法做到这一点。我能看到这样做的最好方法是创建输出字符串并使用file_put_contents将其输出到文件。

这可以通过复制数组结构来实现,例如

$arr_str = "[\n";
         . "\t'simple_annotations' => false,\n"
         . "];";

或者通过创建一个帮助函数来代替var_export。像这样:

function var_str($var, $level = 0){
    if(is_array($var)) return arr_str($var, $level+1);
    elseif(is_string($var)) return '\''.$var.'\'';
    elseif(is_numeric($var)) return $var;
    elseif(is_null($var)) return 'null';
    elseif(is_bool($var)) return ($var ? 'true' : 'false');
}

function arr_str($arr, $level){
    $str = "[\n";
    foreach($arr as $k => $e){
        $str .= str_repeat("\t", $level);
        $str .= "'".$k."' => ".var_str($e, $level).",\n";
    }
    return $str.str_repeat("\t", $level-1).']';
}

print var_str($my_array);

答案 1 :(得分:0)

在搜索了几个小时后,我得出结论,完全控制我想做的事情的唯一方法是使用模板引擎。

此项目适用于Laravel,因此我使用了Blade,但任何引擎都可以使用(我最初使用Twig进行了尝试。)

我写了我的配置的每个部分,好像它是一个常规的php数组,然后使用Blade包围来包含为每个键找到正确值所需的逻辑。如果值不是表达式,我会评估代码,如果是,我将表达式写入字符串。

我最终得到了这个:

//example.blade.php

[
    'meta' => '{{{ $isFork ? $data['metadata']['driver'] : 'annotations' }}}',
    'connection' => {{{ $isFork ? '\''.$data['connection'].'\'' : 'config("database.default")'  }}},
    'paths' => {{ var_export(ArrayUtil::get($data['metadata']['paths'], $data['metadata']), true) }},
    'repository' => '{{{ ArrayUtil::get($data['repository'], EntityRepository::class) }}}',
    'proxies' => [
        'namespace' => {{{ isset($data['proxy']['namespace']) ? '\'' . $data['proxy']['namespace'] .'\'' : 'false' }}},
        'path'          => '{{{ ArrayUtil::get($data['proxy']['directory'], storage_path('proxies')) }}}',
        'auto_generate' => {{{ ArrayUtil::get($data['proxy']['auto_generate'], env('DOCTRINE_PROXY_AUTOGENERATE', 'false')) }}}
    ],
    'events'     => [
        'listeners'   => [],
        'subscribers' => []
    ],
    'filters' => []
]

和输出:

[
            'meta' => 'yaml',
            'connection' => config('database.default'),
            'paths' => array(
                0 => '/proj/app/Models/mappings',
            ),
            'repository' => 'Doctrine\ORM\EntityRepository',
            'proxies' => [
                'namespace' => false,
                'path' => '/proj/storage/proxies',
                'auto_generate' => false
            ],
            'events' => [
                'listeners' => [],
                'subscribers' => []
            ],
            'filters' => []
]

您可以看到我可能需要扩展数组的位置var_export。除了它非常直接。