我需要从一些php本机函数中捕获一些警告,然后处理它们 .
特别:
array dns_get_record ( string $hostname [, int $type= DNS_ANY [, array &$authns [, array &$addtl ]]] )
当DNS查询失败时,它会发出警告 .
try
/ catch
不起作用,因为警告不是例外 .
我现在有2个选择:
-
set_error_handler
似乎有点矫枉过正,因为我必须使用它来过滤页面中的每个警告(这是真的吗?); -
调整错误报告/显示,以便这些警告不会发生't get echoed to screen, then check the return value; if it' s
false
,找不到主机名的记录 .
这里的最佳做法是什么?
10 回答
如果
dns_get_record()
失败,则应返回FALSE
,因此可以使用@
禁止警告,然后检查返回值 .您可能应该尝试完全摆脱警告,但如果这不可能,您可以使用@(即@dns_get_record(...))预先调用该调用,然后使用您可以获得的任何信息来确定是否发生了警告或不 .
真正有效的解决方案是使用
E_WARNING
参数设置简单的错误处理程序,如下所示:我想尝试/捕获警告,但同时保持通常的警告/错误记录(例如在
/var/log/apache2/error.log
中);处理程序必须返回false
. 但是,由于"throw new..."语句基本上会中断执行,因此必须执行"wrap in function"技巧,也在以下讨论:Is there a static way to throw exception in php
或者,简而言之:
编辑:仔细检查后,事实证明它不起作用:“
return false && throwErrorException ...
”基本上不会抛出异常,只需登录错误日志;删除“false &&
" part, as in "return throwErrorException ...
”,会使异常抛出工作,但不会登录error_log ...我在其他地方看到了这种行为 .Normaly你永远不应该使用@,除非这是唯一的解决方案 . 在该特定情况下,应首先使用函数dns_check_record来知道记录是否存在 .
Set and restore error handler
一种可能性是在调用之前设置自己的错误处理程序,并稍后使用
restore_error_handler()
恢复先前的错误处理程序 .您可以构建这个想法并编写一个可重用的错误处理程序,为您记录错误 .
Turning errors into exceptions
您可以使用
set_error_handler()
和ErrorException
类将所有php错误转换为异常 .使用自己的错误处理程序时需要注意的重要一点是,它将绕过
error_reporting
设置并将所有错误(通知,警告等)传递给错误处理程序 . 您可以在set_error_handler()
上设置第二个参数以定义要接收的错误类型,或使用错误处理程序内的... = error_reporting()
访问当前设置 .Suppressing the warning
另一种可能性是使用@运算符抑制调用,然后检查
dns_get_record()
的返回值 . But I'd advise against this 因触发错误/警告而不被抑制 .我只建议使用@来抑制警告,当它是直接操作时(例如$ prop = @($ high /($ width - $ depth));跳过除零警告) . 但是在大多数情况下最好处理 .
Be careful with the @ operator - 虽然它可以抑制警告但它也可以抑制致命错误 . 我花了很多时间在系统中调试问题,有人写了
@mysql_query( '...' )
,问题是mysql支持没有加载到PHP中,它引发了一个无声的致命错误 . 对于那些属于PHP核心的东西来说是安全的,但请小心使用它 .没有进一步的输出 - 好运调试这个!
这次我们可以看出它失败的原因 .
尝试检查它是否返回一些布尔值,然后你可以简单地把它作为一个条件 . 我用oci_execute(...)遇到了这个问题,它使用我的唯一键返回了一些违规行为 .
将这些代码行组合在一个外部URL的
file_get_contents()
调用上帮助我更好地处理“ failed to open stream: Connection timed out ”之类的警告:此解决方案也适用于对象上下文 . 你可以在函数中使用它: