Codeigniter 3 拓展HMVC
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
在Codeiniter(以下統(tǒng)稱CI) 2.X版本中,我們就通過(guò)拓展核心類庫(kù)實(shí)現(xiàn)了HMVC,但是同樣的代碼,拿到CI 3中,就很有可能不好用了。
###拓展核心類庫(kù)方式
官方的文檔對(duì)拓展核心類有詳細(xì)的說(shuō)明:
你定義的類必須繼承自父類。 你的類名和文件名必須以 MY_ 開(kāi)頭。(這是可配置的,見(jiàn)下文) 舉個(gè)例子,要擴(kuò)展原始的 Input 類,你需要新建一個(gè)文件 application/core/MY_Input.php,然后像下面這樣定義你的類:
class MY_Input extends CI_Input {}CI 控制器加載的過(guò)程很簡(jiǎn)單,官方文檔有圖如下:
我們可以看到,在控制器開(kāi)始加載看,CI是做了Routing(路由)和Security(安全)的操作的,所以,我們需要重寫(xiě),或者說(shuō),在CI拓展我們想要的功能,比如:HMVC
###2.0中擴(kuò)展
在2.0版本中,筆者曾適用過(guò)Jens Segers開(kāi)源的HMVC模塊,代碼的實(shí)現(xiàn)就是對(duì)Routee和Loader進(jìn)行了重寫(xiě)。 Jens Segers的主頁(yè) 核心的代碼如下:
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);}// 子文件夾包含有默認(rèn)控制器?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;}// 適用默認(rèn)的控制器?if (is_file($source . $this->default_controller . '.php')) {$segments[0] = $this->default_controller;return $segments;}}很簡(jiǎn)單的拓展 就能實(shí)現(xiàn)HMVC模式了,同樣的,還得重寫(xiě)Loader中的加載器,不然會(huì)找不到文件。
###CI 3 HMVC拓展 到了CI3中,上述方法已經(jīng)不好用了,CI 3 對(duì)路由有了更多的考慮,在初始化路由時(shí),就進(jìn)行了解析。假設(shè)寫(xiě)MY_Ruter類,必須要重寫(xiě)3個(gè)方法: CI 2 Router構(gòu)造
function __construct(){$this->config =& load_class('Config', 'core');$this->uri =& load_class('URI', 'core');log_message('debug', "Router Class Initialized");}CI 3 Router構(gòu)造
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的構(gòu)造方法中就已經(jīng)對(duì)URL進(jìn)行解析,方法的調(diào)用過(guò)程為: _set_routing() -> _validate_request() -> _parse_routes() -> _set_request() 那我們?yōu)榱艘獙?shí)現(xiàn)HMVC,這幾個(gè)方法是必然要按照我們自己的方法實(shí)現(xiàn)的。 _validate_request 中 我們加入部分驗(yàn)證,即可達(dá)到簡(jiǎn)單的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 是一個(gè)文件夾if ($directory && is_dir($source . $directory . '/')) {$source = $source . $directory . '/';$this->directory .= $directory . '/';// index.php/$modules/$directory/$controller//如果包含 控制器 $controllerif ($controller && is_file($source . ucfirst($controller) . '.php')) {return array_slice($segments, 2);}//如果有默認(rèn)控制器if (is_file($source . $this->default_controller . '.php')) {$segments[1] = $this->default_controller;return array_slice($segments, 1);}//如果有 application/$module/$directory.phpif (is_file($source . $directory . '.php')) {return array_slice($segments, 1);}}//如果有 application/$module/$module.php if (is_file($source . $module . '.php')) {return $segments;}// 默認(rèn)控制器if (is_file($source . $this->default_controller . '.php')) {$segments[0] = $this->default_controller;return $segments;}}為了讓CI_ROUTER知道我們模塊拓展的位置,我們?cè)谂渲梦募屑尤脒x項(xiàng),并在CI_ROUTER的構(gòu)造器中加入如下代碼:
$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);操作完以上步驟,就可以實(shí)現(xiàn)大部分HMVC的拓展了。 本文代碼:https://git.oschina.net/liwenlong/Codeigniter-3-HMVC.git 說(shuō)明:CI3中對(duì)控制器大小寫(xiě)由嚴(yán)格的控制了,為了符合CI3的一貫規(guī)則,所以我們使用了ucfirst()方式尋找首字母大寫(xiě)的類名,一定要注意。
轉(zhuǎn)載于:https://my.oschina.net/lwl1989/blog/516666
總結(jié)
以上是生活随笔為你收集整理的Codeigniter 3 拓展HMVC的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: ***ECharts图表入门和最佳实践
- 下一篇: Fgui: Glist 实现无限滑动 虚
