2011-09-05 150 views
0

我正在编写一个应用程序,允许获得批准的开发人员将PHP代码提交给我们的数据库,以便稍后运行。PHP exec()不按预期工作

我试图实现一个系统,在他们的代码运行之前检查是否有任何问题。

我发现下面的代码在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”);没问题。
pint('foo');没问题。
print('foo);没问题。
print('foo','bar');没问题。

我运行的Apache 2.2/5.3.8 PHP安全模式关闭

+0

安装模块可以是初步认识包括mod_suexec和mod_cgi一样。 – Ash

+2

OT:了解'foreach' – cweiske

回答

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"; 
    } 
} 
+0

谢谢Tarek。正是我需要的。非常感激。 – Ash

3

尝试使用PHP -l -r-l标志执行语法检查。如果使用-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仅检查语法错误,并且在运行时无法找到错误。这意味着调用未定义的函数将不会被php -l检测到。

+0

谢谢。不幸的是它仍然不起作用。使用** php -l -r **我可以得到相同的结果,但是使用** php -l **我在所有行上都得到**不正确**。 – Ash

+0

** - r **不需要放置打开和关闭标签。也许你可以尝试自己添加'$ string =“<?php”。 escapeshellcmd($ string)。 “?>”;'并且只是** php -l **? –

+0

感谢卡洛斯 - 仍然没有快乐 - 像以前一样** **不行。对于返回的内容感到好奇,我在'else语句中添加了'print $ exit',我得到** 255 ** – Ash