文档章节

Codeigniter 3 拓展HMVC

o0无忧亦无怖
 o0无忧亦无怖
发布于 2015/10/13 18:13
字数 1043
阅读 2085
收藏 39
点赞 3
评论 2

在Codeiniter(以下统称CI) 2.X版本中,我们就通过拓展核心类库实现了HMVC,但是同样的代码,拿到CI 3中,就很有可能不好用了。

###拓展核心类库方式

官方的文档对拓展核心类有详细的说明:

你定义的类必须继承自父类。 你的类名和文件名必须以 MY_ 开头。(这是可配置的,见下文) 举个例子,要扩展原始的 Input 类,你需要新建一个文件 application/core/MY_Input.php,然后像下面这样定义你的类:

class MY_Input extends CI_Input {

}

CI 控制器加载的过程很简单,官方文档有图如下:

输入图片说明 我们可以看到,在控制器开始加载看,CI是做了Routing(路由)和Security(安全)的操作的,所以,我们需要重写,或者说,在CI拓展我们想要的功能,比如:HMVC

###2.0中扩展

在2.0版本中,笔者曾适用过Jens Segers开源的HMVC模块,代码的实现就是对Routee和Loader进行了重写。 Jens Segers的主页 核心的代码如下:

            if (is_dir($source = $location . $module . '/controllers/')) {
                $this->module = $module;
                $this->directory = $relative . $module . '/controllers/';
                
                // 根目录下的模块?
                if ($directory && is_file($source . $directory . '.php')) {
                    $this->class = $directory;
                    return array_slice($segments, 1);
                }
                
                // 子模块?
                if ($directory && is_dir($source . $directory . '/')) {
                    $source = $source . $directory . '/';
                    $this->directory .= $directory . '/';
                    
                    // 子控制器?
                    if (is_file($source . $directory . '.php')) {
                        return array_slice($segments, 1);
                    }
                    
                    // 子文件夹包含有默认控制器?
                    if (is_file($source . $this->default_controller . '.php')) {
                        $segments[1] = $this->default_controller;
                        return array_slice($segments, 1);
                    }
                    
                    // 子文件夹中的控制器? 
                    if ($controller && is_file($source . $controller . '.php')) {
                        return array_slice($segments, 2);
                    }
                }
                
                // 控制器和文件夹名一样?
                if (is_file($source . $module . '.php')) {
                    return $segments;
                }
                
                // 适用默认的控制器?
                if (is_file($source . $this->default_controller . '.php')) {
                    $segments[0] = $this->default_controller;
                    return $segments;
                }
            }

很简单的拓展 就能实现HMVC模式了,同样的,还得重写Loader中的加载器,不然会找不到文件。

###CI 3 HMVC拓展 到了CI3中,上述方法已经不好用了,CI 3 对路由有了更多的考虑,在初始化路由时,就进行了解析。假设写MY_Ruter类,必须要重写3个方法: CI 2 Router构造

	function __construct()
	{
		$this->config =& load_class('Config', 'core');
		$this->uri =& load_class('URI', 'core');
		log_message('debug', "Router Class Initialized");
	}

CI 3 Router构造

public function __construct($routing = NULL)
	{
		$this->config =& load_class('Config', 'core');
		$this->uri =& load_class('URI', 'core');

		$this->enable_query_strings = ( ! is_cli() && $this->config->item('enable_query_strings') === TRUE);

		
		is_array($routing) && isset($routing['directory']) && $this->set_directory($routing['directory']);
		
		$this->_set_routing();

		
		if (is_array($routing))
		{
			empty($routing['controller']) OR $this->set_class($routing['controller']);
			empty($routing['function'])   OR $this->set_method($routing['function']);
		}

		log_message('info', 'Router Class Initialized');
	}

可以看到,在CI3的构造方法中就已经对URL进行解析,方法的调用过程为: _set_routing() -> _validate_request() -> _parse_routes() -> _set_request() 那我们为了要实现HMVC,这几个方法是必然要按照我们自己的方法实现的。 _validate_request 中 我们加入部分验证,即可达到简单的HMVC

 if (is_dir($source = $relative . $module . '/controllers/')) {
                $this->module = $module;
                $this->directory =  '../'.$location.$module . '/controllers/';


                // 如果 有 application/$module/controollers/$directory.php 文件
                if ($directory && is_file($source . ucfirst($directory) . '.php')) {
                    return array_slice($segments, 1);
                }

                //如果application/$module/$directory 是一个文件夹
                if ($directory && is_dir($source . $directory . '/')) {
                    $source = $source . $directory . '/';
                    $this->directory .= $directory . '/';
                    //  index.php/$modules/$directory/$controller
                    //如果包含 控制器  $controller
                    if ($controller && is_file($source . ucfirst($controller) . '.php')) {
                        return array_slice($segments, 2);
                    }

                    //如果有默认控制器
                    if (is_file($source . $this->default_controller . '.php')) {
                        $segments[1] = $this->default_controller;
                        return array_slice($segments, 1);
                    }

                    //如果有 application/$module/$directory.php
                    if (is_file($source . $directory . '.php')) {
                        return array_slice($segments, 1);
                    }
                }

                //如果有 application/$module/$module.php  
                if (is_file($source . $module . '.php')) {
                    return $segments;
                }

                // 默认控制器
                if (is_file($source . $this->default_controller . '.php')) {
                    $segments[0] = $this->default_controller;
                    return $segments;
                }
            }

为了让CI_ROUTER知道我们模块拓展的位置,我们在配置文件中加入选项,并在CI_ROUTER的构造器中加入如下代码:

$locations = $this->config->item('modules_locations');

		if (!$locations) {
			$locations = array('modules/');
		} else if (!is_array($locations)) {
			$locations = array($locations);
		}

		$this->config->set_item('modules_locations', $locations);

操作完以上步骤,就可以实现大部分HMVC的拓展了。 本文代码:https://git.oschina.net/liwenlong/Codeigniter-3-HMVC.git 说明:CI3中对控制器大小写由严格的控制了,为了符合CI3的一贯规则,所以我们使用了ucfirst()方式寻找首字母大写的类名,一定要注意。

© 著作权归作者所有

共有 人打赏支持
o0无忧亦无怖
粉丝 33
博文 73
码字总数 49267
作品 1
程序员
加载中

评论(2)

海诺者
海诺者
哟西(๑´ㅂ`๑)
首席技师
首席技师
79
使用CodeIgniter框架搭建RESTful API服务

使用CodeIgniter框架搭建RESTful API服务 发表于 2014-07-12 | 分类于 翻译笔记 | 6条评论 在2011年8月的时候,我写了一篇博客《使用CodeIgniter框架搭建RESTful API服务》,介绍了RESTful的...

thinkyoung ⋅ 2015/08/07 ⋅ 0

Windows10环境下Codelgniter安装及配置说明

CodeIgniter ,简称CI,是一套给 PHP 网站开发者使用的应用程序开发框架和工具包。 它的目标是让你能够更快速的开发,它提供了日常任务中所需的大量类库, 以及简单的接口和逻辑结构。通过减...

Yuanmes ⋅ 05/02 ⋅ 0

CodeIgniter中运用composer安装依赖包

基本信息 + CodeIgniter 版本:3.1.8+ Nginx: Tengine/2.1.2 (nginx/1.6.2)+ MySQL: Ver 14.14 Distrib 5.6.33, for Linux (x86_64) using EditLine wrapper+ PHP: 5.6.30+ Zend Engine ......

冷三叔 ⋅ 04/28 ⋅ 0

Laradock 7.0.2 发布,Docker 的 PHP 本地开发环境

Laradock 7.0.2 已发布,更新内容如下: 更新 Kibana 版本以匹配 Elasticsearch 的版本; 修复 php 5.6 drush “Segmentation fault” 报错; 修复 php 7.0 swoole 构建失败。 更多细节可查阅...

王练 ⋅ 昨天 ⋅ 0

CodeIgniter的伪静态配置

基本信息 + CodeIgniter 版本:3.1.8+ Nginx: Tengine/2.1.2 (nginx/1.6.2)+ MySQL: Ver 14.14 Distrib 5.6.33, for Linux (x86_64) using EditLine wrapper+ PHP: 5.6.30+ Zend Engine ......

冷三叔 ⋅ 04/28 ⋅ 0

PHP 开源网站管理系统 - POSCMS

POSCMS 介绍 PHP 开源网站管理系统(PhpOpenSourceCMS,简称POSCMS)以开放、开源、灵活为产品理念,基于 PHP+MYSQL+CI 框架开发的开源 Web 内容管理系统,程序完美兼容 PHP7 ,并在 PHP7 基...

天睿云计算 ⋅ 2017/05/19 ⋅ 1

POSCMS V3.2.18 发布,跨平台网站内容管理系统

POSCMS V3.2.18 已发布,PHP开源内容管理系统(PhpOpenSourceCMS简称POSCMS)是Php+Mysql开发的一款开源的跨平台网站内容管理系统。POSCMS系统基于CodeIgniter框架,具有良好扩展性和管理性。...

天睿云计算 ⋅ 04/24 ⋅ 0

php基于thinkphp、smarty\CodeIgniter构建的开源的淘宝客cms程序下载

现在有很多开源的淘宝客软件cms,很多人不知道,所以,提供该服务,完全开源,比市面上的加密的好很多, 这些开源的淘宝客程序代码写的都非常简约,适合学习观摩,所以,收集了一些优秀的开源...

616921521 ⋅ 05/30 ⋅ 0

Yaf 中使用 Larvael Eloquent ORM

本教程示例代码见:https://github.com/creazy412/yaf2eloquentorm 背景介绍 Yaf 是鸟哥(Laruence)在俩年前写的一个PHP扩展的MVC框架. 开发Yaf的目的是为了解决使用框架带来的性能下降的经...

老K8 ⋅ 05/31 ⋅ 0

php-Codeigniter使用redis

1、安装redis 首先计算机上必须已经装了redis服务(redis数据库)并运行,详见另一篇文章:http://blog.csdn.net/wzj0808/article/details/54891178 2、安装phpredis <1>下载 项目地址:htt...

梦梦阁 ⋅ 06/06 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Day 17 vim简介与一般模式介绍

vim简介 vi和Vim的最大区别就是编辑一个文件时vi不会显示颜色,而Vim会显示颜色。显示颜色更便于用户编辑,凄然功能没有太大的区别 使用 yum install -y vim-enhanced 安装 vim的三种常用模式...

杉下 ⋅ 27分钟前 ⋅ 0

【每天一个JQuery特效】根据可见状态确定是否显示或隐藏元素(3)

效果图示: 主要代码: <!DOCTYPE html><html><head><meta charset="UTF-8"><title>根据可见状态确定 是否显示或隐藏元素</title><script src="js/jquery-3.3.1.min.js" ty......

Rhymo-Wu ⋅ 36分钟前 ⋅ 0

OSChina 周四乱弹 —— 初中我身体就已经垮了,不知道为什么

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @加油东溪少年 :下完这场雨 后弦 《下完这场雨》- 后弦 手机党少年们想听歌,请使劲儿戳(这里) @马丁的代码 :买了日本 日本果然赢了 翻了...

小小编辑 ⋅ 55分钟前 ⋅ 8

浅谈springboot Web模式下的线程安全问题

我们在@RestController下,一般都是@AutoWired一些Service,由于这些Service都是单例,所以并不存在线程安全问题。 由于Controller本身是单例模式 (非线程安全的), 这意味着每个request过来,...

算法之名 ⋅ 今天 ⋅ 0

知乎Java数据结构

作者:匿名用户 链接:https://www.zhihu.com/question/35947829/answer/66113038 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 感觉知乎上嘲讽题主简...

颖伙虫 ⋅ 今天 ⋅ 0

Confluence 6 恢复一个站点有关使用站点导出为备份的说明

推荐使用生产备份策略。我们推荐你针对你的生产环境中使用的 Confluence 参考 Production Backup Strategy 页面中的内容进行备份和恢复(这个需要你备份你的数据库和 home 目录)。XML 导出备...

honeymose ⋅ 今天 ⋅ 0

JavaScript零基础入门——(九)JavaScript的函数

JavaScript零基础入门——(九)JavaScript的函数 欢迎回到我们的JavaScript零基础入门,上一节课我们了解了有关JS中数组的相关知识点,不知道大家有没有自己去敲一敲,消化一下?这一节课,...

JandenMa ⋅ 今天 ⋅ 0

火狐浏览器各版本下载及插件httprequest

各版本下载地址:http://ftp.mozilla.org/pub/mozilla.org//firefox/releases/ httprequest插件截至57版本可用

xiaoge2016 ⋅ 今天 ⋅ 0

Docker系列教程28-实战:使用Docker Compose运行ELK

原文:http://www.itmuch.com/docker/28-docker-compose-in-action-elk/,转载请说明出处。 ElasticSearch【存储】 Logtash【日志聚合器】 Kibana【界面】 答案: version: '2'services: ...

周立_ITMuch ⋅ 今天 ⋅ 0

使用快嘉sdkg极速搭建接口模拟系统

在具体项目研发过程中,一旦前后端双方约定好接口,前端和app同事就会希望后台同事可以尽快提供可供对接的接口方便调试,而对后台同事来说定好接口还仅是个开始、设计流程,实现业务逻辑,编...

fastjrun ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部