众所周知,在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()
等更加规范的方法避免此类问题。
以上,是个人整理,希望对大家有帮助。