Catching PHP Parser error when using include

不打扰是莪最后的温柔 提交于 2020-01-01 12:14:15

问题


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?


回答1:


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.



回答2:


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);
}



回答3:


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 ';'
        }
    }
?>



回答4:


What if you put

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

at the beginning of foo_functions.php ?




回答5:


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.




回答6:


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.



来源:https://stackoverflow.com/questions/21431773/catching-php-parser-error-when-using-include

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!