note 82809 deleted from function.php-check-syntax by felipe
| From: | felipe@php.net | Date: | Sun, 27 Apr 2008 00:27:27 +0000 |
| Subject: | note 82809 deleted from function.php-check-syntax by felipe | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-138836@lists.php.net to get a copy of this message | ||
Note Submitter: kevin at metalaxe dot com
----
2: kevin at metalaxe dot com
Hm.. i think your function didnt work...
Yeah, I noticed this. I could do a couple of things, but I played with this a little less half-assed
today. Give this new version a shot, see output below. I tried to even parse classes, but it seems
that classes are being processed a lot differently and blow FATAL errors during the parsing phase...
Anyone have any ideas around this?
<?php
/**
* Check Eval
* Performs a Syntax check without killing the parser (hopefully)
*
* @params string PHP to be evaluated
* @return array Parse error info or true for success
**/
function checkEval( $php )
{
$evalStr = 'return;';
# Get the string tokens
$crack = token_get_all( '<'.'?php'.$php );
# Drop our manually entered opening tag
array_shift( $crack );
# Check to see how we need to proceed
# prepare the string for parsing
if( isset( $crack[0] ) && $crack[0][1] === T_CONSTANT_ENCAPSED_STRING | T_STRING |
T_OPEN_TAG )
$evalStr .= '?>';
# Make sure syntax reporting is on...probably only need E_PARSE...but I'm anal
$oldErr = error_reporting( E_ALL | E_STRICT );
# Prevent output
ob_start();
eval( $evalStr.$php );
$evaluput = ob_get_clean();
# Reset error reporting
error_reporting( $oldErr );
# Only do this if there was output
if( $evaluput !== '' )
{
# Strip annoying html tags, in case html reporting is enabled in php.ini
$evaluput = strip_tags( $evaluput );
# Fancy Regex to pull the error that killed us
$pattern = '/Parse error:\s*syntax error,(.+?)\s+in\s+.+?\s*line\s+(\d+)/';
$parse_fail = (bool)preg_match( $pattern, $evaluput, $match );
# Parse error to report?
if( $parse_fail === true )
{
return array(
'line' => (int)$match[2],
'msg' => $match[1]
);
}
}
return true;
}
?>
Test Case:
<?php
require('syntaxcheck.php');
//$axis = axis_kernel::init( __FILE__ );
ini_set( 'display_errors', true );
error_reporting( E_ALL | E_STRICT );
$php[] = 'asfvsd <?php echo \'aaa\'; ?> asvsdgb';
$php[] = '<'."?php echo 'something';?> asvsdgb";
$php[] = "echo 'something';?> asvsdgb";
$php[] = "if( PHP_VERSION ) { echo PHP_VERSION; }";
$php[] = $temp = <<<EOF
abstract class bob {
public \$property = 'string';
public \$property2 = true;
public \$property3 = array();
abstract public static final function __construct(){}
}
EOF;
$php[] = '<?php '.$temp;
print '<pre>';
foreach( $php as $code )
{
print 'Test php'."\n\n";
print htmlspecialchars( $code );
print "\n\n".'Results:'."\n";
var_dump( checkEval( $code ) );
print "\n\n";
}
exit();
?>
Output:
Test php
asfvsd <?php echo 'aaa'; ?> asvsdgb
Results:
bool(true)
....