php_check_syntax

(PHP 5 <= 5.0.4)

php_check_syntax Проверяет (и запускает) PHP синтаксис указанного файла

Описание

bool php_check_syntax ( string $filename [, string &$error_message ] )

Выполняет проверку синтаксиса (производит верификацию) файла, указанного в filename проверяя ошибки в коде.

Действие похоже на использование php -l из командной строки, исключая то, что эта функция запустит (но не выведет) проверяемый файл из filename.

К примеру, если функция определена в filename, то эта функция будет доступна после в файле, из которого производится запуск функции php_check_syntax(), но вывод из файла, указанного в filename будет невозможен.

Замечание:

По техническим причинам эта функция устарела и удалена из PHP. Вместо этой функции используйте php -l somefile.php из командной строки.

Список параметров

filename

Имя проверяемого файла.

error_message

Если используется параметр error_message, то в нем будет содержаться сообщение об ошибке, сформированное при проверке синтаксиса. error_message передается по ссылке.

Возвращаемые значения

Возвращает TRUE если проверка пройдена, и FALSE если возникла ошибка или файл из filename недоступен.

Список изменений

Версия Описание
5.0.5 Эта функция была удалена из PHP.
5.0.3 Вызов функции exit() после php_check_syntax() передает результат в Segfault.
5.0.1 error_message передается по ссылке.

Примеры

php -l somefile.php

Результатом выполнения данного примера будет что-то подобное:

PHP Parse error: unexpected T_STRING in /tmp/somefile.php on line 81

Смотрите также

  • include - include
  • is_readable() - Определяет существование файла и доступен ли он для чтения

Коментарии

While developing an app where I have to include PHP files written by a user, I came across the following problem:

I used "php -l somefile.php" to check the syntax of the file I was about to include and if it passed, I would include it - so far so good. But in some test cases, the file I was including would have other includes/requires inside it. If one of these was invalid, then I would still get the parse error that I was trying to avoid.

I got round it using this:

<?php
   
function CheckSyntax($fileName$checkIncludes true)
    {
       
// If it is not a file or we can't read it throw an exception
       
if(!is_file($fileName) || !is_readable($fileName))
            throw new 
Exception("Cannot read file ".$fileName);
       
       
// Sort out the formatting of the filename
       
$fileName realpath($fileName);
       
       
// Get the shell output from the syntax check command
       
$output shell_exec('php -l "'.$fileName.'"');
       
       
// Try to find the parse error text and chop it off
       
$syntaxError preg_replace("/Errors parsing.*$/"""$output, -1$count);
       
       
// If the error text above was matched, throw an exception containing the syntax error
       
if($count 0)
            throw new 
Exception(trim($syntaxError));
       
       
// If we are going to check the files includes
       
if($checkIncludes)
        {
            foreach(
GetIncludes($fileName) as $include)
            {
               
// Check the syntax for each include
               
CheckSyntax($include);
            }
        }
    }
   
    function 
GetIncludes($fileName)
    {
       
// NOTE that any file coming into this function has already passed the syntax check, so
        // we can assume things like proper line terminations
           
       
$includes = array();
       
// Get the directory name of the file so we can prepend it to relative paths
       
$dir dirname($fileName);
       
       
// Split the contents of $fileName about requires and includes
        // We need to slice off the first element since that is the text up to the first include/require
       
$requireSplit array_slice(preg_split('/require|include/i'file_get_contents($fileName)), 1);
       
       
// For each match
       
foreach($requireSplit as $string)
        {
           
// Substring up to the end of the first line, i.e. the line that the require is on
           
$string substr($string0strpos($string";"));
           
           
// If the line contains a reference to a variable, then we cannot analyse it
            // so skip this iteration
           
if(strpos($string"$") !== false)
                continue;
           
           
// Split the string about single and double quotes
           
$quoteSplit preg_split('/[\'"]/'$string);
           
           
// The value of the include is the second element of the array
            // Putting this in an if statement enforces the presence of '' or "" somewhere in the include
            // includes with any kind of run-time variable in have been excluded earlier
            // this just leaves includes with constants in, which we can't do much about
           
if($include $quoteSplit[1])
            {
               
// If the path is not absolute, add the dir and separator
                // Then call realpath to chop out extra separators
               
if(strpos($include':') === FALSE)
                   
$include realpath($dir.DIRECTORY_SEPARATOR.$include);
           
               
array_push($includes$include);
            }
        }
       
        return 
$includes;
    }
?>

This checks as many of the includes inside the file as it possibly can without executing anything.
2008-02-05 07:35:55
http://php5.kiev.ua/manual/ru/function.php-check-syntax.html
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 tempnamNULL'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 !== )
        {
           
# 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;
}
?>
2008-12-19 18:37:58
http://php5.kiev.ua/manual/ru/function.php-check-syntax.html

    Поддержать сайт на родительском проекте КГБ