本文目录导读:

在 Joomla 中,模型-视图-控制器(MVC) 是一种设计模式,用于将应用程序的业务逻辑(模型)、用户界面(视图)和用户输入处理(控制器)分离开来,这是 Joomla 组件开发的核心架构。
注意: 从 Joomla 4 开始,Joomla 的 MVC 架构发生了显著变化(引入了基于名称空间的 MVCFactory 和新的 Model / Controller 基类),以下是基于 Joomla 4 和 Joomla 5 的标准解释(同时会标注与 Joomla 3 的区别)。
控制器 (Controller)
职责: 处理用户请求(如点击提交按钮、访问特定 URL),调用相应的模型获取数据,并决定渲染哪个视图。
位置: src/Controller/ 目录下。
核心类: Joomla\CMS\MVC\Controller\BaseController 或 AdminController, SiteController。
工作原理:
- 用户访问 URL(如
index.php?option=com_mycomponent&task=article.edit)时,Joomla 路由找到对应的控制器。 - 控制器接收
task参数,执行相应的方法(如edit())。 - 控制器通常会检查用户权限,调用模型,并将数据传递到视图。
示例(Joomla 4):
// src/Controller/ArticleController.php
namespace MyCompany\Component\MyComponent\Site\Controller;
use Joomla\CMS\MVC\Controller\BaseController;
class ArticleController extends BaseController {
public function display($cachable = false, $urlparams = []) {
// 获取模型
$model = $this->getModel('Article');
// 获取数据
$article = $model->getItem();
// 设置视图
$view = $this->getView('Article', 'html');
$view->setModel($model, true);
$view->display();
}
}
模型 (Model)
职责: 负责业务逻辑和数据操作(与数据库交互、数据验证、状态管理等)。
位置: src/Model/ 目录下。
核心类: Joomla\CMS\MVC\Model\BaseDatabaseModel 或 AdminModel, SiteModel。
关键方法:
getItem($pk = null):获取单条记录。getItems():获取列表数据。save($data):保存数据。publish($pks, $value):更改发布状态。
示例(Joomla 4):
// src/Model/ArticleModel.php
namespace MyCompany\Component\MyComponent\Site\Model;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
class ArticleModel extends BaseDatabaseModel {
public function getItem($pk = null) {
$db = $this->getDatabase();
$query = $db->getQuery(true);
$query->select('*')
->from($db->quoteName('#__mycomponent_articles'))
->where($db->quoteName('id') . ' = ' . (int) $pk);
$db->setQuery($query);
return $db->loadObject();
}
}
视图 (View)
职责: 获取模型数据,并将数据渲染为用户可读的 HTML 输出。
位置: src/View/ 目录下(分 HtmlView, JSONView 等)。
核心类: Joomla\CMS\MVC\View\HtmlView 或 JsonView。
关键文件:
view.html.php(旧版 Joomla 3)或在 Joomla 4 中对应的View类,加上对应的tmpl模板文件(如tmpl/default.php)。- 视图类负责调用模型,然后将数据分配给模板。
示例(Joomla 4):
// src/View/Article/HtmlView.php
namespace MyCompany\Component\MyComponent\Site\View\Article;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
class HtmlView extends BaseHtmlView {
protected $item;
public function display($tpl = null) {
$this->item = $this->get('Item'); // 从模型中获取数据
parent::display($tpl);
}
}
对应的模板文件:tmpl/default.php 使用 $this->item 输出数据。
Joomla 3 vs Joomla 4/5 的关键区别
| 特性 | Joomla 3 | Joomla 4/5 |
|---|---|---|
| 文件命名 | controller.php, model.php, view.html.php 在组件根目录 |
使用 名称空间,文件放在 src/Controller/, src/Model/, src/View/ |
| 视图类 | 强制使用 ViewLegacy 基类 |
使用 HtmlView, JsonView 等清晰类名 |
| 模型工厂 | 直接 $this->getModel() 使用字符串 |
通过 MVCFactory 自动加载,支持依赖注入 |
| 前端视图后缀 | .html.php |
.php(名称空间决定类型) |
工作流程示例
用户访问 index.php?option=com_mycomponent&view=article&id=5
- 路由 解析
option=com_mycomponent,加载组件。 - 控制器 找到
ArticleController并调用display()方法。 - 模型
ArticleModel从数据库查询id=5的文章。 - 视图
ArticleView接收模型数据,渲染tmpl/default.php模板。 - 输出 Joomla 将生成的 HTML 嵌入页面布局。
最佳实践
- 保持分离:控制器不做数据库查询,视图不做数据处理,模型只返回数据。
- 使用 Joomla API:在模型中使用
$this->getDatabase()而非直接创建JDatabaseDriver。 - 遵循命名约定:Joomla 的 MVC 工厂通过类名和名称空间自动加载,因此文件名、类名和路径必须严格对应。
- 安全验证:在控制器和模型中进行权限检查(如
$this->authorise('core.edit'))。
如果需要更详细的代码示例(如如何创建完整的 Joomla 4 组件),可以参考 Joomla 官方文档或使用 Joomla Component Builder 工具。