常用模块之错误处理

第1章 错误报告级别

PHP 程序的错误一般归属于下列三个领域:

语法错误:

语法错误最常见,并且也容易修复。如:代码中遗漏一个分号。这类错误会阻止脚本的执行。

运行时错误:

这种错误一般不会阻止PHP脚本的执行,但会阻止当前要做的事情。输出一条错误,但php脚本继续执行。

逻辑错误:

这种错误最麻烦,既不阻止脚本执行,也不输出错误消息。

案例:

//语法错误,忘记加分号
echo "123"   
 
//运行时错误
echo '123';
function laowang(){
    echo '456';
}

laoliu();

//逻辑错误,想要输出隔壁老王,结果出现的是帽子,在系统角度看,这并不是错误。
if(1==1){
    echo "帽子";
}else{
    echo "隔壁老王";
}

在 PHP 系统中,到底有哪些错误报告级别?

在 php.ini 中可以找到错误级别的说明和设置。

//表示打开所有错误提示但屏蔽NOTICE错误
error_reporting = E_ALL & ~E_NOTICE 

//直接关闭所有错误提示,开发阶段一般是on,但上线以后一般会选择off
display_errors = off/on    
级别常量 错误值 错误报告描述
E_ERROR 1 致命的运行时错误(阻止脚本执行)
E_WARNING 2 运行时警告(非致命性错误)
E_PARSE 4 从语法中解析错误
E_NOTICE 8 运行时注意消息(可能是或可能不是一个问题)
E_CORE_ERROR 16 PHP启动时初始化过程中的致命错误
E_CORE_WARNING 32 PHP启动时初始化过程中的警告(非致命性错)
E_COMPILE_ERROR 64 编译时致命性错
E_COMPILE_WARNING 128 编译时警告(非致命性错)
E_USER_ERROR 256 用户自定义的致命错误
E_USER_WARNING 512 用户自定义的警告(非致命性错误)
E_USER_NOTICE 1024 用户自定义的提醒(经常是bug)
E_STRICT 2048 编码标准化警告(建议如何修改以向前兼容)
E_ALL 6143 所有的错误、警告和注意信息
//错误值一般都是系统定义好的常量
echo E_ERROR; //1

//1 2 4 8 ... 6143原理
//利用的二进制,采用亮灯的原理,错了就亮。
//000000000001 ---> 就是第一个错误

在实际的开发中,没有人关注什么错误级别错误值什么的,报错了,看一眼大概啥类型的,直接找BUG就行了。

在实际的开发中,我们其实需要做大量的错误处理,写功能比较容易,无非就是增删改查,就像汽车,让一辆汽车开起来并不难,但如果要做各种安全防护,就要麻烦的多,考虑的因素也非常多,说明书厚的跟字典一样。

第2章 调整错误报告级别

动态设置 PHP 错误信息是否输出,只在当前脚本生效,并不会影响php.ini全局的设置。

  • display_errors: 是否开启PHP输出错误报告的功能。

    值为:On(默认输出错误报告)、 Off(屏蔽所有错误信息)

    在PHP脚本中可调用ini_set( )函数,动态设置php.ini配置文件.

    如:ini_set("display_errors","On"); //显示所有错误信息

//设置是否输出错误信息
ini_set('display_errors',"off");//关闭
ini_set('display_errors',"on");//开启
ini_set('display_errors',0);//关闭
ini_set('display_errors',1);//开启
//调用函数进行试验
aa();

error_reporting: 设置不同的错误报告级别。

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)

-- 报告除用户导致的错误之外的所有错误。

在PHP脚本可以通过error_reporting( )函数动态设置错误报告级别。如:error_reporting(E_ALL);

//动态设置错误等级
error_reporting(E_ALL);
//试验,报所有错误
echo $a;

//开启除了notice以外的所有错误
error_reporting(E_ALL & ~E_NOTICE);
echo $a;

案例:

ini_set('display_errors',1);//开启
error_reporting(E_ALL);//开启所有错误

$sum=0;//此处如果屏蔽掉,初次使用sum时,变量未定义会notice报错
for($i=0;$i<=10;$i++){
    $sum+=$i;
}
echo $sum;


strlen();//字符串长度函数,不给参数,报warning警告错误,不会影响程序执行
echo "aaaaaaaa";
aa();//致命错误,调用一个不存在的函数时程序会终止运行。

php.ini 中错误设置选项(了解即可,无需深究)。

配置指令 默认值 描述
display_startup_errors Off 是否显示PHP引擎在初始化时遇到的错误
log_errors Off 确定日志语句记录位置
error_log Null 设置错误可以发送到syslog中
log_errors_max_len 1024 每个日志项的最大长度,以字节为单位,设置0表示指定最大长度。
ignore_repeated_errors Off 是否忽略同一个文件、同一行发生的重复错误消息
ignore_repeated_source Off 忽略不同文件中和同一文件中不同行发生的重复错误。
track_errors Off 启动该指令会使PHP在$php_errormsg中存储最近发生的错误信息。

第3章 PHP 日志的记录方式

1)采用文件记录 (推荐使用)。

2) 错误日志记录到操作系统日志中。

思考:为什么要做日志记录?

1.方便自己开发的时候查询,框架一般都自带日志功能,只需要开启就OK。

2.可以借助运行日志开发相应的后台日志功能,给管理员查询,方便管理。

3.1 采用文件记录

先配置 php.ini 文件

error_reporting = E_ALL     //将向PHP发送每个错误
    display_errors=Off          //不显示错误报告
  * log_errors=On               //决定日志语句记录的位置
    log_errors_max_len=1024     //每个日志项的最大长度
  * error_log=G:/myerror.log    //指定错误写进的文件

试验:

a();//注意观察日志文件
conunt();//注意观察日志文件

以上记录的是系统报错的日志。

思考:我能不能做一个用户操作的人为的日志?

使用函数:在 PHP 文件中使用 error_log() 来记录日志,就可以将信息写入到 myerror.log 文件中。

error_log("用户xxx想删除ID为69的用户名,已经记录到日志,请注意这个小子");

参数参考手册。

rigger_error() 函数记录日志

上一节中,我们使用error_log()报一个自定义的错误信息,让系统记录,只记录信息。

而使用 trigger_error() 比 error_log 更加灵活一些,可指定等级和文件位置。

//可利用系统提供的错误等级给日志记录自己定义好的错误信息,默认为notic级别
trigger_error("用户xxx想删除ID为69的用户名,已经记录到日志,请注意这个小子",E_USER_ERROR);

3.2 错误日志记录到操作系统日志中

先配置 php.ini 文件

    error_reporting = E_ALL     //将向PHP发送每个错误
  * display_errors=Off          //不显示错误报告
  * log_errors=On               //决定日志语句记录的位置
    log_errors_max_len=1024     //每个日志项的最大长度
  * error_log=syslog            //指定错误写进的文件

使用四个函数来记录日志:

//define_syslog_variables(); 为系统日志初始化配置
//openlog();                打开一个日志链接
//syslog();                 发送一条日志记录
//closelog();               关闭日志链接

试验:

aa();//不再显示日志,而是记录到系统日志中去了。

目前的开发已经淘汰这种方式,4个函数必须同时使用,课后可自行试验,代码如下:

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

如何查看 Window 系统日志。

计算机右键 ---> 管理(G) ---> 系统工具 ---> 事件查看器 ---> Windows 日志 ---> 应用程序

第4章 自定义错误处理

自定义错误报告的处理方式,可以完全绕过标准的PHP错误处理函数,这样就可以按自己定义的格式打印错误报告,或改变错误报告打印的位置。

说白了就是不使用系统的错误提示,改为自己的。

set_error_handler() -- 设置用户自定义错误处理。

参数:mixed set_error_handler ( callable $error_handler [, int $error_types = E_ALL | E_STRICT ] )

回调函数:回来调取函数。

所谓的回调函数:

function demo(){
    return "我才不要呢";
}

function demo2(){
    return "我也不要";
}
function result($suan){
    return $suan();
}
//将函数名demo1 函数名demo2 作为字符串参数传递给result函数,那么可以自动调用上面的函数,我们就说demo1,demo2是result的回调函数
echo result('demo2');

案例:

//回调函数也需要参数接收,参考手册
/*
errno
第一个参数 errno,包含了错误的级别,是一个 integer。

errstr
第二个参数 errstr,包含了错误的信息,是一个 string。

errfile
第三个参数是可选的,errfile, 包含了发生错误的文件名,是一个 string。

errline
第四个参数是一个可选项, errline, 包含了错误发生的行号,是一个 integer。
*/
function callbackset($errno,$errstr,$errfile,$errline){
    echo "自定义错误处理:错误级别:{$errno},错误信息是:{$errstr}.所在文件:{$errfile}的第{$errline}行";
}


set_error_handler("callbackset");//此处设置为报错的返回信息交给callbackset自行处理

echo $aa;

特别注意:E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING是不会有效果的,通常会用原始的方式显示。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容

  • 简介 PHP提供了错误处理和日志记录的功能. 这些函数允许你定义自己的错误处理规则,以及修改错误记录的方式. 这样...
    零一间阅读 634评论 0 2
  • 文件加载 语法形式:include、include_once、require、require_once4 种语法都...
    THEyAnJ阅读 543评论 0 1
  • PHP错误简介 PHP提供了错误处理和日志记录的功能. 这些函数允许你定义自己的错误处理规则,以及修改错误...
    四月不见阅读 2,453评论 0 7
  • 前言:关于PHP的错误和异常我准备用四大块来说明,内容如下: 一、错误与异常的 区别 异常一般指非语法和编译上的错...
    peanut___阅读 655评论 1 2
  • //禁用错误报告 error_reporting(0); //报告运行时错误 error_reporting(E_...
    沁心轩墨阅读 587评论 1 1