PHP exec()没有按预期工作

时间:2011-09-05 07:20:19

标签: php

我正在编写一个应用程序,允许经过批准的开发人员将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安全模式关闭

2 个答案:

答案 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";
   }
}