有没有比处理`@`更好的方法来处理预期的错误?

时间:2015-09-08 12:02:03

标签: php error-handling

我有一个脚本,用于检查IP地址上是否可以访问端口。因此,无论我选择使用file_get_contents还是fsockopen执行此操作,概念都保持不变,即我必须调用其中任何一个函数才能获得结果。例如,没有相当于file_exists的保证"保证"调用file_get_contents时调用URL不会产生错误。

在这种情况下,我错误的是错误是程序流程中完全可以接受的部分,因此不应该被视为其他错误("实际")我的应用程序错误。因为我通常运行的是自定义错误处理程序,对于任何意外失败的情况,将错误消息写入日志文件,然后显示一个类似404的错误页面。这意味着在这种情况下,我必须执行restore_error_handler,以便能够在没有出现大量错误屏幕的情况下执行@file_get_contents,以便检查其结果是否为{{1 }}。

目前,它是如何工作的,输出是正确的,但方法似乎错误。我想知道的是,有没有更好的方法来解决这种情况?一个不会要求我取消设置应用程序范围的东西,而且更像false方法的东西。

2 个答案:

答案 0 :(得分:3)

我会从最好的选项开始,即使它实际上还没有存在。

当PHP 7发布时(目前处于测试阶段3,因此最终版本应在接下来的几个月内完成),它将具有完全重写的错误处理系统。

新的PHP 7错误处理程序将所有旧的PHP错误转换为新类型的异常。这意味着您可以使用try ... catch来处理它们,就像其他例外一样。这将极大地简化PHP错误处理,对我而言,它是在发布之后尽快升级到PHP 7的主要卖点之一。

但是,它尚未发布,您可能无法/愿意立即升级到它,所以这里有其他选项:

  1. 切换到替代OO课程 许多PHP函数都有面向对象的替代方法,它们抛出异常而不是旧式错误。例如,您在问题中指定了file_get_contents();这些可以通过调用the SplFileObject class来替换。 fsockopen()通常用于进行http调用,因此可以将该代码替换为Guzzle库。等等。通常有一种做法可以避免依赖旧功能。

  2. 如果您确实需要依赖旧函数,并且在调用它们之前确实无法找到检查潜在错误的方法,那么您需要考虑使用旧的错误处理函数{{3 }}。此功能允许您指定在发生错误时将调用的函数。一旦进入错误处理函数,你就可以做必要的事情来处理它并返回(在这种情况下,原始代码将在下一行连接)或者如果无法从中恢复错误就会优雅地死掉。

  3. 但最终,你是绝对正确的 - PHP错误有点像狗早餐,并且真的不容易使用。 @运算符很臭,但偶尔也没有任何替代方法。我现在很久没有发现自己在使用它了,所以你真的不需要它,但我确实承认它可能是不时的,因为PHP没有提供更好的东西。

    这将随PHP 7而改变;错误处理是许多正在大幅改进的事情之一。我期待它的发布。

答案 1 :(得分:1)

  

我想知道的是,有没有更好的方法来解决这种情况?一个不会要求我取消设置应用程序范围的东西,而且更像try-catch方法的东西。

这是否更漂亮"是基于意见的,但您可以在自定义错误处理程序中将所有错误转换为异常,这样您就可以实际catch

set_error_handler(function($num, $msg, $file, $line)
{
    // Convert to exceptions
    throw new ErrorException($msg, 0, $num, $file, $line);
});
set_exception_handler(function($e)
{
    // Print or log to file
    echo get_class($e).': '.$e->getMessage().' ['.$e->getFile().':'.$e->getLine().']';
});

try
{
    // Will be caught
    echo array();
}
catch(ErrorException $e) {}

// Will not be caught
echo array();

[Demo]