• PHP的错误处理机制


    php的错误处理是比较复杂的, 本文讲解php中所有错误相关的重要知识点做一次梳理, 便于理解php的错误机制.

    基础知识

    在此之前, 先熟悉一下php error的基础知识

    预定义常量

    定义了所有php的错误类型常量, 每一个常量都是一个整型数值, 它的作用在于

    上面的值(数值或者符号)用于建立一个二进制位掩码,来制定要报告的错误信息。可以使用按位运算符来组合这些值或者屏蔽某些类型的错误。请注意,在 php.ini 之中,只有'|', '~', '!', '^' 和 '&' 会正确解析。

    从使用的角度看, 可以分为三类:

    1. 用户手动抛出的
      E_USER_NOTICEE_USER_WARNINGE_USER_ERRORE_USER_DEPRECATED
    2. 用户造成的
      E_NOTICEE_PARSEE_WARNINGE_ERRORE_COMPILE_ERRORE_COMPILE_WARNINGE_STRICTE_RECOVERABLE_ERROR
    3. php内核造成的
      E_CORE_ERRORE_CORE_WARNING

    从是否终止程序执行的角度看, 可分为两类

    1. 终止程序执行
      程序终止, 进入处理错误流程

    2. 不终止程序执行
      产生错误, 但程序仍可以继续执行, 同样进入错误处理流程

    对于PHP中的错误类型, 可以参考这篇更详细的文章--PHP的错误机制总结

    运行时配置

    手册--运行时配置讲解的很详细, 但有几个配置仍需特别注意

    1. error_reporting
      报告错误的类型, 建议在开发/测试环境配置成E_ALL, 解决所有的类型的错误后, 在生产环境配置E_ALL & E_DEPRECATED, 则表明:报告除废弃错误外的所有错误

    2. display_errors
      是否显示错误, 在生产环境中配置成false, 配合上面error_reporting的设置, 则表明: 报告除废弃错误外的所有错误, 但不显示错误信息.

    3. log_errors
      错误记录是否开启, 生产环境需开启. 配合上面的两项配置, 则表明: 报告除废弃错误外的所有错误, 不显示错误信息, 但记录(只有php自己可以操作错误信息)到日志中.

    4. error_log
      指定错误的文件(syslog是特殊值).默认未被设置, 手册中:

    如果该配置没有设置,则错误信息会被发送到 SAPI 错误记录器

    一般情况下, 未设置会被记录到apache/nginx的错误日志中. 配合上面三项配置, 则表明: 报告除废弃错误外的所有错误, 不显示错误信息, 但记录到apache/nginx日志中.若配置了文件路径, 则表明: 报告除废弃错误外的所有错误, 不显示错误信息, 但记录到file_dir日志中.

    上面这几项配置影响着php错误最基本的表现.当然,这些配置可以通过 ini_set() 在代码中更改 或 php-fpm配置更改

    错误处理函数

    错误函数并不多, 最应该关注的就是set_error_handler 和 set_exception_handler, 因为通过它们可以介入错误/异常的处理流程.

    上面提到过, 错误发生后, 都会进行错误处理流程, 那错误流程是如何定义的?

    先看看php手册中的讲解: Errors

    简单来说就是, 默认的处理流程就是通过配置完成, 但我们可以设置自定义的错误处理流程

    终止脚本执行的错误如何处理

    上文提到过, 错误有两种, 那对于这种会终止脚本执行的错误如何处理?
    set_error_handler不能处理这种错误, 这一点很容易被忽略. 所以要寻找另一种方法.

    这个问题基本上是这样完成的(还未见过其他方案):

    // 终止脚本的错误会终止脚本执行
    // 即会调用已通过register_shutdown_function注册的处理函数
    // 由此可注册我们的错误处理流程, 这样就进入了自定义错误流程
    register_shutdown_function('FatalErrorHandle');
    
    ...
    
    FatalErrorHandle(array $error = null) {
         
         ... 
         
         if (null === $error) {
             // 通过这种方式可以获取最后一条错误
            $error = error_get_last();
         }
    
         ... 
         
         // log or other logic
    }

    异常

    根据w3cPHP 异常处理中的讲解:

    异常处理用于在指定的错误(异常)情况发生时改变脚本的正常流程。这种情况称为异常。
    当异常被触发时,通常会发生:

    • 当前代码状态被保存
    • 代码执行被切换到预定义的异常处理器函数
    • 根据情况,处理器也许会从保存的代码状态重新开始执行代码,终止脚本执行,或从代码中外的位置继续执行脚本

    未被catch的异常会终止脚本执行并产生一个E-ERROR错误, 执行定义的异常处理, 若无则进行php默认的错误处理流程, 即记录到日志中. 但在编程概念上应该将异常与错误分开, 异常对于用户而言是可预见的, 不符合预期的, 可控制的结构.

    上文提到的set_exception_handler就是处理异常的, 用法与set_error_handler一致. 在各框架中的异常处理很成熟, 大致都是在set_exception_handler中将Exception转移到框架可处理级别, 框架同时会开放良好的接口供用户使用, 从而达到用户控制异常处理的目的, 实现定制和扩展.

    总结

    php的错误处理机制总是被忽略, 但它对调试, 监控错误有很大的作用. 本文主要介绍了其中的主要知识点, 并做了一个梳理, 希望对大家有用.更多的细节还请查看手册.

    学习资料

    预定义常量
    运行时配置
    错误处理函数
    PHP的错误机制总结
    异常
    Errors
    PHP 异常处理
    Symfony Debug:是一个完整的应用, 可以说是一个全面的指导教程, 所有与error相关的知识点都涉及到了. 建议阅读源代码.

  • 相关阅读:
    team explorer everywhere 2010解决license试用到期的问题
    上海系分证书登记亲历
    Windows Server 8 IIS7中Remoting访问出现404错误的解决方法
    Eclipse中安装支持tfs(team foundation server)的插件team explorer everywhere 2010(二)
    Linq to oracle 太变态:Contains等函数要反着写:
    一个简单的powerdesigner模型(oom,pdm)分析器
    兴趣真的那么重要么?
    莫愁
    写给2013年自己的信
    .NET程序员也用JAVA:使用BlazeDS,SpringFramework,MySql,Flex构建RIA应用 part 3 :Flex及As 3代码编写
  • 原文地址:https://www.cnblogs.com/zcbing/p/6637926.html
Copyright © 2020-2023  润新知