【问题标题】:How to catch error of require() or include() in PHP?如何在 PHP 中捕获 require() 或 include() 的错误?
【发布时间】:2012-01-05 21:36:03
【问题描述】:

我正在用 PHP5 编写一个脚本,它需要某些文件的代码。当 A 文件不可包含时,首先会引发警告,然后引发致命错误。当无法包含代码时,我想打印自己的错误消息。如果 requeire 不起作用,是否可以执行最后一个命令?以下不起作用:

require('fileERROR.php5') or die("Unable to load configuration file.");

使用error_reporting(0) 抑制所有错误消息只会出现白屏,不使用 error_reporting 会出现 PHP 错误,我不想显示。

【问题讨论】:

    标签: php error-handling try-catch require fatal-error


    【解决方案1】:

    更好的方法是首先在路径上使用realpath。如果文件不存在,realpath 将返回 false

    $filename = realpath(getcwd() . "/fileERROR.php5");
    $filename && return require($filename);
    trigger_error("Could not find file {$filename}", E_USER_ERROR);
    

    您甚至可以在应用的 namespace 中创建自己的 require 函数,该函数包装了 PHP 的 require 函数

    namespace app;
    
    function require_safe($filename) {
      $path = realpath(getcwd() . $filename);
      $path && return require($path);
      trigger_error("Could not find file {$path}", E_USER_ERROR);
    }
    

    现在您可以在文件中的任何位置使用它

    namespace app;
    
    require_safe("fileERROR.php5");
    

    【讨论】:

    • 我完全不知道为什么,但是在 PHP CLI / 控制台中运行时,您的代码无法正常工作(产生误报)。 IE。它停止执行脚本,声称文件 XYZ 不存在,但它确实存在 - 注释掉您的代码并直接转到 include() 工作正常,并且文件包含在内而没有错误。
    【解决方案2】:

    我建议您查看set_error_handler() 函数的文档中最多的recent comment

    它建议以下作为捕获致命错误的方法(并带有示例):

    <?php
    function shutdown()
    {
        $a=error_get_last();
        if($a==null)  
            echo "No errors";
        else
             print_r($a);
    
    }
    register_shutdown_function('shutdown');
    ini_set('max_execution_time',1 );
    sleep(3);
    ?> 
    

    我没有尝试过这个建议,但这可能会用于其他致命错误场景。

    【讨论】:

    • 虽然这可能有效,但它产生了很好的问题,如果这在条件下有效,OP 在问?我相信大多数登陆这里的人都在寻找一个解决方案,他们可以在不存在的文件上捕获require 并继续脚本执行。能够优雅地死去(即显示一些东西,我想要但最终脚本终止 - 这就是你的代码似乎正在做的事情)似乎不适合许多场景。我假设,如果脚本死了,它可以显示它想要的任何东西。我想防止在馈送到require 的不存在文件上死亡/终止。
    【解决方案3】:

    你需要使用include()。 Require() 在不存在的文件上使用时会产生致命错误并退出脚本,因此您的 die() 不会发生。 Include() 只抛出警告,然后脚本继续。

    【讨论】:

    • 您的答案要么特定于某个 P​​HP 版本,要么特定于某个 php.ini 配置。在我这边(PHP 5.5.4)我的配置,将require 更改为include 绝对没有任何区别。两者都抛出丑陋的致命错误,我无法捕捉到。
    【解决方案4】:

    您可以通过将set_error_handlerErrorException 结合使用来完成此操作。

    ErrorException 页面中的示例是:

    <?php
    function exception_error_handler($errno, $errstr, $errfile, $errline ) {
        throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
    }
    set_error_handler("exception_error_handler");
    
    /* Trigger exception */
    strpos();
    ?>
    

    一旦您将错误作为异常处理,您可以执行以下操作:

    <?php
    try {
        include 'fileERROR.php5';
    } catch (ErrorException $ex) {
        echo "Unable to load configuration file.";
        // you can exit or die here if you prefer - also you can log your error,
        // or any other steps you wish to take
    }
    ?>
    

    【讨论】:

    • @SajnEvardsson php 手册的 ErrorException 第三个参数为 $errno,而不是第二个。
    • 上面的例子是直接从 ErrorException 文档(上面的链接)复制的——在“官方”例子中,他们使用 $errno 作为 $code,而其他人(包括该页面上的 cmets)建议将其用作 $severity - 请注意,如果您愿意,可以同时使用它,也可以两者都不使用。
    • 似乎过度设计的方式做非常简单的事情
    【解决方案5】:

    我只使用'file_exists()':

    if (file_exists("must_have.php")) {
        require "must_have.php";
    }
    else {
        echo "Please try back in five minutes...\n";
    }
    

    【讨论】:

    • 最好使用is_readable();除了文件的可读性之外,它还会检查文件是否存在(简单地说,文件必须存在才能读取)。此外,为了防止包含目录,您应该使用is_dir()(即!is_dir($filename))。
    • file_exists 不检查包含路径,因此它可能不起作用
    • 在您的回声末尾包含 die()require 将停止脚本运行,如果文件不存在,将显示回显并加载页面的其余部分。但改为添加 die() 将在页面中显示除消息之外的任何内容。
    • 它也适用于 DIRECTORIES,而不仅仅是文件,效果更好
    【解决方案6】:

    我使用的一个简单方法是

    <?php
        ...
        if(!include 'config.php'){
            die("File not found handler. >_<");
        }
       ...
    ?>
    

    【讨论】:

    • 任何特定的情况下这不起作用?
    猜你喜欢
    • 1970-01-01
    • 2019-11-28
    • 2017-11-04
    • 2016-07-03
    • 1970-01-01
    • 2014-01-17
    • 2010-09-25
    • 2011-04-24
    • 1970-01-01
    相关资源
    最近更新 更多