修复不带引号的PHP数组键

时间:2016-04-20 13:10:45

标签: php arrays constants find-replace

或者更确切地说“修复用作PHP数组键的未加引号的字符串”,但标题有点长。

我继承了一个非常大的代码库,其中数组的编写如下:

$array[id] = 0;
$array[value] = "test"

虽然这段代码确实有效,但它会抛出很多Use of undefined constant个通知,所以这些行真的需要成为:

$array['id'] = 0;
$array['value'] = "test"

我们正在谈论成千上万行代码分散到几千个文件中。

还有这样的情况:

$_SESSION[user_information][access_bit][ACCESS_NULL] = 1;

其中user_informationaccess_bit表示字符串,ACCESS_NULL是定义的常量。好处是常量只用大写字母定义。

为了让事情变得更有趣,我们在同一个php文件中也有javascript,其中像array[id] = 0;这样的代码非常好。

我想有效地清理这个混乱并将所有这些未定义的常量包装在单引号中,但我不确定一个简单的查找/替换(即使使用正则表达式)也会这样做。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

事实证明这比我想象的要容易。

function fix_unquoted_array_keys($filename){
    if(!is_file($filename)){
        return "File not found!";
    }
    $content = file_get_contents($filename);
    $content = preg_replace('/^!|\$([a-zA-Z_]+)\[([a-z_]+)\]/','\$$1[\'$2\']',$content);
    $content = preg_replace('/\]\[([a-z_]+)\]/','][\'$1\']',$content);
    file_put_contents($filename,$content);

    // Check the file just in case we break something.
    @exec("php -l ".$filename." 2>&1",$syntax);
    if($syntax[0] && strpos($syntax[0],"No syntax errors") === false){
        return $syntax[0];
    }

    return "OK";
}

第一个preg_replace将所有简单数组替换为$user[id]$user['id']。它会将$user[data][id]等多维数组留给$user['data'][id]。我故意不匹配大写键,因为它们很可能是定义的常量。

第二个preg_replace只需匹配上一个键的右括号即可对所有后续键起作用。

这可能不是最优雅的解决方案,但它似乎完成了这项工作。我现在正在检查最后一小时的差异,我找不到一个失败的地方。

P.S。 PHP tokenizer在此任务上失败,因为它似乎也将未定义的常量转换为字符串,并将它们标记为T_STRING