对于Tokenizer来说,这听起来像是一份工作!
您可以使用token_get_all从PHP源文件中获取所有已解析的令牌。然后,您可以遍历结果数组,一次评估每个令牌。令牌名称以数字形式返回,您可以使用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
)
)
如您所见,我们的邪恶数组索引是一个T_VARIABLE,后跟一个空心括号,然后是一个没有引号的T_STRING。单引号的索引是T_CONSTANT_ENCAPSED_STRING,引号和全部。
掌握了这些知识之后,您就可以遍历令牌列表并实际重写源代码,以消除所有未引用的数组索引-它们中的大多数应该非常明显。将文件写回时,只需在字符串周围添加单引号即可。
请记住,您将不希望引用任何数字索引,因为这肯定会有不良的副作用。
还请记住,表达式在索引内部是合法的:
$pathological[ some_function(\'Oh gods\', \'why me!?\') . \'4500\' ] = \'Teh bad.\';
您将需要一个很小的小巧的时间,用自动化工具来处理这些问题会更加困难。我的意思是试图处理它们可能会使您陷入致命的愤怒。我建议现在只尝试解决常量/字符串问题。如果做得正确,您应该能够将通知计数降低到更可管理的水平。
(还请注意,令牌生成器将卷曲字符串语法作为实际令牌处理,即10),这应该使那些讨厌的内联数组索引更易于处理。这再次是所有令牌的列表,以防万一您错过了它。)