处理格式错误的输入而不是抛出错误的PHP替代方案

处理格式错误的输入而不是抛出错误的PHP替代方案,php,error-handling,Php,Error Handling,PHP语言中有许多函数(事实上大多数函数)在不喜欢输入内容时会感到不安并发出警告和通知,而不仅仅是返回FALSE(尽管它们也这样做) 这在GD和string函数中非常常见。他们对自己的论点非常挑剔,用户输入很容易达不到他们的标准 例如,用户上载损坏的图像(有意或无意)。导致GD库发出警告 到目前为止,我发现只有三种方法可以让PHP在这个问题上保持沉默: 在ini或中更改错误报告设置(糟糕) 使用慢速@符号抑制错误 在函数之前/之后更改错误报告: 像这样: $errorlevel=error_

PHP语言中有许多函数(事实上大多数函数)在不喜欢输入内容时会感到不安并发出警告和通知,而不仅仅是返回
FALSE
(尽管它们也这样做)

这在GD和string函数中非常常见。他们对自己的论点非常挑剔,用户输入很容易达不到他们的标准

例如,用户上载损坏的图像(有意或无意)。导致GD库发出警告

到目前为止,我发现只有三种方法可以让PHP在这个问题上保持沉默:

  • 在ini或中更改错误报告设置(糟糕)
  • 使用慢速
    @
    符号抑制错误
  • 在函数之前/之后更改错误报告:
像这样:

$errorlevel=error_reporting();
error_reporting($errorlevel & ~E_NOTICE);
//...code that generates notices
error_reporting($errorlevel);
当然,后两个选择让我恶心。这让我只能使用1)和调低PHP错误设置。然而,我希望PHP处于严格模式,以便在我工作时能够捕获可能潜入代码中的逻辑错误和错误形式。然而,我不想在PHP不喜欢某些东西时抛出随机错误

那么,有没有办法将格式错误的参数(错误输入)产生的错误与编程错误产生的错误分开呢?例如:

  • 如果用户图像无效,只需返回FALSE,我将处理它。我不需要警告
  • 如果将图像资源传递给打印函数无效,则抛出警告
  • 修正代码
    在调用函数之前对输入进行清理。这样可以避免错误

    如果有类似的情况,您可以使用

    这不是一个干净的解决方案,但在某些情况下,这是必不可少的


    在使用getimagesize()之前是否检查了图像?

    还有另一种选择-使用
    设置错误处理程序()
    ,您甚至可以在GD函数调用之前调用它,并使用
    还原错误处理程序()
    返回默认设置


    问题中有一个很好的注释,它提供了关于如何实现这一点的更多细节。

    从PHP一开始,这就是一个糟糕的设计。现代PHP库会在出现错误时抛出异常。并且可能会捕获异常。但当时GD是由PHP编写的,PHP还不支持异常

    因此,我认为在这种情况下,使用
    @
    操作符是合法的

    然而,我不想有随机的 当PHP不喜欢时抛出的错误 什么


    为什么不呢?PHP试图通过警告和通知告诉您一些值得注意的事情。在GD示例中,当用户上载损坏的文件时,尤其是在攻击中使用该文件时,您需要登录

    除了编辑有问题的库并更改其抛出异常的方式之外,没有通用的方法适用于所有库。老实说,很多PHP开发人员真的不在乎抛出异常,但现在越来越多的人开始严格遵守E_规则。当GD LIB生成时,人们的想法可能是抛出不可跟踪的错误并没有什么大不了的


    至于使用GD验证图像。你唯一能做的就是使用不同的库或函数来验证你的图像。您可能需要检查图像是否有正确的头(尽管这并不意味着文件的其余部分结构正确)。至少使用magic byte函数可以处理一些显而易见的事情,比如有人上传文本文件而不是JPEG。

    在我尝试用GD打开图像文件之前,我不知道如何判断图像文件是否有效。如果GD不能读取它,那么我知道它是无效的。当然,PHP在本机上对您没有帮助。所有GD imagecreate*函数在出现错误时都应该返回false,或者您正在使用其他函数?@tadamson许多GD函数除了返回false之外还发出警告/通知:@tadamson正如我上面提到的,它们确实返回false。但是,它们也会抛出E_警告,这些警告无法立即捕获并像异常或布尔结果一样进行分析。啊,对不起,很久没有使用gd了。可能根本无法回答您的问题,但是:由于imagick库是基于OO的,因此您可以使用ImagickExceptions来执行catch。不过,从一个异常切换到另一个异常是件麻烦事。抛出异常对我来说也没问题,因为我可以像处理函数结果的布尔错误检查一样处理它们。糟糕的是,它没有抛出可捕获的东西……我认为不捕获错误的最大问题是,用户被扔到白色或部分加载的屏幕上,没有清楚地解释出什么地方出错或发生了什么。对于一个普通用户来说,这将是非常令人不安的。这不应该是一个问题,因为函数也返回false,您可以检测并输出除空白页以外的内容。警告不会终止脚本的执行&您不应该在生产服务器上输出它们。是的,如果您检查用户映像上GD函数的输出是否为
    ==FALSE
    ,则不需要抛出警告错误。在这一点上,你应该知道一些明显的错误,并记录有关情况的数据。是的,我实际上曾经这样做。但是,为每个函数添加一个try{}catch{}块将显著增加代码库的大小。现在每个1行函数=5行代码。另外,由于处理异常比检查
    $result===FALSE花费更多时间,因此它也会大大降低代码的速度。您不必对每个函数都使用try/catch,您可以使用
    添加异常处理程序()
    为所有异常设置默认处理程序。但如果我设置了全局处理程序,那么如何将其与发生异常时运行的代码联系起来?我必须抓住这个例外