php:try-catch 未捕获所有异常
Posted
技术标签:
【中文标题】php:try-catch 未捕获所有异常【英文标题】:php: try-catch not catching all exceptions 【发布时间】:2013-03-05 21:23:44 【问题描述】:我正在尝试执行以下操作:
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 的补充,很少有内置函数会抛出它们。相反,您需要验证大多数函数的返回值。 【参考方案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.php 和 php.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;
【讨论】:
以上是关于php:try-catch 未捕获所有异常的主要内容,如果未能解决你的问题,请参考以下文章