zoukankan      html  css  js  c++  java
  • PHP错误处理注册机制

    对于PHP错误,比如语法错误,需要做到收集错误并处理,在线上也要防止被普通用户看到关键的错误信息:

    博客推荐:

    PHP error_log记录日志的使用方法和配置:

    https://www.cnblogs.com/caicaizi/p/6812010.html

    手册:

    http://www.w3school.com.cn/php/php_ref_error.asp

    PHP的错误跟异常区别:

    https://www.cnblogs.com/taijun/p/4234603.html

    学会以后需要:

    主要作用:
    1、记录日志到指令文件
    2、强错误信息发送到邮箱之中
    
    相关配置:
    error_reporting     ;将会向PHP报告发生的每个错误
    display_errors      ;不显示满足上条 指令所定义规则的所有错误报告   
    log_errors          ;决定日志语句记录的位置   
    log_errors_max_len  ;设置每个日志项的最大长度   
    error_log           ;指定产生的 错误报告写入的日志文件位置 

    自己动手试试哦!

    模拟错误 + 模拟异常 + 发送email + 线上环境对普通用户隐藏错误信息

    1、PHP错误类型和相应例子:

     分号缺失,致命错误。

    直接注册在根命名空间的error类重名会出现致命错误,直接脚本终止,

    如果在错误出现之前都没注册shutdown函数的话,直接给你一个error500,很难受

    2、自己常用的错误报告处理类:

    ThinkPHP的写法(方然仿照的,真实的TP5.0错误处理机制更加细分,SQL exception 还有 缓存的exception 等等统统继承基础类扩展出了一个类(虽然跟没扩展一样,但是这个OOP思想值得借鉴)):

    自己用的简单的错误处理:

    <?php
    /**
     * 错误处理机制
     * @author xu <435861851@qq.com>
     */
    class ErrorCatch{
        /**
         * 注册异常处理
         * @access public
         * @return void
         */
        public static function register()
        {
            // 设定报错级别为全部
            error_reporting(E_ALL);
            // set_error_handler — 设置用户自定义的错误处理函数
            set_error_handler([__CLASS__, 'appError']);
            // set_exception_handler — 设置用户自定义的异常处理函数
            set_exception_handler([__CLASS__, 'appException']);
            // register_shutdown_function — 注册一个会在php中止时执行的函数,脚本执行完成或者 exit() 后被调用
            register_shutdown_function([__CLASS__, 'appShutdown']);
        }
        /**
         * 错误处理
         * @access public
         * @param  integer $errno      错误编号
         * @param  integer $errstr     详细错误信息
         * @param  string  $errfile    出错的文件
         * @param  integer $errline    出错行号
         * @param  array   $errcontext 出错上下文
         * @return void
         * @throws ErrorException
         */
        public static function appError($errno, $errstr, $errfile = '', $errline = 0, $errcontext = [])
        {
            $msg = '错误编号: <strong>'.$errno.'</strong></br>';
            $msg = '错误信息: <strong>'.$errstr.'</strong></br>';
            $msg .= '文件: <strong>'.$errfile.'</strong></br>';
            $msg .= '在第: <strong>'.$errline.'</strong> 行</br>';
            echo $msg;
            exit();
        }
        /**
         * 异常处理
         * @access public
         * @param   Exception $e 异常对象
         * @return void
         */
        public static function appException($exception)
        {
             echo "捕获异常: " , $exception->getMessage(), "
    ";
        }
        /**
         * 异常中止处理
         * @access public
         * @return void
         */
        public static function appShutdown()
        {
            // 只有错误导致的程序终止才会托管至错误处理函数
            if (!is_null($error = error_get_last()) && self::isFatal($error['type'])) {
                self::appException(new ErrorException(
                    $error['type'], $error['message'], $error['file'], $error['line']
                ));
            }
        }
    
    
        /**
         * 确定错误类型是否致命
         * @access protected
         * @param  int $type 错误类型
         * @return bool
         */
        protected static function isFatal($type)
        {
            return in_array($type, [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE]);
        }
    
    }
    
    // 注册自定义错误处理
    ErrorCatch::register();
    
    // 模拟抛出异常
    trigger_error("Cannot divide by zero", E_USER_ERROR);

     如果上面的trigger_error的时候后面少了一个;那么直接就是500,错误,显示服务器内部错误,

    不能被shutdown函数捕获,

    像这样,已经注册了函数了,就可以捕获到错误信息:

    捕获异常: syntax error, unexpected end of file

     一些常犯的错误及其报错信息:

    <?php
    
    foreach ([] as $k => $v)
    {
        echo $v;
    }
    // no any msg catch
    
    array_merge([1,2,3],'');
    
    // Warning: array_merge(): Argument #2 is not an array in D:webserverwww	est.php on line 8
    
    if($a)
    {
        echo 1;
    }
    
    // Notice: Undefined variable: a in D:webserverwww	est.php on line 13
    
    " select * from user where id in ([])";
    
    // General error: 936 OCIStmtExecute: ORA-00936: 缺失表达式 PDO exception IN ()后面表达式不能为空不能为ARRAY
    
    if(in_array("a", $a)){echo 1;};
    
    // Notice: Undefined variable: a in D:webserverwww	est.php on line 24
    // Warning: in_array() expects parameter 2 to be array, null given in D:webserverwww	est.php on line 24
    
    echo 22
    
    // Parse error: syntax error, unexpected end of file, expecting ',' or ';' in D:webserverwww	est.php on line 27
  • 相关阅读:
    伪静态规则写法RewriteRule-htaccess详细语法使用
    事务的操作
    layer 模版使用
    追加下拉框的自动生成
    PHP自动生成前端的表单框架
    MySQL高效获取记录总数
    引用JS表单验证大全 以后方便查看用
    关于left join连接查询 两张表里有同名字段的问题
    详解clientHeight、offsetHeight、scrollHeight
    php防止SQL注入详解及防范
  • 原文地址:https://www.cnblogs.com/xuweiqiang/p/8324897.html
Copyright © 2011-2022 走看看