资讯专栏INFORMATION COLUMN

CodeIgniter3.0+框架自定义异常处理实现

LinkedME2016 / 3071人阅读

摘要:背景框架核心代码自动实现了异常,并实现了抛出的对应页面和方法,对于一些个性化需求特别是接口类型的应用,会不合适。因此需要在不改版核心代码目录下文件,来改变对异常及等相关异常的处理。方法说明框架比有比较大的改动,其中之一就是对异常的处理。

背景

ci3.0框架核心代码自动实现了异常,并实现了抛出的对应页面和方法,对于一些个性化需求特别是接口类型的应用,会不合适。因此需要在不改版核心代码 (system目录下文件),来改变对异常及404等相关异常的处理。

方法说明

ci框架3.0比2.0有比较大的改动,其中之一就是对异常的处理。以下是CodeIgniter-3.1.8systemcoreCodeIgniter.php 中对异常处理的部分代码

/*
 * ------------------------------------------------------
 *  Define a custom error handler so we can log PHP errors
 * ------------------------------------------------------
 */
    set_error_handler("_error_handler");
    set_exception_handler("_exception_handler");
    register_shutdown_function("_shutdown_handler");
...

以上括号内的方法均在common.php中以function_exists为前提声明。

...
if ( ! function_exists("_exception_handler"))
{
...
代码实现

我们简单粗暴的在项目入口文件index.php中重写以下方法

/**
 * 推送到redis cc异常队列
 * @time 2019/3/21 15:29
 * @author tongbo
 * @param $msg
 * @param $error_type
 * @param $error_code
 * @return bool|int|string
 */
function redis_list_add($msg, $error_type, $error_code)
{
    ini_set("default_socket_timeout", -1);
    $v = explode(":", $_SERVER["SITE_REDIS_SERVER"]);
    if (is_array($v) && !empty($v)) {
        try {
            $redis = new redis();
            $redis->pconnect($v[0], $v[1]);
            $space = "

";
            $trace = "";
            if ($error_code) {
                $trace .= "状态码    :" . $error_code . "
";
            }
            if ($error_type) {
                $trace .= "错误类型 :" . $error_type . "
";
            }
            $trace .= "客户端IP : " . $_SERVER["REMOTE_ADDR"] . "
";
            $trace .= "服务端IP : " . $_SERVER["SERVER_NAME"] . "(" . $_SERVER["SERVER_ADDR"] . ")" . "
";
            $trace .= "请求地址 : " . (isset($_SERVER["REQUEST_URI"]) ? $_SERVER["REQUEST_URI"] : "empty") . "
";
            $trace .= "请求参数 : =" . print_r($_REQUEST ? $_REQUEST : $_GET, true) . "
";
            return $redis->LPUSH("CC_PHP_ERROR_WARNING", $space . $msg . $space . $trace);
        } catch (Exception $e) {
            return $e->getMessage();
        }
    }
}

/**
 * 优先重写common.php中对应方法
 * 捕捉语法错误
 * @time 2019/3/21 16:19
 * @author tongbo
 * @param $severity
 * @param $message
 * @param $filepath
 * @param $line
 */
function _error_handler($severity, $message, $filepath, $line)
{
    $is_error = (((E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR | E_STRICT) & $severity) === $severity);

    if ($is_error) {
        $error_msg = $message . "
" . $filepath . "
" . $line;
        $error_code = "501";
        redis_list_add($error_msg, "Error_Handler异常", $error_code);
        exit(json_encode(["success" => "-1", "code" => $error_code, "msg" => "error"]));
    }
}

/**
 * 捕获php本身语法,对象调用,参数类型传递等错误
 * 优先重写common.php中对应方法
 * ParseError,object(Error),TypeError,Error
 * @time 2019/3/20 18:33
 * @author tongbo
 * @param $exception
 */
function _exception_handler($exception)
{
    if (!empty($exception)) {
        $error_type = get_class($exception);
        $error_msg = "
错误类型:  {$error_type};
文件名:  {$exception->getFile()}; 
所在行号:  {$exception->getLine()}; 
错误消息:  {$exception->getMessage()}; ";

        $error_code = "502";
        redis_list_add($error_msg, $error_type, $error_code);
        exit(json_encode(["success" => "-1", "code" => $error_code, "msg" => "exception"]));
    }
}

/**
 * 优先重写common.php中对应方法
 * require_once("no_exists.php")
 * @time 2019/3/21 9:49
 * @author tongbo
 */
function _shutdown_handler()
{
    $last_error = error_get_last();
    if (isset($last_error) &&
        ($last_error["type"] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING))) {
        $error_msg = "
错误类型:  shutdown; >
文件名:  {$last_error["file"]}; 
所在行号:  {$last_error["line"]}; 
错误消息:  {$last_error["message"]}; ";
        $error_code = "503";
        redis_list_add($error_msg, "Shut_Down异常", $error_code);
        exit(json_encode(["success" => "-1", "code" => $error_code, "msg" => "shutdown"]));
    }
}

/**
 * 优先重写common.php中对应方法
 * ci 框架内部的load异常、config异常、loader异常等会自动抛出,
 * 但common.php中的函数定义之类错误无法捕捉
 * @time 2019/3/20 18:46
 * @author tongbo
 * @param $message
 * @param int $status_code
 */
function show_error($message)
{
    $error_msg = "错误消息:  {$message}; ";
    $error_code = "504";
    redis_list_add($error_msg, "框架加载异常", $error_code);
    exit(json_encode(["success" => "-1", "code" => $error_code, "msg" => "ci_exception_1"]));
}

/**
 * 优先重写common.php中对应方法
 * @time 2019/3/21 15:34
 * @author tongbo
 * @param string $page
 */
function show_404($page = "")
{
    $error_msg = "错误消息: 请求的URL: " . $page . " 404 not found";
    $error_code = "404";
    redis_list_add($error_msg, "文件不存在", $error_code);
    exit(json_encode(["success" => "-1", "code" => $error_code, "msg" => "Not Found"]));
}
延伸

在基类中可以处理

错误等级区分对待

将错误处理写到其他地方,require_once进来

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/31108.html

相关文章

  • PHP项目中CodeIgniter使用的一些建议

    摘要:把如下代码添加到目录下的文件中类的构造函数之前,这其实就是进行变量声明,文件也是同样操作。举一个我项目中的例子。该类只需要一个构造函数完成上述功能即可。 最近再给一个APP写API,同时还要写相应的后台管理网站。为了便于开发和代码组织与管理,我决定采用一个现有的框架。Codeigniter由于其轻量容易自定制的特点吸引了我,一路开发过来也有大半年时间了,写下一些自己在开发过程中的一些体...

    Barrior 评论0 收藏0
  • 0开始构建一个属于你己的PHP框架

    摘要:如何构建一个自己的框架为什么我们要去构建一个自己的框架可能绝大多数的人都会说市面上已经那么多的框架了,还造什么轮子。 showImg(https://segmentfault.com/img/bVNg9F?w=500&h=500); 如何构建一个自己的PHP框架 为什么我们要去构建一个自己的PHP框架?可能绝大多数的人都会说市面上已经那么多的框架了,还造什么轮子?。我的观点造轮子不是目...

    vpants 评论0 收藏0
  • PHP框架中的日志系统

    摘要:一的几个函数异常捕获自定义处理函数注册错误捕获自定义处理函数注册程序执行时异常终止错误捕获处理函数注册这三个函数在错误处理控制中给开发者提供了很大的自主空间,在日志系统中记录日志信息有他们的功劳。下面要说的类库是借鉴了日志系统的设计。 引言 接触过php框架的朋友们可能都知道,日志在项目中的重要作用了,他可以帮助我们定位错误的位置,让程序更友好(处理得当的话不会直接抛出一大堆只有程...

    ningwang 评论0 收藏0

发表评论

0条评论

LinkedME2016

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<