Jacob Cohen
Jacob Cohen

Reputation: 1272

Catching PHP Parser error when using include

I have a file called functions.php.

This file consists includes to all the other function files, for example:

include_once("user_functions.php");
include_once("foo_functions.php");

I would like to catch errors where when I screw a code in one of those files, It wouldn't give the error to the entire system.

For example, if there is a parser error in foo_functions.php it will just not include it in functions.php.

Is that possible?

Upvotes: 7

Views: 7448

Answers (6)

This code can check if file is exist or not, if file exist than include it.

<? 
    if(!is_file('user_functions.php')){
        //There is no file user_functions.php . You may use file_put_contents('user_functions.php','<? //content ?>');
    }else{
        //ther is file user_functions.php, so include it.
        include 'user_functions.php'; 
    }
?>

And this one help you get syntax errors (PHP 7+ only)

<?
    try {
        include('user_functions.php');
    }catch (ParseError $e) {
        echo 'Error: '.$e->getMessage();
        //syntax error, unexpected end of file, expecting ',' or ';'
    }


?>

so if you use PHP 7+ you may use:

<? 
    if(!is_file('user_functions.php')){
        echo 'Error: file is not exist';
    }else{
        //check errors
        try {
            include('user_functions.php');
        }catch (ParseError $e) {
            echo 'Error: '.$e->getMessage();
            //syntax error, unexpected end of file, expecting ',' or ';'
        }
    }
?>

Upvotes: 4

Alexander Shostak
Alexander Shostak

Reputation: 722

As of PHP 7, most eval/include errors, such as ParseError can be catched:

try {
  include_once(__DIR__ . '/test.php');
} catch (\Throwable $e) {
  var_dump($e);
}

Upvotes: 13

Harry Pehkonen
Harry Pehkonen

Reputation: 3038

The solution that I am using feels like a band-aid solution, but it will give you control back.

The idea is to use "eval()" to first check for errors. Also, ignore errors with the @ in the beginning. Of course you will need to be careful with eval, so don't ever let users feed anything to it.

    // first "eval" the file to see if it contains errors
    $txt = file_get_contents($template_filename);

    // eval starts out in php-mode.  get out of it.
    $txt = '?' . '>' . $txt;
    ob_start();
    $evalResult = @eval($txt);
    ob_end_clean();

    // if there are no errors
    if($evalResult !== FALSE) {
        require($template_filename);
    } else {
        error_log(print_r(error_get_last(), TRUE));
    }

Please note that I think "file_get_contents + eval" = "require", or very close to it, so you may be able to just skip the require-part.

Upvotes: 0

elixenide
elixenide

Reputation: 44833

Parser errors are fatal errors, so you can't catch them. See this question and answer for more details.

What you can do if you can run exec() is call php -l thefilename.php and check the result. See the manual for information on how this works. There are a few problems here, however:

  • This is extremely dangerous, because you are passing information to the command line. You absolutely must filter any user input very carefully, or you would be giving the user very broad access to your system.
  • exec() is often disabled, as it should be, because of the extremely high security risks of using it incorrectly.
  • There's really no good reason to include a file that you haven't already validated for syntax errors. If this is for plugins or something, then I understand your reasoning. If it is code you have control over, however, you should validate before putting it into production.

Upvotes: 4

Andy
Andy

Reputation: 50550

include() and include_once() return false if they fail. You can use this to check if the included files were successful.

if (!include('user_functions.php'))
   echo 'user functions failed to include';
if (!include('foo_functions.php'))
   echo 'foo_functions failed to include';

By changing the echos to handle your error logic, you should be able to do what you are asking.

Upvotes: 0

John Lucabech
John Lucabech

Reputation: 156

What if you put

error_reporting(E_ALL);
ini_set("display_errors", 1);

at the beginning of foo_functions.php ?

Upvotes: 0

Related Questions