【问题标题】:php: try-catch not catching all exceptionsphp:try-catch 未捕获所有异常
【发布时间】:2023-03-06 14:44:01
【问题描述】:

我正在尝试执行以下操作:

try {
    // just an example
    $time      = 'wrong datatype';
    $timestamp = date("Y-m-d H:i:s", $time);
} catch (Exception $e) {
    return false;
}
// database activity here

简而言之:我初始化了一些要放入数据库的变量。如果由于某种原因初始化失败 - 例如因为 $time 不是预期的格式 - 我希望该方法返回 false 并且不会将错误的数据输入到数据库中。

但是,像这样的错误不会被“catch”语句捕获,而是被全局错误处理程序捕获。 然后脚本继续。

有没有办法解决这个问题?我只是认为这样做会更干净,而不是手动对每个变量进行类型检查,考虑到在 99% 的所有情况下都没有发生任何坏事,这似乎是无效的。

【问题讨论】:

  • 这是因为异常在 PHP 中没有普遍实现。它们是 PHP5 的补充,很少有内置函数会抛出它们。相反,您需要验证大多数函数的返回值。

标签: php exception try-catch


【解决方案1】:

解决方案 #1

使用ErrorException将错误转化为异常处理:

function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
set_error_handler("exception_error_handler");

解决方案 #2

try {
    // just an example
    $time      = 'wrong datatype';
    if (false === $timestamp = date("Y-m-d H:i:s", $time)) {
        throw new Exception('date error');
    }
} catch (Exception $e) {
    return false;
}

【讨论】:

  • 一些注意事项:1) 如果不希望在整个应用程序中普遍引发异常来代替错误,可以在需要的地方启用此功能,并且可以使用restore_error_handler() 恢复常规错误处理。 2)我希望#2 仍然会发出警告。相同的概念适用:错误报告级别可以使用error_reporting() 更改,然后再更改回来。
  • 无论如何都必须抛出警告。它们是您必须将其保存在某处的信息。不想看就关掉error_display
  • 解决方案#2是Js是怎么做的...如果你知道你在做什么就好了
  • 跟进问题:在您的 MVC 应用程序中使用解决方案 #1 是个好主意吗?我觉得在全球范围内使用它会破坏 Exceptions 的目的,而反复使用 restore_error_handler() 感觉非常hackish。
  • 仅在调试模式@VarunAgrawal,在开发期间。我不会依赖全局 php 设置来正确处理您的应用程序最终将如何运行。
【解决方案2】:

我发现的较短的:

set_error_handler(function($errno, $errstr, $errfile, $errline ){
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
});

使所有错误成为可捕获ErrorException 的实例

【讨论】:

    【解决方案3】:

    可以使用catch(Throwable $e) 来捕获所有异常和错误,如下所示:

    catch ( Throwable $e){
        $msg = $e->getMessage();
    }
    

    【讨论】:

    • 稍微解释一下就好了。
    【解决方案4】:
    try {
      // call a success/error/progress handler
    } catch (\Throwable $e) { // For PHP 7
      // handle $e
    } catch (\Exception $e) { // For PHP 5
      // handle $e
    }
    

    【讨论】:

    • 感谢您提供此代码 sn-p,它可能会提供一些有限的即时帮助。 proper explanation 将通过展示为什么这是解决问题的好方法,并使其对有其他类似问题的未来读者更有用,从而大大提高其长期价值。请edit您的回答添加一些解释,包括您所做的假设。
    • @YvetteColomb,哦,所以这是一个消除我意见的幽灵! ;-) 但我仍然相信一些问题可能只有一个单词的答案。问题4 + 4? 的答案是什么 很简短的答案可以不加解释地添加,只有一个字:2,那我们为什么要写:“4 + 4 语句的正确答案是你的问题是2……!”同样,我也同意回复中更详细的解释。但我的意思是,只有其中一些。
    • 我只需要这个简短的答案。但我不确定 4 + 4 = 2。
    • 是的,这是严重缺乏记录的,你几乎不会注意到它,如果你很幸运并同时访问 php.net/manual/en/class.error.phpphp.net/manual/en/class.exception.php 链接......因为应该包含这个:php.net/manual/en/language.exceptions.php - 甚至不包含单词 Throwable(在文档部分)。
    • 什么情况下会进入后面的catch块?当 Exception 类实现 Throwable 接口时,这不总是在第一个 catch 块中被捕获吗?
    【解决方案5】:

    也可以在catch中为$e参数定义多种类型:

    try {
        // just an example
        $time      = 'wrong datatype';
        $timestamp = date("Y-m-d H:i:s", $time);
    } catch (Exception|TypeError $e) {
        return false;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-09
      • 2020-02-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多