PHPCMS V9 採用模塊化架構,二次開發核心是創建符合規範的模塊。本文基於實戰經驗,系統梳理模塊目錄結構、每個核心文件職責、數據模型定義、後台控制器開發、安裝/協載流程,助你快速上手模塊開發。
phpcms/modules/my_test/ # 模塊標識: my_test ├── classes/ # 模塊專用類庫 ├── functions/ # 模塊公共函數 ├── install/ # 安裝相關 │ ├── config.ini.php # 安裝配置 │ ├── menu.php # 後台菜單定義 │ └── sql/ # 建表 SQL ├── language/ # 多語言包 ├── templates/ # 模板文件 ├── config.ini.php # 模塊元信息 ├── extention.inc.php # 菜單/權限註冊 ├── model.php # 使用的數據模型列表 ├── my_test.sql # 主表建表語句 ├── my_test.php # 後台控制器 └── index.php # 前台控制器
phpcms/model/my_test_model.class.php<?php
defined('IN_PHPCMS') or exit('No permission resources.');
pc_base::load_sys_class('model', '', 0);
class my_test_model extends model {
public function __construct() {
$this->db_config = pc_base::load_config('database');
$this->db_setting = 'default';
$this->table_name = 'my_test'; // 不含表前綴
parent::__construct();
}
}
?>
model 類,自動獲得 CURD 方法(insert/update/delete/select/get_one...)table_name 不加表前綴,系統自動拼接config.ini.php$module = 'my_test';
$modulename = '我的測試模塊';
$introduce = '演示模塊開發流程';
$author = 'Your Name';
$authorsite = 'https://example.com';
$authoremail = 'dev@example.com';
extention.inc.php<?php
// 插入後台菜單,返回菜單 ID
$menuId = $menu_db->insert([
'name' => '我的測試列表',
'parentid' => 0, // 頂級菜單
'm' => 'my_test', // 模塊
'c' => 'my_test', // 控制器
'a' => 'init', // 方法
'data' => '',
'listorder' => 100,
'display' => 1
], true);
// 註冊語言包鍵值(對應 language/zh-cn/system_menu.lang.php)
$language = [
'我的測試列表' => '我的測試列表',
'my_test_init' => '列表管理',
];
?>
model.phpreturn ['my_test', 'my_test_article']; // 使用的模型名(對應 model/ 目錄下類文件)
install/sql/my_test.sqlCREATE TABLE `{table_pre}my_test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL DEFAULT '',
`content` text,
`inputtime` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
系統安裝時自動替換 {table_pre} 為配置的表前綴(如 v9_)。
my_test.php<?php
defined('IN_PHPCMS') or exit('No permission resources.');
pc_base::load_app_class('admin', 'admin', 0);
class my_test extends admin {
public function __construct() {
parent::__construct();
$this->db = pc_base::load_model('my_test_model');
}
public function init() {
$page = max(intval($_GET['page']), 1);
$data = $this->db->listinfo('', 'id DESC', $page, 20);
$pages = $this->db->pages;
include $this->admin_tpl('my_test_list');
}
public function add() {
if (isset($_POST['dosubmit'])) {
$data = array_map('trim', $_POST['info']);
$this->db->insert($data);
showmessage('添加成功', HTTP_REFERER);
}
include $this->admin_tpl('my_test_add');
}
public function edit() {
$id = intval($_GET['id']);
if (isset($_POST['dosubmit'])) {
$data = array_map('trim', $_POST['info']);
$this->db->update($data, ['id' => $id]);
showmessage('修改成功', HTTP_REFERER);
}
$info = $this->db->get_one(['id' => $id]);
include $this->admin_tpl('my_test_edit');
}
public function delete() {
$id = intval($_GET['id']);
$this->db->delete(['id' => $id]);
showmessage('刪除成功', HTTP_REFERER);
}
}
?>
templates/my_test_list.tpl.php<table class="table_list">
<thead><tr><th>ID</th><th>標題</th><th>時間</th><th>操作</th></tr></thead>
<tbody>
<?php foreach($data as $v) { ?>
<tr>
<td><?=$v['id']?></td>
<td><?=$v['title']?></td>
<td><?=date('Y-m-d H:i', $v['inputtime'])?></td>
<td>
<a href="?m=my_test&c=my_test&a=edit&id=<?=$v['id']?>">編輯</a> |
<a href="?m=my_test&c=my_test&a=delete&id=<?=$v['id']?>" onclick="return confirm('確定刪除?')">刪除</a>
</td>
</tr>
<?php } ?>
</tbody>
</table>
<div class="pages"><?=$pages?></div>
my_test → 提交install/sql/*.sql 建表config.ini.php 寫入模塊表extention.inc.php 註冊菜單、權限、語言包model.php 註冊模型關聯| 問題 | 原因 | 解決 |
|---|---|---|
| 安裝報錯「表已存在」 | 協載未執行 SQL 刪除 | 先在後台協載,或手動 DROP TABLE |
| 菜單不顯示 | extention.inc.php 未返回 menuId / parentid 錯誤 | 檢查父菜單 ID 是否存在,確保 return $menuId |
| 模型方法調用失敗 | model.php 未聲明或模型類文件命名不規範 | 模型文件必須為 xxx_model.class.php,類名 xxx_model |
| 模板找不到 | 路徑錯誤 | 用 $this->admin_tpl('template_name') 自動解析路徑 |
<?php
defined('IN_PHPCMS') or exit('No permission resources.');
pc_base::load_app_class('index', 'index', 0);
class index extends index {
private $db;
public function __construct() {
parent::__construct();
$this->db = pc_base::load_model('my_test_model');
}
public function init() {
$data = $this->db->select(['status' => 1], '*', 'id DESC', 10);
include template('my_test', 'index');
}
}
?>
前台模板放在 phpcms/templates/default/content/my_test_index.html,使用標籤 {pc:content action="lists" catid="..."} 或直接遍歷 $data。