浅谈PHP异常处理
1、PHP中异常的独特性
PHP中的异常的独特性,即PHP中的异常不同于主流语言C++、java中的异常。在Java中,异常是唯一的错误报告方式,而在PHP中却不是这样,而是把所有不正常的情况都视作了错误进行处理。这两种语言对异常和错误的界定存在分歧。什么是异常什么是错误,两种语言的设计者存在不同的观点。
PHP中的异常:
是程序在运行中出现不符合预期的情况及与正常流程不同的状况。一种不正常的情况,按照正常逻辑本不该出的错误,但仍然会出现的错误,这是属于逻辑和业务流程的错误,而不是编译或者语法上的错误。
PHP中的错误:
是属于php脚本自身的问题,大部分情况是由错误的语法,服务器环境导致,使得编译器无法通过检查,甚至无法运行的情况。warning、notice都是错误,只是他们的级别不同而已,并且错误是不能被try-catch捕获的。
在PHP中遇到任何自身错误都会触发一个错误,而不是抛出异常。PHP一旦遇到非正常代码,通常都会触发错误,而不是抛出异常。因此,如果想要使用异常处理不可预料的问题,是办不到的。
典型例子:
<?php try {
echo 1/0;
} catch (Exception $e){
echo $e->getMessage();
}
结果:
结果显示:
此时出现了一个警告级别的错误,程序终止。
2、PHP中的错误级别
PHP中的异常机制是不足的,绝大多数情况下无法自动抛出异常,必须使用if....else语句先进行判断,在进行手动抛出异常。
手动抛出异常的意义不大,是已经预料到的错误,这种方式将会使你陷入纷繁复杂的业务逻辑判断和处理中。
因此我们可以通过一些特殊的函数来自定义错误处理函数,来接管PHP原生的错误处理函数,然后再进行抛出异常。
接下来我们需要了解PHP中的一些错误。
错误显示控制:
【ALL设置】
全局:php.ini中设置display_error = on/off;
局部:ini_set("display_error", true/false);
PHP.ini中display_errors = Off失效的解决
问题: PHP设置文件php.ini中明明已经设置display_errors = Off,但是在运行过程中,网页上还是会出现错误信息。
解决: 经 查log_errors= On,据官方的说法,当这个log_errors设置为On,那么必须指定error_log文件,如果没指定或者指定的文件没有权限写入,那么照样会输 出到正常的输出渠道,那么也就使得display_errors 这个指定的Off失效,错误信息还是打印了出来。于是将log_errors = Off,问题就解决了。
【选择性设置显示错误】
全局:error_reporting = E_ALL | E_STRICT....
局部:error_reporting(E_ERROR | E_WARNING | E_PARSE)
1 E_ERROR 致命的运行错误。错误无法恢复,暂停执行脚本。
2 E_WARNING 运行时警告(非致命性错误)。非致命的运行错误,脚本执行不会停止。
4 E_PARSE 编译时解析错误。解析错误只由分析器产生。
8 E_NOTICE 运行时提醒(这些经常是你代码中的bug引起的,也可能是有意的行为造成的。)
16 E_CORE_ERROR PHP 启动时初始化过程中的致命错误。
32 E_CORE_WARNING PHP启动时初始化过程中的警告(非致命性错)。
64 E_COMPILE_ERROR 编译时致命性错。这就像由Zend脚本引擎生成了一个E_ERROR。
128 E_COMPILE_WARNING 编译时警告(非致性错)。这就像由Zend脚本引擎生成了E_WARNING警告。
256 E_USER_ERROR 自定义错误消息。像用PHP函数trigger_error(程序员设置E_ERROR)
512 E_USER_WARNING 自定义警告消息。像用PHP函数trigger_error(程序员设的E_WARNING警告)
1024 E_USER_NOTICE 自定义的提醒消息。像由使用PHP函数trigger_error(程序员E_NOTICE集)
2048 E_STRICT 编码标准化警告。允许PHP建议修改代码以确保最佳的互操作性向前兼容性。
4096 E_RECOVERABLE_ERROR 开捕致命错误。像E_ERROR,但可以通过用户定义的处理捕获(又见set_error_handler())
8191 E_ALL 所有的错误和警告(不包括 E_STRICT) (E_STRICT will be part of E_ALL as of PHP 6.0)14 16384 E_USER_DEPRECATED 15 30719 E_ALL
一共有十五种,使用二进制代替,0000 0000 0000 0011 表示 E_ERROR和E_WARNING
例如:
error_reporting(3); //只显示E_ERROR和E_WARNING错误
error_reporting(-1); //只显示所有错误误
注意:
在开发阶段通常是显示所有错误,方便解决问题;
在生产阶段通常是隐藏错误,并将需错误记录到文件中(错误日志);
php.ini中设置:log_error = on/off; //记录、不记录
error_log = php_errors.log //设定错误日志文件(此时没有给定路径则在当前位置生成)
还可以通过ini_set()进行设置。
3、PHP中的异常处理
3.1、set_error_handler(error_function, error_type)
使用set_error_handler(error_function, error_type)函数设置自定义错误处理函数,接管原错误处理函数。
eg.
<?php // 方式一
// set_error_handler('myError');
// function myError($errorNum, $errorMs, $errorFile, $errorLine){
// echo('set_error_handler: ' . $errorNum . ':' . $errorMs . ' in ' . $errorFile . ' on ' . $errorLine . ' line ');
// } // 方式二
class ErrorClass{
// 必须静态public方法
public static function myError($errorNum, $errorMs, $errorFile, $errorLine){
echo('set_error_handler: ' . $errorNum . ':' . $errorMs . ' in ' . $errorFile . ' on ' . $errorLine . ' line ');
}
} set_error_handler(['ErrorClass', 'myError']); try {
$a = 5/0;
} catch (Exception $e) {
echo "666666";
}
访问结果:
由结果可知:我们自定义的myError方法截取了错误,此时我们可以主动的处理这些错误,抛出相应的异常。
但是我们需要注意以下两点:
3.2、register_shutdown_function(exception_function)
[message] - 错误消息
[file] - 发生错误所在的文件
[line] - 发生错误所在的行
eg.
<?php try {
$a = 5/0;
} catch (Exception $e) {
echo "666666";
} register_shutdown_function('myshutdownfunc');
function myshutdownfunc()
{
if ($error = error_get_last()) {
echo "<pre>";
print_r($error);
echo "</pre>";die;
}
}
测试1:
测试2:(使用echo "string";替换try....catch)
测试3:(使用echo "string"替换try...catch)
此时语法错误,register_shutdown_function函数未执行
测试4:
新建一个文件,具有语法错误的php代码,并将其引入执行文件中,例如
ceshi2.class.php文件
<?php
echo "string" ?> ceshi.class.php文件
<?php register_shutdown_function('myshutdownfunc');
function myshutdownfunc()
{
if ($error = error_get_last()) {
echo "<pre>";
print_r($error);
echo "</pre>";die;
}
} include "ceshi2.class.php";
?>
结果:
3.3、set_exception_handler(exception_function)
参数 | 描述 |
---|---|
error_function | 必需。规定未捕获的异常发生时调用的函数。 该函数必须在调用 set_exception_handler() 函数之前定义。 这个异常处理函数需要需要一个参数,即抛出的 exception 对象。 |
作用:
set_exception_handler() 函数设置用户自定义的异常处理函数。
该函数用于创建运行时期间的用户自己的异常处理方法。
该函数会返回旧的异常处理程序,若失败,则返回 null。
提示:在这个异常处理程序被调用后,脚本会停止执行。
eg.
<?php
// 第一种放方法
// function myException($exception) {
// echo "<b>Exception:</b> " , $exception->getMessage();
// }
// set_exception_handler('myException'); // 第二种方法
class MyError{
//必须是静态public方法
public static function myException($exception) {
echo "<b>Exception:</b> " , $exception->getMessage();
}
}
set_exception_handler(['MyError', 'myException']);
throw new Exception('Uncaught Exception occurred---没有人处理的异常');
运行结果:
作者:那一叶随风
原文地址:http://www.cnblogs.com/phpstudy2015-6/p/8433541.html
声明:本博客文章为原创,只代表本人在工作学习中某一时间内总结的观点或结论。转载时请在文章页面明显位置给出原文链接
浅谈PHP异常处理的更多相关文章
- 浅谈C++ 异常处理的语义和性能
异常处理是个十分深奥的主题,这里只是浅论其对C++性能的影响. 在VC++中,有多个异常处理模式,三个最重要: No exception handling (无异常处理) C++ only (C++语 ...
- 浅谈Objective-C异常处理
-----<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培 ...
- 浅谈MVC异常处理
在日常开发中,我们会去捕捉很多的异常,来进行处理,通常我们的方法就是,在需要进行异常处理的地方加上 try catch 块,但是,如果需要异常处理的地方很多,那么,就会频繁的去写try catch 块 ...
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
- 浅谈Hybrid技术的设计与实现
前言 浅谈Hybrid技术的设计与实现 浅谈Hybrid技术的设计与实现第二弹 浅谈Hybrid技术的设计与实现第三弹——落地篇 随着移动浪潮的兴起,各种APP层出不穷,极速的业务扩展提升了团队对开发 ...
- jsp内置对象浅谈
jsp内置对象浅谈 | 浏览:1184 | 更新:2013-12-11 16:01 JSP内置对象:我们在使用JSP进行页面编程时可以直接使用而不需自己创建的一些Web容器已为用户创建好的JSP内置对 ...
- [C#]6.0新特性浅谈
原文:[C#]6.0新特性浅谈 C#6.0出来也有很长一段时间了,虽然新的特性和语法趋于稳定,但是对于大多数程序猿来说,想在工作中用上C#6.0估计还得等上不短的一段时间.所以现在再来聊一聊新版本带来 ...
- Android安全开发之启动私有组件漏洞浅谈
0x00 私有组件浅谈 android应用中,如果某个组件对外导出,那么这个组件就是一个攻击面.很有可能就存在很多问题,因为攻击者可以以各种方式对该组件进行测试攻击.但是开发者不一定所有的安全问题都能 ...
- 【WebApi系列】浅谈HTTP
[01]浅谈HTTP在WebApi开发中的运用 [02]聊聊WebApi体系结构 [03]详解WebApi如何传递参数 [04]详解WebApi测试和PostMan [05]浅谈WebApi Core ...
随机推荐
- VSTS/TFS Auto Build
前几天使用VSTS配置自动部署前端网站(AngularJS)和RESTfulAPI(.NET)到客户环境. 由于都是参考官方文档 https://docs.microsoft.com/zh-cn/vs ...
- CTF---Web入门第十一题 PHP大法
PHP大法分值:20 来源: DUTCTF 难度:中 参与人数:8205人 Get Flag:2923人 答题人数:3042人 解题通过率:96% 注意备份文件 解题链接: http://ctf5.s ...
- 2017 Multi-University Training Contest - Team 9 1005&&HDU 6165 FFF at Valentine【强联通缩点+拓扑排序】
FFF at Valentine Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- poj 3261
Milk Patterns Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 13249 Accepted: 5894 Ca ...
- HDU1061-Rightmost Digit-规律题,快速幂
Rightmost Digit Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- BZOJ1304: [CQOI2009]叶子的染色
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1304 树形dp. 可以发现其实根选在哪里都是没有问题的. f[u][0],f[u][1],f[ ...
- three.js 入门案例
最近公司需要用tree.js实现一个3D图的显示,就看了官方文档,正好有时间,就记录下来. 由于我们公司的前端框架用的是angular,所以我就把我的treejs封装在一个directives里面.后 ...
- flume1.8 Interceptors拦截器(五)
1. Flume Interceptors Flume有能力修改/删除流程中的events.这是在拦截器(interceptor)的帮助下完成的.拦截器(Interceptors)是实现org.apa ...
- TypeScript笔记 5--变量声明(解构和展开)
解构是什么 解构(destructuring assignment)是一种表达式,将数组或者对象中的数据赋给另一变量. 在开发过程中,我们经常遇到这样问题,需要将对象某个属性的值赋给其它两个变量.代码 ...
- 关于atom
以前老听别人说atom这款编辑器如何如何的好用,今天特地试了下,结果一不小心将顶部的工具栏给隐藏了,弄了半天都没弄出来.后来就在网上到处寻找帮助,试试这个试试那个,终于弄好了,其实是这样的. 首先在任 ...