我正在编写一个应用程序,允许经过批准的开发人员将PHP代码提交到我们的数据库,以便稍后运行。
我正在尝试实施一个系统,在运行代码之前,会检查是否存在任何问题。
我在http://bytes.com/topic/php/answers/4819-before-eval-how-can-one-test-string-see-if-valid-php-code
找到了以下代码function checkPHP($string) {
$string = escapeshellcmd($string);
exec("php -r \"$string\"",$output,$exit);
if($exit==0) return TRUE;
else return FALSE;
}
/* tests */
$test = array ("print ('foo');",
"print (\"foo\");",
"pint ('foo');",
"print ('foo);",
"print ('foo','bar');"
);
for($i=0;$i<sizeof($test);$i++) {
print $test[$i];
if(checkPHP($test[$i])) {
print " is ok.<br />\n";
} else {
print " not ok.<br />\n";
}
}
当我使用它时,我得到:
print('foo');没问题。
print(“foo”);没问题。
品脱('foo');没问题。
print('foo);没问题。
print('foo','bar');没问题。
我正在运行Apache 2.2 / PHP 5.3.8安全模式关闭
答案 0 :(得分:3)
尝试使用 php -l -r 。 -l </ strong>标志执行语法检查。如果您使用-l。
,我不知道是否需要 -r 标志更新:我在命令行中尝试了这个。以下是使用正确语法时的结果:
$ php -l # what I executed
<?php #
print ('foo'); # What I entered
?> #
No syntax errors detected in - # What I got
$ echo $?
0 # exit status
接下来使用不正确的语法:
$ php -l
<?php
print ('foo);
?>
Warning: Unexpected character in input: ''' (ASCII=39) state=1 in - on line 2
No syntax errors detected in -
$ echo $?
0
最后一次尝试:
$ php -l
<?php
kla asd a sss; # after entering this line, the command aborted itself with the
# next message
Parse error: syntax error, unexpected T_STRING in - on line 2
Errors parsing -
$ echo $?
255
第一个和最后一个案例导致我们应该期待什么,但中间案例不是。我希望在这上面有一个!= 0退出状态,但似乎一切正常(显然不是)。所以也许你唯一的选择(我能想到,至少),如果你得到0退出统计数据,解析输出并计算行数,寻找警告或其他一些特定的单词?
另外,请注意 -l </ strong>仅检查语法错误,并且在运行时无法找到错误。这意味着 php -l </ strong>将无法检测到未定义的函数。
答案 1 :(得分:0)
php
命令期望从STDIN
或文件执行代码。 -r标志将在不需要<?php ?>
标记的情况下评估后续内容,但在此之后它仍在等待文件名。
一种解决方案是编写您想要评估的代码,并将其名称传递给php
。这会将您的eval
命令更改为eval ("php $string", $output, $exit);
,其中$ string是要执行(测试)的代码所在的文件名。
您需要确保文件以<?php
开头,以免出错。
这有效
function checkPHP($string) {
$string = escapeshellcmd($string);
exec("php -l $string",$output,$exit);
return ($exit == 0 ? TRUE : FALSE);
}
/* tests */
$test = array ("print ('foo');",
"print (\"foo\");",
"pint ('foo');",
"print ('foo);",
"print ('foo','bar');"
);
foreach ($test as $code){
$fd = fopen('code.dat', 'w');
fwrite($fd, "<?php \n" . $code . "\n ?>\n");
fclose($fd);
print $code;
if(checkPHP("code.dat")) {
print " is ok.<br />\n";
} else {
print " not ok.<br />\n";
}
}