2

或者更确切地说“修复用作 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;

where user_informationandaccess_bit是字符串,ACCESS_NULL是一个定义的常量。好消息是常量仅以大写形式定义。

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

我想有效地清理这个烂摊子并将所有这些未定义的常量用单引号括起来,但我不确定一个简单的查找/替换(即使使用正则表达式)是否会做到这一点。有什么想法吗?

4

1 回答 1

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]to $user['id']。它留下多维数组,$user[data][id]$user['data'][id]. 我故意不匹配大写键,因为它们很可能是定义的常量。

通过简单地匹配前一个键的右括号,第二个preg_replace适用于所有后续键。

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

PS PHP 标记器在此任务上失败,因为它似乎还将未定义的常量转换为字符串,并且它们被标记为T_STRING.

于 2016-04-20T19:21:19.773 回答