PHP语言学习之11. php的错误和异常处理(一)
小标 2019-02-22 来源 : 阅读 1019 评论 0

摘要:本文主要向大家介绍了PHP语言学习之11. php的错误和异常处理(一),通过具体的内容向大家展示,希望对大家学习php语言有所帮助。

本文主要向大家介绍了PHP语言学习之11. php的错误和异常处理(一),通过具体的内容向大家展示,希望对大家学习php语言有所帮助。

PHP语言学习之11. php的错误和异常处理(一)

1. 错误的分类




  1. 语法错误 

    • 程序无法运行,直接显示语法错误(最容易修复)


  2. 运行时错误 

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


  3. 逻辑错误 

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




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






2. 错误的报告级别



级别常量错误报告描述对应整数值
E_ERROR致命的运行时错误(它会阻止脚本的执行)1
E_WARNING运行时警告(非致命错误)2
E_PARSE从语法中解析错误4
E_NOTICE运行时注意消息(可能或者可能不是一个问题)8
E_CORE_ERROR类似E_ERROR, 但不包括PHP核心造成的错误16
E_COMPILE_ERROR致命的编译时错误64
E_COMPILE_WARNING致命的编译时警告128
E_USER_ERROR用户导致的错误消息256
E_USER_WARNING用户导致的警告512
E_USER_NOTICE用户导致的注意消息1024
E_ALL所有的错误,警告和注意2047
E_STRICT关于PHP版本移植的兼容性和互操作性建议



如果希望显示错误消息,则需要在php.ini中将display_errors设置为on,开启PHP输出错误报告的功能,



;//php.net/display-errors
display_errors = on



也可以在php脚本中调用ini_set()函数,动态设置配置文件php.ini中的某个指令。



<?php
ini_set(‘display_errors‘,true);






3. 调整错误报告级别




  1. 通过设置php.ini中,修改error_reporting的值,修改成功后重启web服务器。可以把位运算符[&(与),|(或),~(非)]和错误级别一起使用




;可以抛出任何非注意的错误,默认值
error_reporting = E_ALL&~E_NOTICE
;只考虑致命的运行时错误,解析错误和核心错误
;error_reporting = E_ERROR|E_PARSE|E_CORE_ERROR
;报告除了用户导致的错误之外的所有错误
;error_reporting = E_ALL&~(E_USER_ERROR|E_USER_WARNING|E_USER_NOTICE)



解释一下,具体解释看前面的博文



E_NOTICE:       00000000 00001000
E_WARNING       00000000 00000010
E_USER_ERROR:  00000001 00000000
或运算(|)       00000001 00001010

实际上,在开发阶段,常用的是:
error_reporting = E_ALL | E_STRICT;
它是这样的结果:
E_ALL           01110111 11111111
E_STRICT:       00001000 00000000
或运算(|)       01111111 11111111




  • 可以使用error_reporting()函数,基于各个脚本来调整这种行为




<?php
error_reporting(0);//设置为0会完全关闭错误报告
error_reporting(E_ALL);//将会向PHP报告发生的每个错误
error_reporting(E_ALL&~E_NOTICE);//可以抛出任何非注意的错误报告




  • 使用ini_set()直接设定




<?php
ini_set(“error_reporting”,  E_NOTICE);    //只显示E_NOTICE错误
ini_set(“error_reporting”,  E_NOTICE | E_WARNING);  ////显示E_NOTICE和E_WARNING错误
ini_set(“error_reporting”,  E_ALL | E_STRICT & ~E_NOTICE);    //只关闭E_NOTICE错误

ini_set();//含义可以设定几乎所有php.ini中的设定项,形式如下:
ini_set(“设定项名称” ,值);//这种设定都只对当前脚本有效,而且无需重启apache,很方便。
//另一个对应函数是:
ini_get(“设定项名称”);//用于获取某项的值。



4. 使用trigger_error()函数来替代die()



函数die()等同于exit(),两者如果执行都会中止PHP程序,而trigger_error()则可以生成一个用户警告来代替。例如,trigger_error("没有找到文件",E_USER_ERROR),使用trigger_ERROR()函数来替代die(),则代码在处理错误上会更具优势。






5. 自定义错误处理



以下几种情况可以考虑自定义错误处理。




  • 可以记下错误信息。及时发现一些生产环境出现的问题


  • 可以用来屏蔽错误。防止信息暴漏给用户,极有可能被黑客攻击


  • 可以做相应的处理,将所有错误报告放到脚本最后输出。或出错时可以显示跳转到预定义好的出错页面,提供更高的用户体验,如果必要,还可以在自定义的错误处理程序中,根据情况去终止脚本运行


  • 可以作为调试工具,




通常使用set_error_handler()函数去设置用户自定义的错误处理函数,该函数用于创建运行时期自己定义的错误处理方法,返回旧的错误处理程序,若失败,则返回null。



该函数有两个参数,其中第一个参数是必选的,需要一个回调函数,规定发生错误时运行的函数。这个回调函数一定要声明4个参数,否则无效,按顺序分别为是否存在错误,错误信息,错误文件和错误行号。set_error_handler()函数的第二个参数则为可选的,规定在哪个错误报告级会显示用户定义的错误。默认是”E_ALL”.例如:



<?php
error_reporting(0);
//屏蔽程序中的错误
function error_handler($error_level, $error_message, $file, $line) {
    $exit = FALSE;
    switch ($error_level) {
        //提醒级别
        case E_NOTICE:
        case E_USER_NOTICE;
            $error_type = ‘Notice‘;
            break;
        //警告级别
        case E_WARNING;
        case E_USER_WARNING;
            $error_type = ‘Warning‘;
            break;
        //错误级别
        case E_ERROR;
        case E_USER_ERROR;
            $error_type = ‘Fatal Error‘;
            $EXIT = TRUE;
            break;
        default:
            $error_type = ‘Unknown‘;
            break;
    }
    //直接打印错误信息,也可以写成文件,写数据库
    printf("<font color=‘#FF0000‘><b>%s</b></font>:%s in <b>%s</b> on line <b>%d</b><br>\n", $error_type);
    //如果错误影响到程序的正常执行,跳转到友好的错误提示页面
    if (TRUE == $EXIT){
        echo ‘<script>location="err.html";</script>‘;
    }
}

//这才是真正的关键点,把错误的处理交给error_handler();
set_error_handler(‘error_handler‘);
//使用未定义的变量会报notice
echo $novar;
//除以0会报警告
echo 3 / 0;
//自定义一个错误
trigger_error(‘Trigger a fatal error‘ . E_USER_ERROR);
echo "ddddd";



系统直接报Fatal Error的这里捕获不到,因为系统不可能把这么大的错误交给你处理



注意:




  1. E_ERROR,E_PARSE,E_CORE_ERROR,E_CORE_WARNING,E_COMPILE_ERROR,E_COMPILE_WARNING不会被这个句柄处理的,也就是会用最原始的方式显示出来,不过出现这些错误都是编译或PHP内核出错,在通常情况下不会发生。



    • 使用set_error_handler()后,error_reporting()将会失效。也就是所有的错误(除了上面提到的)都会交给自定义的函数处理




6. 写错误日志



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

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



6.1 使用指定文件记录错误报告日志



如果使用自己指定的文件记录错误日志,一定要确保将这个文件存放在文档根目录之外,以减少遭到攻击的可能。并且文件一定要让PHP脚本的执行用户(web服务器进程所有者)具有写权限。



error_reporting = E_ALL ;将会项PHP报告发生的每个错误
display_errors = off ;不显示满足上条指令所定义规则的所有错误报告
log_errors = On ;决定日志语句记录的设置
log_errors_max_len = 1024   ;设置每个日志项的最大长度
error_log = /usr/local/error.log   ;指定产生的错误报告写入的日志位置
;此时,该文件没有给定路径,则系统会在每个文件夹下建立该文件并记录进去。



使用PHP中的error_log()函数,送出一个用户自定义的错误信息,该函数的原型如下所示:



bool error_log(string message [,int message_type [,string destination [,string extra_headers]]])



此函数会送出错误信息到web服务器的错误日志文件,某个TCP服务器或到指定文件中。该函数执行成功则返回true,失败则返回false.




  1. 第一个参数message是必选项,即为要送出的错误信息。如果仅使用这一参数,会按配置文件中php.ini中所设置的位置处发送消息。 

    • 第二个参数message_type为整数值:0表示送到操作系统的日志中;1则使用PHP的Mail()函数,发送信息到某E-mail处,第四个参数extra_headers也会用到;2则将错误信息送到TCP服务器中,此时第三个参数destination表示目的地IP及port;3则将信息存到文件destination中。




<?php
error_log("出麻烦了",0);    //写入操作系统日志中
error_log("出现麻烦了",1,"the_victory@mydomain.com");    //发送到管理员邮箱中
error_log("搞砸了", 2, "localhost:5000");  //发送到本机对应5000端口的服务器中
error_log("搞砸了", 3, "/usr/local/errors.log");



6.2 错误信息记录到操作系统的日志里



错误报告也可以记录在操作系统日志里,Linux系统中错误语句将送往syslog,而在windows中错误将发送到事件日志里。



error_reporting = E_ALL ;将会项PHP报告发生的每个错误
display_errors = off ;不显示满足上条指令所定义规则的所有错误报告
log_errors = On ;决定日志语句记录的设置
log_errors_max_len = 1024   ;设置每个日志项的最大长度
error_log = syslog   ;指定产生的错误报告写入的操作系统的日志



php允许向系统syslog中发送定制的消息。PHP提供了需要一起使用的4个专用函数。




  1. define_syslog_variables() 在使用openlog(),syslog()以及closelog()函数之前必须调用的函数。它会初始化一些必须的常量


  2. openlog()     打开一个和当前系统中日志器的连接,为向系统插入日志消息做好准备,并将提供的第一个字符串参数插入到每个日志消息中,该函数还需要指定两个将在日志上下文使用的参数,可以参考官方文档使用。


  3. syslog() 该函数向系统日志中发送一个定制消息。必选两个参数,1.通过指定一个常量定制消息的优先级。例如LOG_WARNING表示一般的警告,LOG_EMERG`表示严重的预示着系统给崩溃的问题等。第二个参数则是向系统日志中发送定制消息,需要提供一个消息字符串,也可以是PHP引擎在运行时的错误字符串


  4. closelog()    关闭日志连接。




如果已经开启了syslog,则例如:



<?php
define_syslog_variables();
openlog("PHP5",LOG_PID, LOG_USER);
syslog(LOG_WARNING,"警告报告向syslog发送的演示,警告时间:".date("Y/m/d H:i:s"));
closelog();

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言PHP频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程