18

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!

3
  • Why not spawn a php -l subprocess? Commented Aug 14, 2012 at 21:02
  • @arxanas - How can this be done?? Possible answer...? Commented Aug 14, 2012 at 21:06
  • @SolomonClosson, I think he's terse comment is referring to php.net/manual/en/function.exec.php Commented Jan 28, 2015 at 7:59

8 Answers 8

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Ok, have fixed the undefined output error, however, now it returns an empty string regardless if there are PHP Syntax errors or not.
Using exec() instead of shell_exec() will give you the output in the third parameter: php.net/manual/en/function.exec.php
5

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.

2 Comments

This string parses but crashes if your try to run it <?php class {CLASS}: 3v4l.org/p9k1Y
Eh. That's weird. But you should add the TOKEN_PARSE flag: 3v4l.org/VFDrG
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

Comments

1

From command line use -ln to return the line containing the error.

> php -ln file.php

Parse error: syntax error, unexpected ':' in file.php on line 899
Errors parsing file.php

1 Comment

-l does a syntax check ("lint"), -n prevents it from using php.ini. I suppose php.ini often contains display_errors=off. To overcome this directly, you can do php -ddisplay_errors=on, but perhaps it's not generally desirable to bother reading php.ini when only a syntax check is desired.
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
}

Comments

-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.

3 Comments

This function was removed from PHP... link
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.
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.
-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.

Comments

-2

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.

1 Comment

How do you prevent all the side effects from running (evaling) the code? Such as printing, connecting to the database, writing files, etc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.