这听起来像是Tokenizer的工作!
您可以使用token_get_all
. 然后,您可以遍历生成的数组,一次评估每个令牌。令牌名称以数字形式返回,您可以使用token_name
.
PHP 交互式提示符下的一个小演示:
php > $str = '<?php echo $face[fire]; echo $face[\'fire\']; ?>';
php > $t = token_get_all($str);
php > foreach($t as $i => $j) { if(is_array($j)) $t[$i][0] = token_name($j[0]); }
这是不同代码块中的输出,因为它有点高,在滚动浏览源字符串时引用它会很好。
php > print_r($t);
Array
(
[0] => Array
(
[0] => T_OPEN_TAG
[1] => <?php
[2] => 1
)
[1] => Array
(
[0] => T_ECHO
[1] => echo
[2] => 1
)
[2] => Array
(
[0] => T_WHITESPACE
[1] =>
[2] => 1
)
[3] => Array
(
[0] => T_VARIABLE
[1] => $face
[2] => 1
)
[4] => [
[5] => Array
(
[0] => T_STRING
[1] => fire
[2] => 1
)
[6] => ]
[7] => ;
[8] => Array
(
[0] => T_WHITESPACE
[1] =>
[2] => 1
)
[9] => Array
(
[0] => T_ECHO
[1] => echo
[2] => 1
)
[10] => Array
(
[0] => T_WHITESPACE
[1] =>
[2] => 1
)
[11] => Array
(
[0] => T_VARIABLE
[1] => $face
[2] => 1
)
[12] => [
[13] => Array
(
[0] => T_CONSTANT_ENCAPSED_STRING
[1] => 'fire'
[2] => 1
)
[14] => ]
[15] => ;
[16] => Array
(
[0] => T_WHITESPACE
[1] =>
[2] => 1
)
[17] => Array
(
[0] => T_CLOSE_TAG
[1] => ?>
[2] => 1
)
)
如您所见,我们的邪恶数组索引是 aT_VARIABLE
后跟一个左括号,然后T_STRING
是未引用的 a。单引号索引来自 as T_CONSTANT_ENCAPSED_STRING
,引号和所有。
掌握了这些知识,您可以浏览标记列表并实际重写源代码以消除所有未引用的数组索引——它们中的大多数应该非常明显。当您写回文件时,您可以简单地在字符串周围添加单引号。
请记住,您不希望引用任何数字索引,因为这肯定会产生不良的副作用。
还要记住,表达式在索引内部是合法的:
$pathological[ some_function('Oh gods', 'why me!?') . '4500' ] = 'Teh bad.';
使用自动化工具处理这些问题会稍微困难一些。我的意思是试图处理它们可能会导致你陷入杀气腾腾的愤怒。我建议现在只尝试修复常量/字符串问题。如果操作正确,您应该能够将通知倒计时降低到更易于管理的水平。
(另请注意,Tokenizer 将卷曲字符串语法作为实际标记处理,T_CURLY_OPEN
——这应该使那些讨厌的内联数组索引更容易处理。这里再次列出所有标记,以防你错过它。)