处理不可避免警告的正确方法

时间:2015-07-13 13:01:42

标签: php

由于常规操作可能发生的错误情况,有很多好的旧程序函数会发出警告,例如:fopen()mail()oci_connect()。 ..

  • 据说most obvious workaround价格昂贵且隐藏所有内容的副作用

    echo @file_get_contents(oops_forgot_dollar);
    
  • 自定义错误处理程序看起来有点过分:

    private function warningHandler($errno, $errstr, $errfile, $errline/*, array $errcontext*/){
        if(error_reporting()===0){
            return false;
        }else{
            throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
        }
    }
    
    // ....
    
    try{
        set_error_handler('CSVLoader::warningHandler', E_WARNING);
        $this->fp = fopen($filename, 'r');
        restore_error_handler();
    
        $this->readData();
    }catch(ErrorException $e){
        restore_error_handler();
        throw new CSVLoaderException("Could not open file: {$e->getMessage()}");
    }
    
  • 即使在配置正确的服务器中,让警告通过也很烦人:

    • developpement 中,它们会在不知名的地方显示并且可能会破坏事物
    • 生产中,他们使用无用数据填充错误日志

建议的做法是什么? PHP大师如何处理它?<​​/ p>

2 个答案:

答案 0 :(得分:1)

error_log不是无用的数据

我发现,如果有一个每小时的cron作业将error_log文件的内容通过电子邮件发送给某人,通常很容易掌握.....

很快你就会在相应的检查中添加代码库和排序的问题。

答案 1 :(得分:1)

我在一些流行的PHP框架和流行的Packagist软件包中做了一个快速肮脏倾斜的不科学调查,发现了这个:

  • 错误抑制运算符相当受欢迎(CodeIgniter,Nette,Swift Mailer,Yii ......)。
  • 相当其他项目使用set_error_handler()抛出ErrorException或其他一些异常(Zend,Symfony,Laravel,PHPUnit,Psy ......)。大多数只是使用项目范围的错误处理程序,一些(PHPMailer)在set / restore调用中包装特定的操作。
  • 其他一些项目显然不在乎(PHPExcel)。

我说:

  • 如果您已经有自定义错误处理程序,那么最好利用它。
  • 否则,错误控制操作符可以很好(但是在开发那段代码时暂时删除它可能是个好主意)。所谓的不良表现doesn't seem to be a big deal无论如何*,尤其是如果你正在做一个慢的&#34;打开数据库连接,套接字或文件等操作。
  • 作为辩论,它可能与标签与空格位于同一区域。

(*)我找到了无数的基准,可以比较@isset(),并确定@非常慢。真正发生的是isset()非常快 - 实际上是much faster that not using either

最后但并非最不重要的是,由于性能很重要,我将分享我的第一个家酿基准 - 再一次快速而肮脏的基准测试,没有适当的基准测试框架。请注意我到目前为止仅测试最差情况(所有函数调用都会生成警告):

<?php

error_reporting(-1);
ini_set('display_errors', false);
ini_set('log_errors', false);


define('ITERATIONS', 10000);


function warning_handler($errno, $errstr, $errfile, $errline/*, array $errcontext*/){
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}


echo sprintf('Running %s iterations on PHP/%s...' . PHP_EOL, number_format(ITERATIONS), phpversion());


$t0 = microtime(true);
for($i=0; $i<ITERATIONS; $i++){
    fopen("FooA $i", 'r');
}
echo sprintf('Raw:                         % 6.3fs' . PHP_EOL, microtime(true) - $t0);


$t0 = microtime(true);
for($i=0; $i<ITERATIONS; $i++){
    @fopen("FooB $i", 'r');
}
echo sprintf('@:                           % 6.3fs' . PHP_EOL, microtime(true) - $t0);


$t0 = microtime(true);
for($i=0; $i<ITERATIONS; $i++){
    set_error_handler('warning_handler', E_WARNING);
    try{
        fopen("FooC $i", 'r');
        restore_error_handler();
    }catch(ErrorException $e){
        restore_error_handler();
    }
}
echo sprintf('Local set_error_handler():   % 6.3fs' . PHP_EOL, microtime(true) - $t0);


$t0 = microtime(true);
set_error_handler('warning_handler', E_WARNING);
for($i=0; $i<ITERATIONS; $i++){
    try{
        fopen("FooD $i", 'r');
    }catch(ErrorException $e){
    }
}
restore_error_handler();
echo sprintf('General set_error_handler(): % 6.3fs' . PHP_EOL, microtime(true) - $t0);

我的Windows 7盒子上的结果(x86 PHP版本):

Running 10,000 iterations on PHP/5.3.28...
Raw:                          1.388s
@:                            1.232s
Local set_error_handler():    1.638s
General set_error_handler():  1.497s
Running 10,000 iterations on PHP/5.4.24...
Raw:                          1.170s
@:                            1.185s
Local set_error_handler():    1.357s
General set_error_handler():  1.326s
Running 10,000 iterations on PHP/5.5.22...
Raw:                          1.185s
@:                            1.341s
Local set_error_handler():    4.960s
General set_error_handler():  4.570s
Running 10,000 iterations on PHP/5.6.10...
Raw:                          1.139s
@:                            1.139s
Local set_error_handler():    1.263s
General set_error_handler():  1.232s
Running 10,000 iterations on PHP/7.0.0beta1...
Raw:                          1.232s
@:                            1.279s
Local set_error_handler():    1.669s
General set_error_handler():  1.669s