note 87762 added to function.php-check-syntax
| From: | kevin at metalaxe dot com | Date: | Sat, 20 Dec 2008 00:37:58 +0000 |
| Subject: | note 87762 added to function.php-check-syntax | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-148375@lists.php.net to get a copy of this message | ||
I've given it some thought and rewritten my function to take full advantage of the CLI -l
option (that's lower L). It requires that you enable error reporting via your own php.ini file
(which you should edit the function to apply) otherwise the return result is a worthless "Error
parsing".
Anyway, I hope this is useful for someone. I'm sure it could use improvement, so use at your
own risk. Demo here:
http://kevinpeno.com/projects/php_syntax_check.php
<?php
/**
* Check Syntax
* Performs a Syntax check within a php script, without killing the parser (hopefully)
* Do not use this with PHP 5 <= PHP 5.0.4, or rename this function.
*
* @params string PHP to be evaluated
* @return array Parse error info or true for success
**/
function php_check_syntax( $php, $isFile=false )
{
# Get the string tokens
$tokens = token_get_all( '<?php '.trim( $php ));
# Drop our manually entered opening tag
array_shift( $tokens );
token_fix( $tokens );
# Check to see how we need to proceed
# prepare the string for parsing
if( isset( $tokens[0][0] ) && $tokens[0][0] === T_OPEN_TAG )
$evalStr = $php;
else
$evalStr = "<?php\n{$php}?>";
if( $isFile OR ( $tf = tempnam( NULL, 'parse-' ) AND file_put_contents( $tf, $php ) !==
FALSE ) AND $tf = $php )
{
# Prevent output
ob_start();
system( 'C:\inetpub\PHP\5.2.6\php -c "'.dirname(__FILE__).'/php.ini" -l
< '.$php, $ret );
$output = ob_get_clean();
if( $ret !== 0 )
{
# Parse error to report?
if( (bool)preg_match( '/Parse error:\s*syntax error,(.+?)\s+in\s+.+?\s*line\s+(\d+)/',
$output, $match ) )
{
return array(
'line' => (int)$match[2],
'msg' => $match[1]
);
}
}
return true;
}
return false;
}
//fixes related bugs: 29761, 34782 => token_get_all returns <?php NOT as T_OPEN_TAG
function token_fix( &$tokens ) {
if (!is_array($tokens) || (count($tokens)<2)) {
return;
}
//return of no fixing needed
if (is_array($tokens[0]) && (($tokens[0][0]==T_OPEN_TAG) ||
($tokens[0][0]==T_OPEN_TAG_WITH_ECHO)) ) {
return;
}
//continue
$p1 = (is_array($tokens[0])?$tokens[0][1]:$tokens[0]);
$p2 = (is_array($tokens[1])?$tokens[1][1]:$tokens[1]);
$p3 = '';
if (($p1.$p2 == '<?') || ($p1.$p2 == '<%')) {
$type = ($p2=='?')?T_OPEN_TAG:T_OPEN_TAG_WITH_ECHO;
$del = 2;
//update token type for 3rd part?
if (count($tokens)>2) {
$p3 = is_array($tokens[2])?$tokens[2][1]:$tokens[2];
$del = (($p3=='php') || ($p3=='='))?3:2;
$type = ($p3=='=')?T_OPEN_TAG_WITH_ECHO:$type;
}
//rebuild erroneous token
$temp = array($type, $p1.$p2.$p3);
if (version_compare(phpversion(), '5.2.2', '<' )===false)
$temp[] = isset($tokens[0][2])?$tokens[0][2]:'unknown';
//rebuild
$tokens[1] = '';
if ($del==3) $tokens[2]='';
$tokens[0] = $temp;
}
return;
}
?>
----
Server IP: 69.147.83.197
Probable Submitter: 71.164.2.148
----
Manual Page -- http://www.php.net/manual/en/function.php-check-syntax.php
Edit -- https://master.php.net/note/edit/87762
Del: integrated -- https://master.php.net/note/delete/87762/integrated
Del: useless -- https://master.php.net/note/delete/87762/useless
Del: bad code -- https://master.php.net/note/delete/87762/bad+code
Del: spam -- https://master.php.net/note/delete/87762/spam
Del: non-english -- https://master.php.net/note/delete/87762/non-english
Del: in docs -- https://master.php.net/note/delete/87762/in+docs
Del: other reasons-- https://master.php.net/note/delete/87762
Reject -- https://master.php.net/note/reject/87762
Search -- https://master.php.net/manage/user-notes.php