14

Well, I have run into a bit of a pickle here. I am needing to check some PHP for syntax errors. I noticed this bit that needs to run from the commandline:

php -l somefile.php

However, is there a way to run this from within a PHP file itself? I've been looking and have think that I can use parse_str function somehow to accomplish this by entering it into a $_GET, but can't quite understand how this works.

Someone else told me to use token_get_all() php function to determine this.

But I can't figure out how to do this with any approach? Can anyone here give me some sample code to get started perhaps?? I don't think using eval() is the way to go, although I had an eval($code) working, but don't think I should run the script if there are PHP syntax errors.

Any help on this is greatly appreciated, as always!

Solomon Closson
  • 6,111
  • 14
  • 73
  • 115

7 Answers7

6

You could simply do shell_exec() like this:

$output = shell_exec('php -l /path/to/filename.php');

This gives you the output of the command line operation in the string $output.

Mike Brant
  • 70,514
  • 10
  • 99
  • 103
  • Ok, have fixed the undefined output error, however, now it returns an empty string regardless if there are PHP Syntax errors or not. – Solomon Closson Aug 14 '12 at 22:13
  • 1
    Using exec() instead of shell_exec() will give you the output in the third parameter: http://www.php.net/manual/en/function.exec.php – Wolfgang Blessen May 05 '18 at 07:37
4

It is safer to check the return status of php -l

$fileName = '/path/to/file.php';
exec("php -l {$fileName}", $output, $return);

if ($return === 0) {
    // Correct syntax
} else {
    // Syntax errors
}

See this fiddle to see it in action

Mandy Schoep
  • 942
  • 11
  • 19
4

I use token_get_all for this. I have some PHP code in the db. Before saving, I do

function is_valid_php_code_or_throw( $code ) {
        $old = ini_set('display_errors', 1);
        try {
                token_get_all("<?php\n$code", TOKEN_PARSE);
        }
        catch ( Throwable $ex ) {
                $error = $ex->getMessage();
                $line = $ex->getLine() - 1;
                throw new InvalidInputException("PARSE ERROR on line $line:\n\n$error");
        }
        finally {
                ini_set('display_errors', $old);
        }
}

Works like a charm. Syntax only. No missing variables, type incompayibility etc.

InvalidInputException is my own. You can make it anything, or return a bool, or handle the exception yourself.

I'm not sure if display_errors is necessary. It was at some point.

Rudie
  • 52,220
  • 42
  • 131
  • 173
0

I would do it like this:

$php_file = 'The path to your file';
if(substr(`php -l $php_file`, 0, 16) == 'No syntax errors') {
    // Correct syntax
} else {
    // Error
}
Samuil Banti
  • 1,735
  • 1
  • 15
  • 26
-1

php_check_syntax should do the trick. If you're running PHP >= 5.05, see the first comment in the comments section for the implementation.

wanovak
  • 6,117
  • 25
  • 32
  • 7
    This function was removed from PHP... [link](http://www.php.net/manual/en/function.php-check-syntax.php) – Solomon Closson Aug 14 '12 at 21:06
  • Good catch @SolomonClosson. OP, luckily in the comments is an implementation that you can use. I won't paste it here as it's very large, but it's the top comment. – wanovak Aug 14 '12 at 21:07
  • 2
    This is a PHP4 function and has been removed in PHP 5.0.x. Moreover it was basically just an alias to `eval()` - it just ran the supplied code to detect parsing errors. – mario Aug 14 '12 at 21:08
-1

You can use exec to check for syntax errors.

$tempFile = path/of/file
$syntaxParseError = strpos(exec('php -l '.$tempFile), 'No syntax errors detected') === false;`

Unfortunately, this will not give you the line number or tell you anything about the error. For that you will either need to install static analyzer on your server Is there a static code analyzer [like Lint] for PHP files? or write your own parser.

NB. token_get_all() will not determine anything on its own, but it useful function for making a parser.

Community
  • 1
  • 1
Dan Bray
  • 7,242
  • 3
  • 52
  • 70
-1

Why use the shell at all?

function syntax_is_valid($code)
{
    try
    {
        @eval($code);
    }
    catch (ParseError $e)
    {
        return false;
    }

    return true;    
}

Alternatively use $e->getMessage() for more info.

kjdion84
  • 9,552
  • 8
  • 60
  • 87
  • 5
    How do you prevent all the side effects from running (evaling) the code? Such as printing, connecting to the database, writing files, etc. – CJ Dennis Oct 08 '17 at 22:56