1. 簡(jiǎn)介
Joomla 是一款基于PHP開發(fā)的CMS系統(tǒng),整體采用MVC模式開發(fā),本文主要介紹Joomla擴(kuò)展組件的MVC開發(fā)模式。
1.1 MVC模式
MVC模式是非常經(jīng)典的開發(fā)模式,將代碼功能分為三個(gè)部分,Model, View, Controller。其中 Model 用于提供數(shù)據(jù)對(duì)象;View 用戶展示數(shù)據(jù)對(duì)象,并且與用戶交互;Controller 則提供邏輯處理,將用戶的操作進(jìn)行特定邏輯的處理,更新Model,通知View。
1.2 Joomla 中的 MVC
Joomla系統(tǒng)提供了MVC模式開發(fā)的大量接口,可以方便的進(jìn)行操作。其中Component開發(fā)大部分都是通過典型的MVC模式,并且包含了大部分自動(dòng)化的加載和處理,使得開發(fā)非常簡(jiǎn)單。
2. MVC 開發(fā)規(guī)則
2.1 開發(fā)規(guī)則
Component 可以實(shí)現(xiàn)界面視圖、邏輯操作,因此MVC模式在Component 中使用最多。
- 每一個(gè)Component 都包含前臺(tái)界面和后臺(tái)管理頁面,開發(fā)分成兩套代碼;
- 每一個(gè)Component的主入口,都直接創(chuàng)建一個(gè)主控制器Controller用于分發(fā);
- 每一個(gè)Controller會(huì)自動(dòng)顯示與當(dāng)前Controller同名的View;
- 每一個(gè)View 內(nèi)部的 get() 方法,都會(huì)自動(dòng)加載同名的 Model 請(qǐng)求;
2.2 代碼目錄結(jié)構(gòu)
Joomla擴(kuò)展項(xiàng)目的代碼目錄有一套命名規(guī)則,根據(jù)規(guī)則能夠讓平臺(tái)自動(dòng)查找相關(guān)的類進(jìn)行加載。
- 頂層目錄的 controller.php 主控制器定義;
- controllers 目錄:所有的視圖控制器,自定義控制器,task控制器都在這里;
- views 目錄:所有的視圖類都在這里進(jìn)行定義;
- models 目錄:所有的數(shù)據(jù)訪問相關(guān)的模型類在這里進(jìn)行定義;
- tables 目錄:所有的數(shù)據(jù)庫表定義在這里進(jìn)行定義;
- language 目錄:所有的國(guó)際化字符串內(nèi)容在這里定義;
3. Controller 說明
3.1 Controller 主控制器
Joomla中的Controller只有主控制器對(duì)象是通過手動(dòng)創(chuàng)建的,其余的Controller,大部分是通過框架代碼創(chuàng)建對(duì)象實(shí)例的。以下代碼會(huì)創(chuàng)建一個(gè)Controller實(shí)例對(duì)象,并且會(huì)處理和分發(fā)所有的請(qǐng)求。
<?php
defined('_JEXEC') or die;
$controller = JControllerLegacy::getInstance('NovelSystem');
$controller->execute(JFactory::getApplication()->input->get('task'));
$controller->redirect();
上述代碼是主入口代碼,包含了非常重要的規(guī)則信息:
- JControllerLegacy::getInstance 會(huì)自動(dòng)加載當(dāng)前目錄的controller.php;
- getInstance 的參數(shù)會(huì)影響所有的需要開發(fā)的代碼;
- MVC各個(gè)對(duì)象的名稱必須以 NovelSystem 開頭,忽略大小寫;
- 加載的controller.php 類名必須是 NovelSystemController
Joomla 以前綴的方式來規(guī)定一套代碼的命名方式,從而實(shí)現(xiàn)自動(dòng)化代碼的加載。
例如: 前綴為NovelSystem 那么大部分類都需要以這個(gè)為前綴。
3.1 SubController 的說明
SubController 是在 controllers 目錄中的所有Controller的總稱,通常我們會(huì)創(chuàng)建controllers 目錄,另外 controller 目錄也是支持的。
SubController包含以下作用:
- 每一個(gè)View都可以有一個(gè)Controller,這個(gè)Controller與View名稱同名
- Joomla網(wǎng)址中的 task 任務(wù)可以采用 subcontroller.task 的方式定義
- 每一個(gè) task 在主控制器處理的時(shí)候,會(huì)自動(dòng)分發(fā)給 SubController 來處理
舉例說明SubController的使用方式:
現(xiàn)有View 對(duì)象 NovelSystemViewLogin,需要處理按鈕點(diǎn)擊的操作
NovelSystemViewLogin 視圖中按鈕會(huì)提交Form表單,F(xiàn)orm表單的action 指向業(yè)務(wù)處理地址,這個(gè)地址包含參數(shù) task=login,當(dāng)用戶點(diǎn)擊操作的時(shí)候,Joomla平臺(tái)會(huì)根據(jù)task參數(shù)來定位login。當(dāng)主控制器沒有找到對(duì)應(yīng)的方法時(shí),會(huì)分發(fā)給SubController。
- 主控制器執(zhí)行 execute,處理task參數(shù),沒有處理,則轉(zhuǎn)發(fā)給子控制器
- 獲取View的名稱 "前綴View名稱" 的方式,找到實(shí)際名稱 login,注意是小寫
- 根據(jù)View名稱 login, 去 controllers 目錄查找 login.php 嘗試加載
- 再根據(jù) "前綴Controller名稱" 的方式拼接為 NovelSystemControllerLogin
- 加載并且調(diào)用任務(wù)方法 login,發(fā)現(xiàn)存在,那么直接執(zhí)行
4. View 說明
主Controller可以設(shè)置默認(rèn)的視圖名稱,平臺(tái)會(huì)自動(dòng)加載指定名稱的視圖進(jìn)行顯示。主控制器默認(rèn)的 task 任務(wù)是 “display”,會(huì)直接進(jìn)行View的顯示。
4.1 View 的命名規(guī)則
創(chuàng)建View 或者是加載View有一套名稱命名規(guī)則,Joomla平臺(tái)自動(dòng)根據(jù)命名規(guī)范來進(jìn)行加載。以下以 login 視圖作為參考樣例,前綴為 NovelSystem。
- 在views目錄中,每一個(gè)文件夾都是一個(gè)View視圖的名稱
- login視圖就需要?jiǎng)?chuàng)建 views/login/ 目錄
- 視圖php文件名稱通常是
view.html.php代表是一個(gè)html視圖 - 視圖類文件的完整路徑為:
views/login/view.html.php - 視圖類內(nèi)部 定義的類必須是繼承 JViewLegacy 或者子類的;
- 類名稱必須是 “前綴View名稱” 的方式,對(duì)于login為: NovelSystemViewLogin
- 關(guān)于大小寫:Joomla查找目錄、文件的時(shí)候會(huì)將類名稱進(jìn)行小寫轉(zhuǎn)換,不需要特殊處理;
- 視圖類的 display 方法會(huì)默認(rèn)調(diào)用,是通過主控制器默認(rèn)display來分發(fā)的。
4.2 View與Model的交互
大部分View需要加載數(shù)據(jù)并且顯示,在View視圖類中獲取數(shù)據(jù)不需要直接與Model打交道,除非特殊情況。一般進(jìn)行數(shù)據(jù)加載的方式是直接通過 View的get()方法來獲取數(shù)據(jù)。
View 視圖類 有一個(gè) get($propertyName) 的方法,這個(gè)方法也是與Model交互的方法。
舉例說明:
View 中調(diào)用方法 get('Item'); 注意大小寫 會(huì)進(jìn)行以下一些操作:
- View 內(nèi)部檢查是否獲取了 model 對(duì)象,通過 model 對(duì)象獲取數(shù)據(jù);
- View 內(nèi)部如果沒有獲取 model對(duì)象,那么根據(jù)規(guī)則獲取 View的名稱 login;
- 根據(jù)login 來查找 models/login.php 這個(gè)文件;
- 加載名稱,類名需要是 “前綴Model名稱”,本例為 NovelSystemModelLogin
- 實(shí)例化NovelSystemModelLogin對(duì)象,查找方法 getItem() 注意大小寫;
- 調(diào)用 Model的 getItem() 方法,返回?cái)?shù)據(jù),交給View來使用;
- 注意get()方法的參數(shù)會(huì)直接拼接到 getXxxx 的方式,注意大小寫。
5. 總結(jié)
Joomla的MVC模式大量的依賴于命名規(guī)范,通過內(nèi)部的自動(dòng)化加載的方式,將代碼之間的關(guān)聯(lián)隱藏在內(nèi)部,開發(fā)人員只需要按照命名規(guī)范進(jìn)行代碼開發(fā),實(shí)現(xiàn)代碼的松耦合。