衆所周知,在php中,如果調用一個不存在的數組的key,會有notice提示,如果開啓了display_errors => On
,則會輸出該notice提示
notice: undefined index: --------
然而,印象中偶爾會直接拋異常,阻斷程序的運行
ErrorException : Undefined index: category_template
那麼什麼時候會是error呢?什麼時候又是notice呢?
- 是否和php版本有關?
於是用 5.4、5.5、5.6、7+ 幾個不同版本的php簡單試了下
$a = array();
echo $a['test'];
//null
均返回null,沒有任何異常,和我們想的一毛一樣。
那麼,確定和php版本無關
- 到底異常是誰拋的?
仔細看了下error信息,來自Illuminate\Foundation\Bootstrap\HandleExceptions::handleError
想起來貌似只有在使用laravel框架時碰到的,第一時間想到的是laravel框架對notice級別的錯誤拋出異常
找到相應代碼
public function handleError($level, $message, $file = '', $line = 0, $context = [])
{
if (error_reporting() & $level) {
throw new ErrorException($message, 0, $level, $file, $line);
}
}
很明顯,和預想的一樣。於是打印下當前我的error_reporting()結果
echo error_reporting();
// -1 (即所有錯誤類型 E_ALL)
在來看下php.ini的配置信息
$ cat /yourpath/php.ini |grep error_reporting
error_reporting = E_ALL & ~E_NOTICE
//這裏注意到依舊是排除了 notice 了,但是
//或者
$ php -i |grep error_reporting
error_reporting => 32759 => 32759
這裏注意這個32759不是任何的error等級常量,而是按位與來的
php -r ‘echo E_ALL & ~E_NOTICE | E_STRICT;’ # should return 32759
另外提一句PHP 5.3中的值爲22527,PHP 5.4中的值爲24575
至此,產生的原因就找到了,那麼解決辦法可以通過以下方法:
- 在
index.php
入口文件中設置錯誤等級
error_reporting(E_ERROR);
- 修改php.ini文件中的對php錯誤等級的設置
$ vim /yourpath/php.ini
error_reporting = E_ERROR
但其實以上兩種方式都無法很有效的解決問題,因爲在框架運行過程中,會有在某些過程中會執行 error_reporting(-1);
的操作(可以全局搜索一下),所以php.ini的原本的設置實際到你代碼運行的位置已經不一致了,而如果在index.php
文件等初始位置加上error_reporting(E_ERROR);
,在中途也會被重置成all,不過可以在具體的代碼置調用,比如某個控制器中等等。不過還是建議通過isset()
等更加規範的方法避免此類問題。
以上,是個人整理,希望對大家有幫助。