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的异常处理机制的更多相关文章

  1. Java异常处理机制 try-catch-finally 剖析

    Java拥有着强大的异常处理机制,最近初步学习了下,感觉内容还是挺多的,特此来将自己的理解写出来与大家分享. 一. 在Java代码code中,由于使用Myeclipse IDE,可以自动提醒用户哪里有 ...

  2. JAVA 异常处理机制

    主要讲述几点: 一.异常的简介 二.异常处理流程 三.运行时异常和非运行时异常 四.throws和throw关键字 一.异常简介 异常处理是在程序运行之中出现的情况,例如除数为零.异常类(Except ...

  3. 深入理解java异常处理机制

       异常指不期而至的各种状况,如:文件找不到.网络连接失败.非法参数等.异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程.Java通 过API中Throwable类的众多子类描述各种不同的 ...

  4. C++学习笔记27:异常处理机制

    一.异常处理机制基础 异常的定义 程序中可以检测的运行不正常的情况 异常处理的基本流程 某段程序代码在执行操作时发生特殊情况,引发一个特定的异常 另一段程序代码捕获该异常并处理它 二.异常的引发 th ...

  5. C++中的异常处理机制

    C++中的捕获异常机制catch参数中实参的类型不同,采取的处理方式则不相同,且与普通的函数调用还不一样,具体表现为当抛出异常throw A()或throw obj时,对象会进行一次额外的对象复制操作 ...

  6. 16、java中的异常处理机制

    异常:就是程序在运行时出现不正常情况.异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述.并封装成对象. 其实就是java对不正常情况进行描述后的对象体现. 对于问题的划 ...

  7. Struts——(四)异常处理机制

    在通常的情况下,我们得到异常以后,需要将页面导航到一个错误提示的页面,提示错误信息.利用Stuts我们可以采用两种方式处理异常: 1.编程式异常处理 即我们在Action中调用业务逻辑层对象的方法时, ...

  8. Java面向对象编程之异常处理机制

    一:Java的异常处理机制的优点: 1:把各种不同情况的异常情况分类,使用JAVA类来表示异常情况,这种类被称为异常类.把各种异常情况表示成异常类,可以充分的发挥类的可扩展性和可重用性. 2:异常流程 ...

  9. Java之异常处理机制

    来源:深入理解java异常处理机制 2.Java异常    异常指不期而至的各种状况,如:文件找不到.网络连接失败.非法参数等.异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程.Java通 ...

  10. SpringMVC异常处理机制详解[附带源码分析]

    目录 前言 重要接口和类介绍 HandlerExceptionResolver接口 AbstractHandlerExceptionResolver抽象类 AbstractHandlerMethodE ...

随机推荐

  1. jsp EL表达式原样输出问题

    jsp原样输出,比如${message},输出也是${message}. 需要在<%@ page......%>里面添加isELIgnored="false". 参考: ...

  2. layui.table图片显示不全和404问题

    1.图片显示不全 在使用layui.table组件中,加载的图片显示不全,需重新定义CSS如下: .layui-table-cell{ height: auto!important; white-sp ...

  3. MySQL5.7.25(解压版)Windows下详细的安装过程

    大家好,我是浅墨竹染,以下是MySQL5.7.25(解压版)Windows下详细的安装过程 1.首先下载MySQL 推荐去官网上下载MySQL,如果不想找,那么下面就是: Windows32位地址:点 ...

  4. Python 创建递归文件夹

    # 创建递归文件夹 def createfiles(filepathname): try: os.makedirs(filepathname) except Exception as err: pri ...

  5. performance数据

    // 获取 performance 数据 var performance = { // memory 是非标准属性,只在 Chrome 有 // 财富问题:我有多少内存 memory: { usedJ ...

  6. ASP.NET Core 2.0 MVC - 获取当前登录用户信息

    一.前言 上篇实战完成后,没想到会有那么多的圈友给了那么多的支持,甚至连只是作为代码仓储的git上也给了一些小星星,真的感觉很惶恐啊,哈哈哈,毕竟代码写的很烂啊.由于上一篇只是大概说了下项目,所以准备 ...

  7. asp.net core 系列 19 EFCore介绍

    一.概述 目前最新的EF Core版本是3.0,最稳定的EF Core版本是2.2.EF Core 的计划与 .NET Core以及 ASP.NET Core 版本同步.EF Core 是一个 .NE ...

  8. asp.net core 系列 14 错误处理

    一.概述 本文介绍处理 ASP.NET Core 应用中常见错误的一些方法.主要是关于:开发环境异常页:非开发环境配置自定义异常处理页:配置状态代码页(没有正文响应,http状态400~599的). ...

  9. C++版 - Leetcode 400. Nth Digit解题报告

    leetcode 400. Nth Digit 在线提交网址: https://leetcode.com/problems/nth-digit/ Total Accepted: 4356 Total ...

  10. webpack 2 系列

    webpack 2 系列 webpack 是一个强大的工具,学会通过工具来解决开发效率问题,是每一个 工程师都必备的技能之一. 那么我们来从零开始搭建一个 基于webpack 2 到 开发架子,来提升 ...