我可以尝试/发现警告吗?

我需要捕捉一些从本地函数抛出的警告,然后处理它们。

特别:

array dns_get_record ( string $hostname [, int $type= DNS_ANY [, array &$authns [, array &$addtl ]]] ) 

它会在DNS查询失败时引发警告。

try / catch不起作用,因为警告不是一个例外。

我现在有两个select:

  1. set_error_handler看起来像是过度杀伤,因为我必须使用它来过滤页面中的每一个警告(这是真的吗?

  2. 调整错误报告/显示,使这些警告不会回显到屏幕上,然后检查返回值; 如果为false ,则不会为主机名findlogging。

这里最好的做法是什么?

设置和恢复error handling程序

一种可能是在调用之前设置自己的error handling程序,稍后用restore_error_handler()恢复以前的error handling程序。

 set_error_handler(function() { /* ignore errors */ }); dns_get_record(); restore_error_handler(); 

你可以build立这个想法,并编写一个可重用的error handling程序,为您logging错误。

 set_error_handler([$logger, 'onSilencedError']); dns_get_record(); restore_error_handler(); 

将错误转化为例外

你可以使用set_error_handler()ErrorException类将所有的php错误转化为exception。

 set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) { // error was suppressed with the @-operator if (0 === error_reporting()) { return false; } throw new ErrorException($errstr, 0, $errno, $errfile, $errline); }); try { dns_get_record(); } catch (ErrorException $e) { // ... } 

使用自己的error handling程序时要注意的一点是,它将绕过error_reporting设置并将所有错误(通知,警告等)传递给error handling程序。 您可以在set_error_handler()上设置第二个参数来定义您想要接收的错误types,或者在error handling程序中使用... = error_reporting()来访问当前的设置。

禁止警告

另一种可能是用@运算符来抑制调用,然后检查dns_get_record()的返回值。 但我build议不要这样做,因为错误/警告触发处理,不被压制。

真正起作用的解决scheme竟然是用E_WARNING参数设置简单的error handling程序,如下所示:

 set_error_handler("warning_handler", E_WARNING); dns_get_record(...) restore_error_handler(); function warning_handler($errno, $errstr) { // do something } 

要小心@操作符 – 而它禁止警告,它也可以抑制致命的错误。 我花了很多时间在有人写过@mysql_query( '...' )的系统中debugging一个问题,问题是没有将mysql支持加载到PHP中,并且抛出了一个沉默的致命错误。 对于那些属于PHP核心的东西是安全的,但小心使用它。

 bob@mypc:~$ php -a Interactive shell php > echo @something(); // this will just silently die... 

没有更多的输出 – 祝你好运debugging!

 bob@mypc:~$ php -a Interactive shell php > echo something(); // lets try it again but don't suppress the error PHP Fatal error: Call to undefined function something() in php shell code on line 1 PHP Stack trace: PHP 1. {main}() php shell code:0 bob@mypc:~$ 

这一次,我们可以看到为什么失败。

我想尝试/捕捉一个警告,但同时保持通常的警告/错误logging(例如在/var/log/apache2/error.log ); 为此处理程序必须返回false 。 然而,由于“throw new …”语句基本上中断了执行,因此必须执行“wrap in function”技巧,这也在下面讨论:

有没有一种静态的方式来抛出exception在PHP中

或者简而言之:

  function throwErrorException($errstr = null,$code = null, $errno = null, $errfile = null, $errline = null) { throw new ErrorException($errstr, 0, $errno, $errfile, $errline); } function warning_handler($errno, $errstr, $errfile, $errline, array $errcontext) { return false && throwErrorException($errstr, 0, $errno, $errfile, $errline); # error_log("AAA"); # will never run after throw /* Do execute PHP internal error handler */ # return false; # will never run after throw } ... set_error_handler('warning_handler', E_WARNING); ... try { mkdir($path, 0777, true); } catch (Exception $e) { echo $e->getMessage(); // ... } 

编辑:仔细检查后,事实certificate它不工作:“ return false && throwErrorException ... ”将基本上, 抛出exception,只是login错误日志; 删除“ false && ”部分,如“ return throwErrorException ... ”,将使exception投掷的工作,但将不会loginerror_log …我仍然保持这张贴,虽然,因为我没有'看不到其他地方logging的这种行为

你也许应该试着完全摆脱这个警告,但如果这是不可能的,你可以用@(即@dns_get_record(…))预先拨打电话,然后使用任何可以得到的信息来判断是否发生警告或不。

通常你不应该使用@除非这是唯一的解决scheme。 在这种情况下,函数dns_check_record应该先用来知道logging是否存在。

如果dns_get_record()失败,它应该返回FALSE ,所以你可以用@来抑制警告,然后检查返回值。

尝试检查它是否返回一些布尔值,然后你可以简单地把它作为一个条件。 我遇到了oci_execute(…),这是返回一些违反我唯一的关键。

 ex. oci_parse($res, "[oracle pl/sql]"); if(oci_execute){ ...do something } 

我只会推荐使用@来压制警告,例如$ prop = @($ high /($ width – $ depth));跳过除零警告。 但在大多数情况下,最好处理。