第四章:第44节 PHP基础知识最后一节——PHP错误处理

更新于:2020-12-05 21:32:37

第16节前面讲过一次关于PHP出错的话题,这节楠神又从别的地方搜集了点资料做更详细地介绍。感兴趣的朋友可以继续往下看(东西还是很多的),反正楠神觉着对于初学PHP的朋友暂时没必要细研究这些东西。


错误的分类

语法错误:

    程序没法运行,直接提示语法错误。

 

运行时错误:

只有程序运行到某行,或在某些特定的情形下运行才会发生的错误。

 

逻辑错误:

程序从头到尾运行都没有发生(并提示)错误,但程序运行计算的结果是错误的。

 

我们程序员主要面对的和要处理(应付)的错误,就是运行时错误。

错误的分级

php中,将各种错误,分门别类,依据不同的严重程度和产生的来源(机制),将各种错误分为大约10几个级别。

每个级别的错误,都对应一个内部的名称——系统常量!


1.png

系统错误:

E_ERROR:系统严重错误

一发生,程序立即停止执行。

该错误一般希望马上。

E_WARNING:系统警告

一发生,提示错误,并继续执行。

通常该错误希望能够在“下一工作日”去处理掉(解决)。

E_PARSE:语法错误

一发生,提示错误,而且代码完全不会运行——在运行之前先检查语法。

E_NOTICE:系统提示

一发生,提示错误,并继续执行。

发个邮件通知一下,自己安排时间有空去解决。

 

他们的本质是什么呢?

1.png

1.png


 

可见他们只是一个系统内部常量(整数常量);

实际上,这些常量(代号)是供我们对对该类错误进行“控制”的标示符而已。


用户自定义错误

只有3个:

E_USER_ERROR;

 

E_USER_WARNING;

 

E_USER_NOTICE;

我们可以在程序中,自己创建(生成)错误——是为了针对某些数据的不合理情形,而创建的错误。

比如:让用户填写年龄, 18ok,但填写188就是不合理——从数字角度本身是没有问题。

其他:

E_ALL;          代表所有错误——表示它可以“包括”错误。

E_STRICT:    代表“严格性”语法检查错误——某种语法是可以执行的,但在当前的php版本中是不欢迎使用。


错误的触发

正常触发:

程序运行时确实发生了运行时错误——也可能是语法检查错误。

3种常见的运行时错误:

1.png

1.png

人工触发

就是由程序员通过程序代码而“产生”一个错误。

语法:

trigger_error(“错误提示 用户错误代号);


1.png


1.png


应用中,通常是需要检测(判断)数据的有效性,以决定是否触发相应错误,比如:


1.png


1.png

错误的显示控制

网页中显示(提示)错误信息,是可以进行控制的,有2种途径:

1,在php.ini文件中设定,对所有php程序都有效;

2,在当前脚本文件中,只对当前脚步文件有效。

 

错误的显示有2个方面可以进行控制;

1,设定是否显示:display_error:

php.ini中;display_error = On;   //表示显示, Off表示不显示;

1.png(显示)


脚本中:  ini_set(display_error,  1);  //1表示显示, 0表示不显示,也可以用truefalse

脚本中的设定优先级高。


2,设定显示哪些级别的错误——依赖与第一项设定为显示的情况。

php.ini文件中:

error_reporting = E_NOTICE; //只显示E_NOTICE错误

error_reporting = E_NOTICE | E_WARNING; //显示E_NOTICEE_WARNING错误

error_reporting = E_NOTICE | E_WARNING | E_USER_ERROR;

//显示E_NOTICEE_WARNINGE_USER_ERROR错误

解释上一行::

1.png

 

实际上,在开发阶段,常用的是:

error_reporting = E_ALL | E_STRICT;

它是这样的结果:

1.png

可见,E_ALL并非真的表示“所有”,而是只有E_ALL | E_STRICT才真的表示所有

继续:如果在显示“所有”错误的基础上,只想“关闭”个别少数错误呢?

跟状态数据的设定(关闭)道理一样,只要这么做:

error_reporting = E_ALL | E_STRICT & ~E_NOTICE //只关闭了E_NOTICE错误提示

error_reporting = E_ALL | E_STRICT & ~E_NOTICE & ~E_WARNING//关闭了2

在代码中设定:

ini_set(error_reporting,  E_NOTICE); //只显示E_NOTICE错误

ini_set(error_reporting,  E_NOTICE | E_WARNING); ////显示E_NOTICEE_WARNING错误

ini_set(error_reporting,  E_ALL | E_STRICT & ~E_NOTICE); //只关闭E_NOTICE错误

 

ini_set()含义可以设定几乎所有php.ini中的设定项,形式如下:

ini_set(设定项名称 ,值); //这种设定都只对当前脚本有效,而且无需重启apache,很方便。

另一个对应函数是:ini_get(设定项名称);//用于获取某项的值。

记录错误日志

在开发阶段,我们通常都是显示所有错误——意图解决错误

在产品阶段,我们通常都是隐藏所有错误——并同时将错误信息记录到文件中——错误日志文件。

我们可以自己查看错误日志以解决开发阶段没有发现的错误问题。

记录错误日志同样有2种途径:

1,在Php.ini文件中设定:

log_errors = On //用于设定是否记录错误日志,On记录,Off不记录

       1.png 

error_log = 错误日志文件名; //设定错误日志的文件名

        1.png

此时,该文件没有给定路径,则系统会在每个文件夹下建立该文件并记录进去。

1.png

1.png

可见,页面中显示的错误提示内容,和日志文件中记录的错误信息内容,一样。


error_log还有一个特殊值可以使用:

error_log = syslog;  //此时不会记录错误日志文件,而是把错误信息写入到系统错误日志中

自定义错误处理

以上的错误处理,不管是显示错误,还是记录错误日志,都是php语言内部实现的。

我们只是几个简单的设定是否显示或是否记录或显示哪些,或记录到哪里。

则:

自定义错误处理,就可以让我们自己完全控制错误的提示内容

做法非常简单:

1,设定要用来进行自定义处理错误的自定义函数名;

2,自己去定义该函数,并在其中进行任何错误信息的输出(或记录)。

这两件事做好后,一旦发生错误,则系统就会调用该函数去执行里面的代码——想干嘛干嘛。

1.png


注意:上述自定义处理错误的函数中,只作了“显示错误”的工作,而没有做“记录错误日志”的工作,这需要后续“操作文件”的知识。


测试代码:


1.png

1.png


几点说明:

1,一定是用自定义错误处理程序,则系统不再处理错误。

2,但:如果一旦发生严重错误(E_ERRORE_USER_ERROR),则立即停止程序,并也不去调用自定义错误处理——此时系统错误处理工作会照常进行——即对于严重错误,自定义错误处理函数处理不了


以下级别的错误不能由用户定义的函数来处理: E_ERROR E_PARSE E_CORE_ERROR E_CORE_WARNING E_COMPILE_ERROR E_COMPILE_WARNING ,和在 调用 set_error_handler() 函数所在文件中产生的大多数 E_STRICT

如果错误发生在脚本执行之前(比如文件上传时),将不会 调用自定义的错误处理程序因为它尚未在那时注册。 

在php.ini文件中一定要设置

log_errors = On;
error_log = “错误日志文件名”; //设定错误日志的文件名

这样可以发觉PHP代码中一些严重代码错误问题。


结尾再说点:


一些其他的语言都有try catch语法,PHP也有,就是捕获几行代码可能出现的错误。怎么用,手册上有示例:

1.png


楠神平时写项目基本上没用过这种语法,调试错误习惯了var_dump和exit,错误提示也不这样写。这种语法在其他一些语言是非常流行的写法,比如Java(java是必须要用这种语法处理异常,是强制性的,不然一些代码编译不通过,PHP则不会强制要求),有些人说它是鸡肋,也有人很喜欢用它。下面摘自网友的一些评价供朋友们参考:


JAVA 、C#、python之类的,进行异常处理是必需的。php一般不需要try-catch,当一个项目需要用到try-catch的时候,其实你已经可以考虑是否php真的适合用来做这个项目的问题了。 laruence他们引进try-catch,无非是想向JAVA之流看齐,然而事实是,实际价值并没有JAVA那么强大。

PHP5早期版本对异常捕获的确是支持的不够好,很多系统级异常没办法捕获,对比起来,Java的异常处理体系是比较完备的,不过最新版的php我之前看鸟哥博客说是支持try catch finally了,try catch和exit这种其实是两个完全没有任何关联的东西,try catch对于复杂的系统来说是很有必要的,为整个系统设计一个好的异常处理体系,会让你整个程序非常健壮,而不是说 只要一有异常,就直接exit了,举个简单例子,如果直接这么暴力,线上出现问题了,程序员根本就没办法去定位问题,是吧。


php错误处理知识了解》更多了解try-catch


本节学习代码》》》