PHP10 错误和异常处理
学习要点
- 修改错误报告级别
- 写错误日志
- 异常处理实现
- 自定义异常
- 捕获多路异常
错误处理
定义
- 错误:开发过程中的失误、用户操作引起的错误。
- 错误产生原因
- 语法错误:开发环境提示,未修正则脚本无法运行。
- 运行时错误:脚本无法正确运行。例如双引号字符串对变量的解析。
- 逻辑错误:常见的逻辑运算错误,循环条件设置错误等等。
错误报告级别
1、WAMP作为开发环境,在php.ini配置文件中,有两个参数设置:
- display_errors = on
注释:PHP解析器将会输出错误报告的功能。如果是产品正式发布部署,需要在PHP服务器上把此项值值为off。
- error_reporting = E_ALL
注释:PHP解析器将输出每个错误。
2、PHP的错误报告级别:
|
值 |
常量 |
描述 |
|
1 |
E_ERROR |
Fatal run-time errors. Errors that can not be recovered from. Execution of the script is halted |
|
2 |
E_WARNING |
Non-fatal run-time errors. Execution of the script is not halted |
|
4 |
E_PARSE |
Compile-time parse errors. Parse errors should only be generated by the parser |
|
8 |
E_NOTICE |
Run-time notices. The script found something that might be an error, but could also happen when running a script normally |
|
16 |
E_CORE_ERROR |
Fatal errors at PHP startup. This is like an E_ERROR in the PHP core |
|
32 |
E_CORE_WARNING |
Non-fatal errors at PHP startup. This is like an E_WARNING in the PHP core |
|
64 |
E_COMPILE_ERROR |
Fatal compile-time errors. This is like an E_ERROR generated by the Zend Scripting Engine |
|
128 |
E_COMPILE_WARNING |
Non-fatal compile-time errors. This is like an E_WARNING generated by the Zend Scripting Engine |
|
256 |
E_USER_ERROR |
Fatal user-generated error. This is like an E_ERROR set by the programmer using the PHP function trigger_error() |
|
512 |
E_USER_WARNING |
Non-fatal user-generated warning. This is like an E_WARNING set by the programmer using the PHP function trigger_error() |
|
1024 |
E_USER_NOTICE |
User-generated notice. This is like an E_NOTICE set by the programmer using the PHP function trigger_error() |
|
2048 |
E_STRICT |
Run-time notices. PHP suggest changes to your code to help interoperability and compatibility of the code |
|
4096 |
E_RECOVERABLE_ERROR |
Catchable fatal error. This is like an E_ERROR but can be caught by a user defined handle (see also set_error_handler()) |
|
8191 |
E_ALL |
All errors and warnings, except level E_STRICT (E_STRICT will be part of E_ALL as of PHP 6.0) |
3、开启错误报告
处理在php.ini文件中配置,如果对服务器权限不够,可以采用ini_set()函数设置:
例如:
ini_set(‘display_errors’,1);
调整错误报告级别
1、在php.ini中修改配置指令error_reporting的值
默认值:
error_reporting = E_ALL
修改示例1(结合位运算符&,|,~):除运行时注意消息外的全部错误报告
error_reporting = E_ALL&~E-NOTICE;
修改示例2:只考虑运行时错误、解析错误、核心错误
error_reporting = E_ERROR | E_PARSE | E_CORE_ERROR
2、在脚本中使用error_reporting()函数
权限不够,或者需要个性化页面错误报告,采用该函数。
error_reporting(0); //完全关闭错误报告 error_reporting(E_ALL); //报告任何错误 error_reporting(E_ALL&~E_NOTICE); //报告除注意外的任何错误
示例:
/* 开启php.ini中的display_errors指令*/
ini_set ( 'display_errors', 1);
/* 通过error_reporting()函数设置在本脚本中,输出所有级别的错误报告 */
error_reporting ( E_ALL );
//error_reporting ( E_ALL &~(E_WARNING|E_NOTICE));
/* “注意(notice)”的报告,不会阻止脚本的执行,并且可能不一定是一个问题 */
getType ( $var ); // 调用函数时提供的参数变量没有在之前声明
/* “警告(warning)”的报告,指示一个问题,但是不会阻止脚本的执行 */
getType (); // 调用函数时没有提供必要的参数
/* “错误(error)”的报告,它会终止程序,脚本不会再向下执行 */
get_Type (); // 调用一个没有被定义的函数
使用trigger_error()函数代替die()函数
die()等同于exit(),会退出程序。而trigger_error()可以生成一个用户警告来代替退出程序。
示例代码:
//die("程序运行结束!");
trigger_error("there is a bugbugbug!",E_USER_WARNING);
echo "这里是php文件尾巴";
自定义错误处理
1、需要自定义错误信息的情形
- 记录错误信息
- 屏蔽错误信息
- 错误统一输出页面处理或者同一页面位置输出错误信息
- 调试
2、如何自定义错误处理
用户自定义错误处理函数:set_error_handler()
语法格式:
mixed set_error_handler ( callable $error_handler [, int $error_types = E_ALL | E_STRICT ] )
参数说明:
error_handler:
handler ( int $errno , string $errstr [, string $errfile [, int $errline [, array $errcontext ]]] ) //四个参数含义:错误级别、错误信息、错误所在文件,错误所在文件第几行
error_types:
错误报告级别。默认E_ALL。
示例代码:
// 屏蔽所有错误报告
error_reporting ( 0 );
function error_handler($error_level, $error_message, $file, $line) {
$EXIT = false;
$error_type='';
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';
break;
//未知错误
default:
$error_type = 'Unknown';
$EXIT=true;
break;
}
//打印错误信息,可以自定义错误格式
printf("%s,%s,%s,%d",$error_type,$error_message,$file,$line);
if(true==$EXIT){
echo '<script>location="error.php";</script>';
}
}
set_error_handler('error_handler');
//echo $novar;
echo 3/0;
注意:
1、set_error_handler()不处理以下错误报告:E_ERR0R、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING。不处理不等于不显示错误信息,它不会按照用户设定格式显示。
2、除了第1条中列出的错误,在使用了set_error_handler()函数后,所有的错误都交给用户处理。
上机练习1:自定义错误处理
1、 set_error_handler()函数的用法
2、 自定义回调函数
3、 错误报告格式:
写错误日志
PHP项目部署运行后,一般display_errors = off。程序日常运行的错误信息是需要记录下来,作为运维参考,如何处理?有两种记录日志的方式:
1、使用指定的文件记录错误报告日志
php.ini配置
error_reporting = E_ALL
display_errors = off
log_errors=on
log_errors_max_len = 1024
error_log = "d:/wamp/logs/php_error.log"
error_log()函数
//写入操作系统日志 (需要php.ini中设置error_log=syslog)
error_log("error message",0);
//发送到电子邮件(需要邮件服务器)
error_log("error message",1,"2083967667@qq.com");
//发送到某个ip的某个端口
error_log("error message",2,"localhost:5000");
//写入到某个路径文件中
error_log("error message",3,"er.log");
2、错误信息记录到操作系统日志中
php.ini配置
error_reporting = E_ALL
display_errors = off
log_errors=on
log_errors_max_len = 1024
error_log = syslog
使用syslog向系统发送订制消息
//php5.3开始,已经废除相关函数 define_syslog_variables(); ……
异常处理
定义
Exception:在程序执行过程中出现的一个例外或是一个事件,它中断了正常指令的运行,跳转到其他程序模块继续执行。
简单异常处理
1、语法结构
try{
//需要捕获异常的代码块
}catch (Exception $ex1){
//处理异常
} finally {
//始终被执行的代码
}
2、示例代码
try {
$number = 100;
$div = 0;
if ($div == 0) {
throw new Exception ( "除数不能为0" );
}
$result=$number/$div;
echo '计算结果'.$result;
} catch ( Exception $e ) {
echo '程序异常:'.$e->getMessage();
}finally {
echo '<br>finally代码始终执行';
}
echo '<br>程序继续执行';
自定义异常处理类
1、内置Exception类结构
class Exception {
protected $message = 'Unknown exception'; // 异常信息
protected $code = 0; // 用户自定义异常代码
protected $file; // 发生异常的文件名
protected $line; // 发生异常的代码行号
function __construct($message = null, $code = 0);
final function getMessage(); // 返回异常信息
final function getCode(); // 返回异常代码
final function getFile(); // 返回发生异常的文件名
final function getLine(); // 返回发生异常的代码行号
final function getTrace(); // backtrace() 数组
final function getTraceAsString(); // 已格成化成字符串的 getTrace() 信息
/* 可重载的方法 */
function __toString(); // 可输出的字符串
}
2、自定义异常处理类
/* 自定义异常处理类 */
class MyException extends Exception {
// 重写构造函数
public function __construct($message, $code = 0) {
parent::__construct ( $message, $code );
}
/*重写父类__toString魔术方法*/
public function __toString() {
return __CLASS__ . ":[" . $this->code . "]:" . $this->message . "<br>";
}
/*自定义异常方法*/
public function customFunction() {
echo "按自定义的方法处理出现的这个类型的异常<br>";
}
}
try {
$error = '允许抛出这个错误';
throw new MyException ( $error );
echo '出现异常,不被执行的代码.....';
} catch ( MyException $e ) {
echo '捕获异常: ' . $e;
$e->customFunction ();
}
echo '程序继续执行......';
上机练习2:自定义异常处理
多路异常捕获
class MyException extends Exception {
public function __construct($message, $code = 0) {
parent::__construct ( $message, $code );
}
public function __toString() {
return __CLASS__ . ":[" . $this->code . "]:" . $this->message . "<br>";
}
public function customFunction() {
echo "按自定义的方法处理出现的这个类型的异常";
}
}
class TestException {
public $var;
function __construct($value = 0) {
switch ($value) {
case 1 :
throw new MyException ( "传入的值“1” 是一个无效的参数", 5 );
break;
case 2 :
throw new Exception ( "传入的值“2”不允许作为一个参数", 6 );
break;
default :
$this->var = $value;
break;
}
}
}
// 示例1,在没有异常时,程序正常执行,try中的代码全部执行并不会执行任何catch区块
$testObj=null;
try {
$testObj = new TestException (); // 使用默认参数创建异常的测试类对象
echo "***********<br>"; // 没有抛出异常这条语句就会正常执行
} catch ( MyException $e ) { // 捕获用户自定义的异常区块
echo "捕获自定义的异常:$e <br>"; // 按自定义的方式输出异常消息
$e->customFunction (); // 可以调用自定义的异常处理方法
} catch ( Exception $e ) { // 捕获PHP内置的异常处理类的对象
echo "捕获默认的异常:" . $e->getMessage () . "<br>"; // 输出异常消息
}
var_dump ( $testObj ); // 判断对象是否创建成功,如果没有任何异常,则创建成功
// 示例2,抛出自定义的异常,并通过自定义的异常处理类捕获这个异常并处理
$testObj1=null;
try {
$testObj1 = new TestException ( 1 ); // 传入参数1时,创建测试类对象抛出自定义异常
echo "***********<br>"; // 这个语句不会被执行
} catch ( MyException $e ) { // 这个catch区块中的代码将被执行
echo "捕获自定义的异常:$e <br>";
$e->customFunction ();
} catch ( Exception $e ) { // 这个catch区块不会执行
echo "捕获默认的异常:" . $e->getMessage () . "<br>";
}
var_dump ( $testObj1 ); // 有异常产生,这个对象没有创建成功
//示例2,抛出内置的异常,并通过自定义的异常处理类捕获这个异常并处理
$testObj2=null;
try {
$testObj2 = new TestException ( 2 ); // 传入参数2时,创建测试类对象抛出内置异常
echo "***********<br>"; // 这个语句不会被执行
} catch ( MyException $e ) { // 这个catch区块不会执行
echo "捕获自定义的异常:$e <br>";
$e->customFunction ();
} catch ( Exception $e ) { // 这个catch区块中的代码将被执行
echo "捕获默认的异常:" . $e->getMessage () . "<br>";
}
var_dump ( $testObj2 ); // 有异常产生,这个对象没有创建成功
PHP10 错误和异常处理的更多相关文章
- PHP错误以及异常处理
以前一直觉得php的异常处理没有什么,现在才发现这个还真是门学问,于是狠下心来好好研究了一下,写一篇文章,也作备忘吧. 1. php错误 无论是什么语言编程,都会有如下三种错误,当然php也不例外. ...
- Yii中的错误及异常处理
Yii中的错误及异常处理 Yii已经默认已经在CApplication上实现了异常和错误的接管,这是通过php的set_exception_handler, set_error_handler实现的. ...
- 再谈PHP错误与异常处理
博客好久没有更新了,实在惭愧,最近在忙人生大事,哈哈!这段时间没有看什么新的东西,结合项目中遇到的PHP异常处理问题,我又重新梳理了之前模糊的概念,希望对大家理解PHP异常处理有所帮助. 请一定要注意 ...
- Golang错误和异常处理的正确姿势
Golang错误和异常处理的正确姿势 错误和异常是两个不同的概念,非常容易混淆.很多程序员习惯将一切非正常情况都看做错误,而不区分错误和异常,即使程序中可能有异常抛出,也将异常及时捕获并转换成错误.从 ...
- 【PHP】解析PHP中的错误和异常处理
目录结构: contents structure [-] 错误级别 自定义处理器 设置异常日志 自定义异常类 在这篇文章中,笔者将会阐述PHP中的异常处理,希望能够对你有所帮助. 1.错误级别 PHP ...
- ThinkPHP5.0源码学习之注册错误和异常处理机制
在base.php文件中,用一句代码\think\Error::register();实现错误和异常处理机制的注册. // 注册错误和异常处理机制 \think\Error::register(); ...
- 2018/05/02 PHP 之错误与异常处理
在学习中,越学习越觉得自己基础薄弱. 在平常工作中,对于某些错误处理感觉不知道怎么下手,于是决定重新再整理一下. 强烈推荐这篇文章,真的感觉学习到了很多. 部分引用::再谈PHP错误与异常处理 -- ...
- PHP 注册错误和异常处理机制
注册错误和异常处理机制有三个PHP函数需要学习 1. register_shutdown_function('Bootstrap\Library\Frame::fatalError'); 2. set ...
- PHP常用功能块_错误和异常处理 — php(32)
一.错误和异常处理 1.1 错误类型和基本的调试方法PHP程序的错误发生一般归属于下列三个领域: 语法错误:语法错误最常见,并且也容易修复.如:代码中遗漏一个分号.这类错误会阻止脚本的执行. 运行时错 ...
随机推荐
- Codechef SUMCUBE
SUMCUBE code 给定无向简单图 G = (V, E)(即不存在自环和重边),以及 k = 1, 2, 或3 .求$$ \sum_{S \subseteq V} f(S)^k, $$其中 $f ...
- Table View Programming Guide for iOS---(五)---Creating and Configuring a Table View
Creating and Configuring a Table View Your app must present a table view to users before it can mana ...
- windows下patch
经常在网上看到有人发布patch文件来更新他们的开源代码,例如cegui.ogre等都使用这种形式来修bug或者增加一些小功能.但是,我们下载到的patch文件,貌似是linux/unix的diff工 ...
- poj2385【基础DP】
挑战DP 题意: 有两棵树,给每分钟有苹果掉落的苹果树,一开始B在 1 树下,B最多只能移动W步,求一个最大数量拿到的. 思路: 一开始想的是,我对于每分钟情况来说无非是等于之前的在本位置+1,或者等 ...
- Educational Codeforces Round 12 A. Buses Between Cities
题意: 从A到B的汽车每隔 a 分钟发车一次,从A到B要ta分钟. 从B到A汽车每隔b分钟发车一次,从B到A要ta分钟. Simion从A出发,问他在A->B的途中共遇到了多少辆车. 汽车都是从 ...
- bzoj 1207: [HNOI2004]打鼹鼠【dp】
跟简单的dp,设f[i]表示前i只最多打几只,因为起点不确定,所以f[i]可以从任意abs(x[i]-x[j])+abs(y[i]-y[j])<=abs(time[i]-time[j])的j&l ...
- mysql 用 group by 和 order by同时使用
首先,这是不可能实现的 mysql的查询的顺序 select -> from-> where->group by->having->order by. 但mysql的解析 ...
- Oracle之Char VarChar VarChar2
Oracle之Char VarChar VarChar2 在Oracle数据库中,字符类型有Char.VarChar和VarChar2三种类型,但不大清楚各自区别在哪儿,平时基本上就是用VarChar ...
- css为什么要定最小宽度和最大宽度,最小宽度和最大宽度有什么用
设最小和最大宽度,主要是为了防止页面变形而已如,如果一个页面的宽度设置为百分比,这时此页面的宽度会根据浏览器的宽度而定但如果浏览器的宽度过小,页面就会变形,例如,你做的用百分比设置的页面,而用户端的浏 ...
- Qt容器类之三:通用算法
在<QtAlgorithm>头文件中,Qt提供了一些全局的模板函数,这些函数是可以使用在容器上的十分常用的算法.我们可以在任何提供了STL风格迭代器的容器类上用这些算法,包括QList.Q ...