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();
- }
输出:
Warning: Division by zero in D:\web\mytest\test.php on line 4
INF
- 结果显示:
- 此时出现了一个警告级别的错误,程序终止。
- 结论:
- PHP通常是无法自动捕获有意义的异常,它把所有不正常的情况都视作了错误,你要想捕获异常就得使用if....else结构,保证代码是正常的,然后判断进行手动抛出异常。
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)
- E_ERROR 致命的运行错误。错误无法恢复,暂停执行脚本。
- E_WARNING 运行时警告(非致命性错误)。非致命的运行错误,脚本执行不会停止。
- E_PARSE 编译时解析错误。解析错误只由分析器产生。
- E_NOTICE 运行时提醒(这些经常是你代码中的bug引起的,也可能是有意的行为造成的。)
- E_CORE_ERROR PHP 启动时初始化过程中的致命错误。
- E_CORE_WARNING PHP启动时初始化过程中的警告(非致命性错)。
- E_COMPILE_ERROR 编译时致命性错。这就像由Zend脚本引擎生成了一个E_ERROR。
- E_COMPILE_WARNING 编译时警告(非致性错)。这就像由Zend脚本引擎生成了E_WARNING警告。
- E_USER_ERROR 自定义错误消息。像用PHP函数trigger_error(程序员设置E_ERROR)
- E_USER_WARNING 自定义警告消息。像用PHP函数trigger_error(程序员设的E_WARNING警告)
- E_USER_NOTICE 自定义的提醒消息。像由使用PHP函数trigger_error(程序员E_NOTICE集)
- E_STRICT 编码标准化警告。允许PHP建议修改代码以确保最佳的互操作性向前兼容性。
- E_RECOVERABLE_ERROR 开捕致命错误。像E_ERROR,但可以通过用户定义的处理捕获(又见set_error_handler())
- E_ALL 所有的错误和警告(不包括 E_STRICT) (E_STRICT will be part of E_ALL as of PHP 6.0) E_USER_DEPRECATED E_ALL
- 一共有十五种,使用二进制代替, 表示 E_ERROR和E_WARNING
- 例如:
- error_reporting(); //只显示E_ERROR和E_WARNING错误
- error_reporting(-); //只显示所有错误误
- 注意:
- 在开发阶段通常是显示所有错误,方便解决问题;
- 在生产阶段通常是隐藏错误,并将需错误记录到文件中(错误日志);
- 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)函数设置自定义错误处理函数,接管原错误处理函数。
比如:
- <?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 = 1/0;
- } catch (Exception $e) {
- echo "666";
- }
输出:set_error_handler: 2:Division by zero in D:\web\mytest\test.php on 21 line
- 由结果可知:我们自定义的myError方法截取了错误,此时我们可以主动的处理这些错误,抛出相应的异常。
- 但是我们需要注意以下两点:
- 第一,如果存在该方法,相应的error_reporting()就不能在使用了。它将接管PHP原生错误处理函数,即所有的错误都会交给自定义的函数处理。
- 第二,此方法不能处理以下级别的错误:E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、 E_COMPILE_WARNING,set_error_handler() 函数所在文件中产生的E_STRICT,该函数只能捕获系统产生的一些Warning、Notice级别的错误。
- 注意:
- 如果在脚本执行前发生错误,由于此时自定义的错误处理函数还没有注册,因此就用不到这个自定义错误处理程序。
3.2、register_shutdown_function(exception_function)
- 捕获PHP的错误:Fatal Error、Parse Error等,这个方法是PHP脚本执行结束前最后一个调用的函数,比如脚本错误、die()、exit、异常、正常结束都会调用。
- 通过这个函数就可以在脚本结束前判断这次执行是否有错误产生,这时就要借助于一个函数:error_get_last();这个函数可以拿到本次执行产生的所有错误。error_get_last();返回的信息:
- [type] - 错误类型
- [message] - 错误消息
- [file] - 发生错误所在的文件
- [line] - 发生错误所在的行
- 注意:当parse-time出错时是不会调用本函数的。只有在run-time出错的时候,才会调用本函数。即需要成功注册此函数才能使用。【测试3和测试4对比】
比如:
- <?php
- try {
- $a = 1/0;
- } catch (Exception $e) {
- echo "cat not divied by 0";
- }
- register_shutdown_function('myshutdownfunc');
- function myshutdownfunc()
- {
- if ($error = error_get_last()) {
- echo "<pre>";
- print_r($error);
- echo "</pre>";die;
- }
- }
输出:
Warning: Division by zero in D:\web\mytest\test.php on line 4
- Array
- (
- [type] => 2
- [message] => Division by zero
- [file] => D:\web\mytest\test.php
- [line] => 4
- )
3.3、set_exception_handler(exception_function)
参数 | 描述 |
---|---|
error_function | 必需。规定未捕获的异常发生时调用的函数。 该函数必须在调用 set_exception_handler() 函数之前定义。 这个异常处理函数需要需要一个参数,即抛出的 exception 对象。 |
- 作用:
- set_exception_handler() 函数设置用户自定义的异常处理函数。
- 该函数用于创建运行时期间的用户自己的异常处理方法。
- 该函数会返回旧的异常处理程序,若失败,则返回 null。
- 提示:在这个异常处理程序被调用后,脚本会停止执行。
比如:
- <?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('没有人处理异常');
输出:Exception: 没有人处理异常
PHP的异常处理机制的更多相关文章
- Java异常处理机制 try-catch-finally 剖析
Java拥有着强大的异常处理机制,最近初步学习了下,感觉内容还是挺多的,特此来将自己的理解写出来与大家分享. 一. 在Java代码code中,由于使用Myeclipse IDE,可以自动提醒用户哪里有 ...
- JAVA 异常处理机制
主要讲述几点: 一.异常的简介 二.异常处理流程 三.运行时异常和非运行时异常 四.throws和throw关键字 一.异常简介 异常处理是在程序运行之中出现的情况,例如除数为零.异常类(Except ...
- 深入理解java异常处理机制
异常指不期而至的各种状况,如:文件找不到.网络连接失败.非法参数等.异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程.Java通 过API中Throwable类的众多子类描述各种不同的 ...
- C++学习笔记27:异常处理机制
一.异常处理机制基础 异常的定义 程序中可以检测的运行不正常的情况 异常处理的基本流程 某段程序代码在执行操作时发生特殊情况,引发一个特定的异常 另一段程序代码捕获该异常并处理它 二.异常的引发 th ...
- C++中的异常处理机制
C++中的捕获异常机制catch参数中实参的类型不同,采取的处理方式则不相同,且与普通的函数调用还不一样,具体表现为当抛出异常throw A()或throw obj时,对象会进行一次额外的对象复制操作 ...
- 16、java中的异常处理机制
异常:就是程序在运行时出现不正常情况.异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述.并封装成对象. 其实就是java对不正常情况进行描述后的对象体现. 对于问题的划 ...
- Struts——(四)异常处理机制
在通常的情况下,我们得到异常以后,需要将页面导航到一个错误提示的页面,提示错误信息.利用Stuts我们可以采用两种方式处理异常: 1.编程式异常处理 即我们在Action中调用业务逻辑层对象的方法时, ...
- Java面向对象编程之异常处理机制
一:Java的异常处理机制的优点: 1:把各种不同情况的异常情况分类,使用JAVA类来表示异常情况,这种类被称为异常类.把各种异常情况表示成异常类,可以充分的发挥类的可扩展性和可重用性. 2:异常流程 ...
- Java之异常处理机制
来源:深入理解java异常处理机制 2.Java异常 异常指不期而至的各种状况,如:文件找不到.网络连接失败.非法参数等.异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程.Java通 ...
- SpringMVC异常处理机制详解[附带源码分析]
目录 前言 重要接口和类介绍 HandlerExceptionResolver接口 AbstractHandlerExceptionResolver抽象类 AbstractHandlerMethodE ...
随机推荐
- 找一个数组的最大和的连续子数组(时间复杂度 O(n))
设计思想 一开始的思想是求出全部的情况,再分别比较大小,这种方法适用于有限个数组,不适用于输入数组长度和内容的情况. 但也试着做了 int a[]= {-1,2,6,-10}; int size=4; ...
- position 几个属性的作用
//定位一般都会配合left 和 top 一起使用; //静态定位 : 元素默认位置; 不脱标 不常用position:static; //相对定位 : 相对于元素本身之前的位置进行定位;不脱标pos ...
- MySQL 的分页查询 SQL 语句
MySQL一般使用 LIMIT 实现分页.基本语句为: SELECT ... FROM ... WHERE ... ORDER BY ... LIMIT ... 在中小数据量的情况下,这样的SQL足够 ...
- [Swift]LeetCode312. 戳气球 | Burst Balloons
Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by ...
- [Swift]LeetCode667. 优美的排列 II | Beautiful Arrangement II
Given two integers n and k, you need to construct a list which contains n different positive integer ...
- HBase之Table.put客户端流程(续)
上篇博文中已经谈到,有两个流程没有讲到.一个是MetaTableAccessor.getRegionLocations,另外一个是ConnectionImplementation.cacheLocat ...
- 关于CKEditor 4.0 过滤html标签
今天遇到一个问题,就是整个页面存储在数据库中,然后后台可以进行编辑,开始我使用ckeditor进行编辑,后来发现他会自动的过滤掉一些html标签,花了一上午的时间在网上查找资料,并且在官网也看了,但是 ...
- 从零开始学习PYTHON3讲义(五)while循环和棋盘麦粒问题
<从零开始PYTHON3>第五讲 上一节课重点学习了字符串,并且传递了一个重要的理念,就是程序要对开发人员自己和用户都足够友好.在这个过程中,利用字符串给出充分.完整.准确的提示是非常重 ...
- mybatis中的动态SQL
在实际开发中,数据库的查询很难一蹴而就,我们往往要根据各种不同的场景拼接出不同的SQL语句,这无疑是一项复杂的工作,我们在使用mybatis时,mybatis给我们提供了动态SQL,可以让我们根据具体 ...
- [Leetcode]538. Convert BST to Greater Tree
Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original B ...