由于常规操作可能发生的错误情况,有很多好的旧程序函数会发出警告,例如: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()}");
}
即使在配置正确的服务器中,让警告通过也很烦人:
建议的做法是什么? PHP大师如何处理它?</ p>
答案 0 :(得分:1)
error_log不是无用的数据
我发现,如果有一个每小时的cron作业将error_log文件的内容通过电子邮件发送给某人,通常很容易掌握.....
很快你就会在相应的检查中添加代码库和排序的问题。
答案 1 :(得分:1)
我在一些流行的PHP框架和流行的Packagist软件包中做了一个快速肮脏倾斜的不科学调查,发现了这个:
set_error_handler()
抛出ErrorException
或其他一些异常(Zend,Symfony,Laravel,PHPUnit,Psy ......)。大多数只是使用项目范围的错误处理程序,一些(PHPMailer)在set / restore调用中包装特定的操作。我说:
(*)我找到了无数的基准,可以比较@
与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