确定任何两个发音相似的PHP函数之间的差异的简单解决方案是在PHP中编写一个快速命令行脚本,该脚本输出整个可能的搜索空间并仅显示差异(在本例中,比较256个值):
<?php
for ($x = 0; $x < 256; $x++)
{
if (chr($x) !== escapeshellcmd(chr($x))) echo $x . " - cmd: " . chr($x) . " != " . escapeshellcmd(chr($x)) . "\n";
}
echo "\n\n";
for ($x = 0; $x < 256; $x++)
{
if (chr($x) !== substr(escapeshellarg(chr($x)), 1, -1)) echo $x . " - arg: " . chr($x) . " != " . substr(escapeshellarg(chr($x)), 1, -1) . "\n";
}
?>
在 Windows 命令提示符输出的 PHP 5.6 下运行上述操作:
0 - cmd: !=
10 - cmd:
!= ^
33 - cmd: ! != ^!
34 - cmd: " != ^"
35 - cmd: # != ^#
36 - cmd: $ != ^$
37 - cmd: % != ^%
38 - cmd: & != ^&
39 - cmd: ' != ^'
40 - cmd: ( != ^(
41 - cmd: ) != ^)
42 - cmd: * != ^*
59 - cmd: ; != ^;
60 - cmd: < != ^<
62 - cmd: > != ^>
63 - cmd: ? != ^?
91 - cmd: [ != ^[
92 - cmd: \ != ^\
93 - cmd: ] != ^]
94 - cmd: ^ != ^^
96 - cmd: ` != ^`
123 - cmd: { != ^{
124 - cmd: | != ^|
125 - cmd: } != ^}
126 - cmd: ~ != ^~
255 - cmd: != ^
0 - arg: !=
33 - arg: ! !=
34 - arg: " !=
37 - arg: % !=
92 - arg: \ != \\
在 PHP 5.5 下为 Linux 输出运行相同的脚本:
0 - cmd: !=
10 - cmd:
!= \
34 - cmd: " != \"
35 - cmd: # != \#
36 - cmd: $ != \$
38 - cmd: & != \&
39 - cmd: ' != \'
40 - cmd: ( != \(
41 - cmd: ) != \)
42 - cmd: * != \*
59 - cmd: ; != \;
60 - cmd: < != \<
62 - cmd: > != \>
63 - cmd: ? != \?
91 - cmd: [ != \[
92 - cmd: \ != \\
93 - cmd: ] != \]
94 - cmd: ^ != \^
96 - cmd: ` != \`
123 - cmd: { != \{
124 - cmd: | != \|
125 - cmd: } != \}
126 - cmd: ~ != \~
128 - cmd: !=
...
255 - cmd: ÿ !=
0 - arg: !=
39 - arg: ' != '\''
128 - arg: !=
...
255 - arg: ÿ !=
主要区别在于,Windows下的PHP escapeshellcmd()将字符与插入符号^而不是反斜杠\前缀。Linux 下从 chr(128) 到 chr(255) 的 escapeshellcmd() 和 escapeshellarg() 的奇怪之处可以通过使用无效的 UTF-8 代码点被删除、截断或误解来解释。
同样值得注意的是,escapeshellarg() 转义的字符要少得多,并且仍然可以完成工作。
就整体系统和应用程序的安全性而言,最好使用 escapeshellarg() 并单独转义由用户输入组成的每个参数。
最后一个例子:
echo escapeshellarg("something here") . "\n";
echo escapeshellarg("'something here'") . "\n";
echo escapeshellarg("\"something here\"") . "\n";
窗口输出:
"something here"
"'something here'"
" something here "
Linux 输出:
'something here'
''\''something here'\'''
'"something here"'
Windows上的PHP escapeshellarg()用双引号“字符包围字符串,而Linux使用单引号”字符。Windows上的PHP完全用空格取代了内部双引号(在某些情况下这可能是一个问题)。Linux上的PHP有点不厌其烦地转义单引号,而反斜杠\在Windows上被转义为\\。Windows 上的 PHP escapeshellarg() 也取代了 !和带空格的 % 字符。所有平台都将 \0 替换为空格。
请注意,PHP版本之间的行为不一定一致,PHP文档并不总是反映现实。编写快速脚本或阅读PHP的源代码是弄清楚幕后发生的事情的两种方法。