Reputation: 1
I'm writing an application that will allow approved developers to submit php code to our database to be run at a later time.
I'm attempting to implement a system where before their code is run it is checked for any issues.
I found the following code at 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";
}
}
When I use it I get:
print ('foo'); is ok.
print ("foo"); is ok.
pint ('foo'); is ok.
print ('foo); is ok.
print ('foo','bar'); is ok.
I'm running Apache 2.2 / PHP 5.3.8 Safe Mode off
Upvotes: 0
Views: 565
Reputation: 23002
Try using php -l -r. The -l flag performs a syntax check. I don't know if the -r flag is necessary if you use -l.
update: I tried this in the command line. Here's what I got when using correct syntax:
$ php -l # what I executed
<?php #
print ('foo'); # What I entered
?> #
No syntax errors detected in - # What I got
$ echo $?
0 # exit status
And the next using incorrect syntax:
$ 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
And one last try:
$ 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
First and last case result in what we should expect, but the middle case is not. I would expect a != 0 exit status on this, but it seems that everything is ok (which clearly is not). So maybe your only option (that I can think of, at least) is, if you get 0 exit stats, parse the output and count the number of lines, look for warning or some other specific words?
Also, take note that -l only checks for syntax error, and cannot find errors at runtime. This means that calling an undefined function will be undetected by php -l.
Upvotes: 3
Reputation: 1959
The php
command expects to execute code from either STDIN
or a file. The -r flag will evaluate what follows without the need for the <?php ?>
tags, however it's still waiting for a filename after that.
One solution is to write the code you want evaluated and pass its name to php
. That'd change your eval
command to eval ("php $string", $output, $exit);
where $string is the filename where the code to be executed (tested) resides.
You will need to make sure that the file begins with <?php
so as not to get an error.
This works
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";
}
}
Upvotes: 0