PHP 程序的错误通常归属于下列三个领域:php
语法错误:安全
语法错误最多见,而且也容易修复。如:代码中遗漏一个分号。这类错误会阻止脚本的执行。 服务器
运行时错误:框架
这种错误通常不会阻止PHP脚本的执行,但会阻止当前要作的事情。输出一条错误,但php脚本继续执行。函数
逻辑错误:工具
这种错误最麻烦,既不阻止脚本执行,也不输出错误消息。编码
图解 Apache Web 服务器与 PHP 引擎的关系。操作系统
案例:.net
//语法错误,忘记加分号 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就好了。
在实际的开发中,咱们其实须要作大量的错误处理,写功能比较容易,无非就是增删改查,就像汽车,让一辆汽车开起来并不难,但若是要作各类安全防御,就要麻烦的多,考虑的因素也很是多,说明书厚的跟字典同样。
动态设置 PHP 错误信息是否输出,只在当前脚本生效,并不会影响php.ini全局的设置。
值为: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 = 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中存储最近发生的错误信息。 |
1)采用文件记录 (推荐使用)。
2) 错误日志记录到操做系统日志中。
思考:为何要作日志记录?
1.方便本身开发的时候查询,框架通常都自带日志功能,只须要开启就OK。
2.能够借助运行日志开发相应的后台日志功能,给管理员查询,方便管理。
先配置 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);
先配置 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 日志 ---> 应用程序
自定义错误报告的处理方式,能够彻底绕过标准的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是不会有效果的,一般会用原始的方式显示。