ThinkPHP3.2.3 的异常和错误屏蔽处理

时间:2024-03-09 19:26:29

一、入口文件关闭调试,配置文件配置异常页面

在生产环境中系统的错误信息不能暴露给用户,入口文件的 APP_DEBUG 默认为开启状态

define(\'APP_DEBUG\',true);

此时如果用户访问到不存在的模块、控制器或者方法会出现:

 

在生产环境中需要把 APP_DEBUG 设置为 FALSE 或者将该定义屏蔽:

define(\'APP_DEBUG\',false);

此时如果用户访问到不存在的模块、控制器或者方法会出现:

这个错误的默认模板页在 ./ThinkPHP/Tpl/think_exception.tpl,可以设置自定义的异常页面来代替 ThinkPHP 默认的错误页面,在配置文件 config.php 中配置:

    //异常页面
    \'TMPL_EXCEPTION_FILE\' => \'./Public/Admin/error.html\',

 

在访问不存在的模块、控制器或方法时,会加载默认的或者自定义的异常页面模板。

 

二、定义 EmptyController 类

例如在 Admin 模块下创建一个 EmptyController.class.php,里面的 index 方法定义当用户访问一个不存在的控制器时系统该如何处理:

<?php
namespace Admin\Controller;
use Think\Controller;

class EmptyController extends Controller{
    public function index(){
       //跳转或加载404页
    }
}

 

三、定义空操作 _empty()

例如在 Admin 模块的  Common 控制器中定义一个 _empty() 方法,当用户访问一个不存在的方法时,就会按照空方法中的设置进行处理:

    //空方法
    function _empty() {
        //跳转或加载404页
    }

注:如果同时请求一个不存在的控制器和一个不存在的方法,或者请求一个不存在的模块时,会加载默认或者自定义的异常页面,而不会执行 EmptyController::index 或 _empty()。

 

四、数据库错误

在默认情况下,如果程序中的 SQL 语句出现了语法错误,很可能会把数据库信息暴露给用户:

注:在 APP_DEBUG 为 TRUE 且没有自定义异常页面时发生数据库错误会输出以上信息。

在关闭 APP_DEBUG 后,遇到数据库错误时,会加载默认的或者自定义的异常页面。如果希望在发生数据库错误时进行自定的处理时,可以在配置文件中设置数据库调试模式为 FALSE(该配置默认值是 TRUE):

\'DB_DEBUG\'  =>  FALSE, // 数据库调试模式 开启后可以记录SQL日志 3.2.3新增

当该选项开启时,会记录 SQL 日志,路径是 ./Application/Runtime/Logs/YourModule/

 

但是当该选项开启时,无法自定义处理异常,只能加载系统默认或者自定义的一场模板。如果关闭该选项,同时在开发时与数据库相关的操作都必须捕获异常,例如:

        $result = M(\'session\')->field(\'a\')->select();
        if($result === false) {
            //处理
        }

或者

try {
    $result= M("session")->field(\'a\')->select();
} catch (\Exception $e) {
    //处理
}

 

注:捕获异常可以参见 ./ThinkPHP/Library/Think/Db/Driver.class.php Line:169

        try{
            $result =   $this->PDOStatement->execute();
            // 调试结束
            $this->debug(false);
            if ( false === $result ) {
                $this->error();
                return false;
            } else {
                return $this->getResult();
            }
        }catch (\PDOException $e) {
            $this->error();
            return false;
        }