如何使用AI开发iCMS8应用,完整提示词规范
iCMS8 前后端应用开发规范
一、项目概述
1.1 技术栈
- 后端框架: iPHP (自研PHP框架)
- 数据库: MySQL 5.0+
- 前端: HTML + JavaScript + Vue.js (部分模块)
- 模板引擎: TemplateLite (类Smarty)
- 支持特性: 多语言、分表分库、事件驱动、缓存系统
1.2 核心特点
- MVC架构模式
- 模块化应用设计
- 国际化(i18n)支持
- RESTful路由
- 事件钩子机制
- 数据模型ORM
二、应用目录结构规范
2.1 标准应用目录结构
app/[应用名]/
├── [App]Model.php # 数据模型 (必需)
├── [App]DataModel.php # 数据表模型 (可选,用于分表)
├── [App]Admincp.php # 后台控制器 (必需)
├── [App]App.php # 前台控制器 (必需)
├── [App]UserApp.php # 用户中心控制器 (可选)
├── [App]Func.php # 模板标签函数 (必需)
├── [App]Hook.php # 钩子文件 (可选)
├── [App]Event.php # 事件处理 (可选)
├── assets/ # 静态资源
│ ├── js/ # JavaScript文件
│ └── *.css # CSS样式文件
├── etc/ # 配置目录
│ ├── lang/ # 多语言配置
│ │ ├── zh-cn.json # 通用语言包
│ │ ├── zh-cn.admincp.json # 后台语言包
│ │ └── zh-cn.usercp.json # 前台语言包
│ ├── menu/ # 菜单配置
│ ├── route/ # 路由配置
│ └── config/ # 应用配置
└── views/ # 后台视图模板
├── index.html # 列表页
├── add.html # 添加页
├── edit.html # 编辑页
└── app/ # 其他视图
---
## 三、后端开发规范
### 3.1 Model 数据模型开发
#### 3.1.1 基础模型结构
```php
<?php
defined('iPHP') or exit('What are you doing?');
class ArticleModel extends Model
{
// 状态映射
public static $statusMap = [
'0' => '草稿',
'1' => '正常',
'2' => '回收站',
];
// 字段类型转换
protected $casts = [
'picdata' => 'array',
'nodeAttrs' => 'array',
];
// 事件绑定
protected $events = [
'delete' => ['ArticleEvent', 'delete'],
'changed' => ['ArticleEvent', 'changed'],
];
}
3.1.2 数据模型关键属性
- $statusMap: 状态映射数组
- $casts: 字段类型自动转换 (array, json, html等)
- $events: 模型事件绑定
- $callback: 异常回调处理
3.1.3 分表模型 (DataModel)
class ArticleDataModel extends Model
{
// 分表策略
public static function sharding($article_id)
{
$model = self::getInstance();
$model->sharding = (int)$article_id % 10;
return $model;
}
// 自动创建表
protected $callback = [
'SQLSTATE:42S02' => [__CLASS__, 'createTable'],
];
}
3.2 Admincp 后台控制器开发
iCMS8 提供了三种后台应用开发模式,根据功能需求选择合适的开发方式。
3.2.1 模式一:标准 CRUD 应用开发 ⭐ 推荐
适用场景: 需要完整增删改查(CRUD)功能的应用模块,如文章管理、用户管理、商品管理等。
开发方式:
<?php
defined('iPHP') or exit('What are you doing?');
defined('APP_URL') or define('APP_URL', '/admincp.php/article');
class ArticleAdmincp extends AdmincpCommon
{
use AdmincpCommonTrait; // 关键:使用 Trait
// 排序字段配置
public static $orderBy = [
'id' => 'ID',
'hits' => '点击',
'postime' => '时间',
'weight' => '权重',
];
}
核心特点:
- ✅ 自动继承功能: 通过
AdmincpCommon和AdmincpCommonTrait,自动获得完整的增删改查、批量操作、状态管理等功能 - ✅ 快速开发: 只需绑定模型类,即可快速实现数据管理功能
- ✅ 扩展性强: 可以通过重写 Trait 中的方法实现自定义逻辑
自动提供的功能:
- 列表展示 (
do_index()) - 添加/编辑 (
do_add()) - 保存数据 (
do_save()) - 删除操作 (
do_delete()) - 批量操作 (
do_batch()) - 状态管理 (
do_status()) - 排序管理 (
do_sort())
自定义扩展示例:
class ArticleAdmincp extends AdmincpCommon
{
use AdmincpCommonTrait;
/**
* 保存前数据处理
*/
protected function saving(&$data)
{
// 自动设置编辑者
if (empty($this->id)) {
$data['editor'] = Admin::$nickname;
$data['userid'] = Admin::$user_id;
}
// 数据验证
empty($data['title']) && self::alert('标题不能为空');
// 自动生成摘要
if (empty($data['description'])) {
$data['description'] = mb_substr(strip_tags($data['content']), 0, 200);
}
// 返回 true 表示验证通过
return true;
}
/**
* 列表数据处理
*/
protected function index_data(&$resource)
{
foreach ($resource as &$item) {
// 添加自定义字段
$item['category_name'] = CategoryModel::getValue($item['cid'], 'name');
}
}
/**
* 自定义添加/编辑页面
*/
public function do_add()
{
// 获取数据
$rs = $this->id ? ArticleModel::get($this->id) : [];
// 初始化默认值
if (empty($this->id)) {
$rs['status'] = '1';
$rs['postype'] = '1';
}
// 加载视图
include self::view();
}
}
3.2.2 模式二:简单功能应用开发
适用场景: 仅需基础功能(如列表查看、详情展示)的应用模块,如文件管理、日志查看等。
开发方式:
<?php
defined('iPHP') or exit('What are you doing?');
class FilesAdmincp extends AdmincpCommon
{
// 注意:不使用 AdmincpCommonTrait
/**
* 列表页
*/
public function do_index()
{
$where = [];
$model = FilesModel::field('*');
// 条件筛选
$keyword = Request::get('keyword');
$keyword && $where[] = ['name', 'LIKE', "%{$keyword}%"];
// 查询数据
$resource = $model->where($where)
->orderBy('id', 'DESC')
->paginate(20);
include self::view();
}
/**
* 详情页
*/
public function do_view()
{
$id = Request::get('id');
$file = FilesModel::get($id);
include self::view();
}
}
核心特点:
- ✅ 轻量级: 仅继承
AdmincpCommon,不引入AdmincpCommonTrait,减少不必要的功能 - ✅ 功能精简: 默认支持列表查看和详情展示,无需额外编码
- ✅ 可配置性: 通过覆盖方法或配置属性,可以禁用不需要的功能
适用场景:
- 仅需查看数据列表或详情,无需编辑、删除等操作
- 功能简单,不需要复杂的业务逻辑
- 只读型数据管理
3.2.3 模式三:基础定制应用开发
适用场景: 需要完全自定义功能逻辑的应用模块,如系统配置、特殊功能模块等。
开发方式:
<?php
defined('iPHP') or exit('What are you doing?');
class ConfigAdmincp extends AdmincpBase
{
// 完全自定义功能
/**
* 配置页面
*/
public function do_index()
{
// 获取配置
$config = ConfigModel::getAll();
include self::view();
}
/**
* 保存配置
*/
public function do_save()
{
$data = Request::post('config');
// 自定义验证逻辑
empty($data['site_name']) && self::alert('网站名称不能为空');
// 自定义保存逻辑
foreach ($data as $key => $value) {
ConfigModel::set($key, $value);
}
// 清除缓存
Cache::delete('config');
// 返回成功
return [true, '保存成功'];
}
/**
* 清理缓存
*/
public function do_clear_cache()
{
Cache::flush();
return [true, '缓存已清理'];
}
}
核心特点:
- ✅ 完全自主: 继承
AdmincpBase,不依赖AdmincpCommon和 Trait,开发者可以完全自定义功能逻辑 - ✅ 灵活性高: 适合需要特殊处理或复杂业务逻辑的场景
- ⚠️ 手动实现: 需要开发者手动实现数据管理、权限控制等功能
适用场景:
- 需要完全自定义的功能模块
- 功能逻辑复杂,无法通过标准 CRUD 模式实现
- 系统级配置管理
3.2.4 开发模式对比
| 特性 | 标准 CRUD | 简单功能 | 基础定制 |
|---|---|---|---|
| 继承类 | AdmincpCommon | AdmincpCommon | AdmincpBase |
| 使用 Trait | ✅ AdmincpCommonTrait | ❌ | ❌ |
| 自动 CRUD | ✅ 完整支持 | ⚠️ 需手动实现 | ❌ 需手动实现 |
| 批量操作 | ✅ 自动支持 | ❌ | ❌ |
| 开发效率 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| 灵活性 | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 适用场景 | 数据管理 | 只读查看 | 特殊功能 |
3.2.5 选择建议
-
标准 CRUD 应用 ⭐ 推荐
- 适用于大多数数据管理场景
- 功能全面,开发效率高
- 90% 的后台应用都应该使用此模式
-
简单功能应用
- 适用于只读型数据管理
- 功能精简,适合快速实现
- 如日志查看、文件浏览等
-
基础定制应用
- 适用于特殊功能模块
- 灵活性高,适合复杂业务逻辑
- 如系统配置、工具类应用等
3.2.6 关键方法命名规范
无论使用哪种模式,方法命名都遵循以下规范:
- do_index(): 列表页面
- do_add(): 添加/编辑页面
- do_save(): 保存数据
- do_delete(): 删除操作
- do_batch(): 批量操作
- do_status(): 状态修改
- do_sort(): 排序操作
- *done_()**: AJAX 数据接口(返回 JSON)
3.2.7 响应方式详解
iCMS8 提供了灵活的响应机制,支持多种返回方式。
错误响应:
// 方式1: 使用 self::alert() - 推荐
empty($data['title']) && self::alert('标题不能为空');
// 方式2: 直接返回 false
if (empty($data['title'])) {
return false; // 自动显示错误
}
// 方式3: 返回错误信息数组
return [false, '操作失败', $url];
成功响应:
// 方式1: 返回 true
return true; // 自动显示成功
// 方式2: 返回成功信息数组
return [true, '保存成功'];
return [true, '保存成功', $url]; // 带跳转URL
// 方式3: 返回 null (POST请求时)
return null; // POST请求自动返回成功
// 方式4: 返回数据数组
return [
'code' => 1,
'state' => 'SUCCESS',
'message' => '操作成功',
'url' => APP_URL,
'data' => ['id' => $id]
];
// 方式5: 返回数字
return $id; // 返回ID,大于0表示成功
// 方式6: 返回URL字符串
return 'http://example.com'; // 自动跳转
return '/article/list'; // 相对路径跳转
return 'url:/article/list:2000'; // 延迟2秒跳转
AJAX/API 响应:
// 使用 iJson 类
public function done_get_data()
{
$id = Request::get('id');
$data = ArticleModel::get($id);
if ($data) {
// 成功响应
iJson::success($data, '获取成功');
} else {
// 失败响应
iJson::error('数据不存在', '', 404);
}
}
// 或者直接返回数据
public function done_list()
{
$list = ArticleModel::limit(10)->select();
return $list; // 自动转为 JSON
}
响应参数说明:
// 数组响应格式
[
'code' => 1, // 状态码: 1=成功, 0=失败
'state' => 'SUCCESS', // 状态: SUCCESS/ERROR
'message' => '提示信息', // 提示消息
'url' => '跳转地址', // 跳转URL(可选)
'data' => [] // 返回数据(可选)
]
// iJson 方法
iJson::success($data, $message, $url, $code, $state);
iJson::error($message, $url, $code, $state);
iJson::fail($message, $url, $code, $state);
实际应用示例:
class ArticleAdmincp extends AdmincpCommon
{
use AdmincpCommonTrait;
// 保存前验证
protected function saving(&$data)
{
empty($data['title']) && self::alert('标题不能为空');
empty($data['cid']) && self::alert('请选择栏目');
// 重复检查
if (ArticleModel::check($data['title'], $data['id'])) {
self::alert('该标题已存在');
}
return true; // 验证通过
}
// 删除操作
public function do_delete()
{
$this->id or self::alert('请选择要删除的文章');
ArticleModel::delete($this->id);
return [true, '删除成功', APP_URL];
}
// AJAX获取数据
public function done_get_article()
{
$id = Request::get('id');
$id or iJson::error('参数错误');
$article = ArticleModel::get($id);
$article or iJson::error('文章不存在', '', 404);
iJson::success($article, '获取成功');
}
}
### 3.3 App 前台控制器开发
前台控制器继承 `AppsBase` 并使用 `AppsAppTrait`,提供三种方法类型来处理不同的请求场景。
#### 3.3.1 三种方法类型
**方法命名规范**:
- `do_*()`: 页面渲染方法(有模板输出)
- `api_*()`: API 接口方法(返回 JSON)
- `display()`: 通用展示方法(供路由调用)
---
#### 3.3.2 类型一:页面渲染方法 (do_*)
**适用场景**: 需要渲染 HTML 模板的页面,如详情页、列表页等。
**访问方式**: `api.php/应用名/方法名?参数`
**示例代码**:
```php
<?php
class ArticleApp extends AppsBase
{
use AppsAppTrait;
protected static $DATA = [];
/**
* 详情页
* 访问: api.php/article/detail?id=1
*/
public function do_detail($id = null, $tpl = null)
{
// 获取参数
$id === null && $id = (int)Request::get('id');
// 查询数据
$article = ArticleModel::where([
'id' => $id,
'status' => 1
])->find();
// 数据验证
empty($article) && self::alert(['errors:not_found', [self::$app, 'id', $id]], 10001);
// 处理数据
$vars = ['tag' => true, 'user' => true];
self::values($article, $vars, $tpl);
// 获取正文数据
$articleData = ArticleDataModel::sharding($id)
->where('article_id', $id)
->first();
$article['body'] = $articleData['body'];
// 渲染模板
$tpl === null && $tpl = self::$DATA['node']['template']['article:detail'];
return self::render($article, $tpl);
}
/**
* 列表页
* 访问: api.php/article/list?cid=1&page=1
*/
public function do_list($cid = null, $tpl = null)
{
$cid === null && $cid = (int)Request::get('cid');
$page = (int)Request::get('page', 1);
// 查询列表
$_GET['page'] = $page;
$articles = ArticleModel::where([
'cid' => $cid,
'status' => 1
])->orderBy('id', 'DESC')->paging(20);
// 处理数据
foreach ($articles as &$item) {
self::values($item, ['tag' => false], false);
}
// 渲染模板
$tpl === null && $tpl = 'article_list.htm';
return self::render([
'list' => $articles,
'total' => Paging::$total,
'page' => $page
], $tpl);
}
}
核心方法:
$this->getData($value, $field, $tpl): 获取数据(继承自 AppsAppTrait)self::render($data, $tpl): 渲染模板self::values(&$data, $vars, $tpl): 数据处理
3.3.3 类型二:API 接口方法 (api_*)
适用场景: 提供 JSON 数据接口,用于 AJAX 请求、小程序、APP 等。
访问方式: api.php/应用名/方法名?参数
返回格式: 自动转换为 JSON
示例代码:
class ArticleApp extends AppsBase
{
use AppsAppTrait;
/**
* 获取文章列表(API)
* 访问: api.php/article/get_list?page=1&pageSize=10
*/
public function api_get_list()
{
$page = Request::get('page', 1);
$pageSize = Request::get('pageSize', 10);
$cid = Request::get('cid', 0);
$_GET['page'] = $page;
// 构建查询
$where = ['status' => 1];
$cid && $where['cid'] = $cid;
$obj = ArticleModel::where($where);
$obj->orderBy('id', 'DESC');
$rows = $obj->paging($pageSize);
// 处理数据
foreach ($rows as &$item) {
$item['url'] = Route::get('article', [$item])->href;
$item['pic'] = FilesPic::getArray($item['pic']);
}
// 返回数据(自动转 JSON)
return [
'list' => $rows,
'total' => Paging::$total,
'page' => $page,
'pageSize' => $pageSize
];
}
/**
* 获取文章详情(API)
* 访问: api.php/article/get_detail?id=1
*/
public function api_get_detail()
{
$id = (int)Request::get('id');
$id or iJson::error('参数错误');
$article = ArticleModel::get($id);
$article or iJson::error('文章不存在', '', 404);
// 获取正文
$articleData = ArticleDataModel::sharding($id)
->where('article_id', $id)
->first();
$article['body'] = $articleData['body'];
$article['url'] = Route::get('article', [$article])->href;
return $article;
}
/**
* 提交评论(API)
* 访问: api.php/article/submit_comment
*/
public function api_submit_comment()
{
$data = [
'userid' => User::$id,
'article_id' => Request::post('article_id'),
'content' => Request::post('content'),
'ip' => Request::ip(),
'created' => $_SERVER['REQUEST_TIME'],
];
// 验证
empty($data['content']) && iJson::error('评论内容不能为空');
User::$id or iJson::error('请先登录');
// 保存
CommentModel::create($data);
return [true, '评论成功!'];
}
}
返回方式:
// 方式1: 返回数组(推荐)
return ['key' => 'value'];
// 方式2: 使用 iJson
iJson::success($data, '成功信息');
iJson::error('错误信息', '', 404);
// 方式3: 返回成功/失败
return [true, '操作成功'];
return [false, '操作失败'];
3.3.4 类型三:通用展示方法 (display)
适用场景: 供路由系统或其他代码调用的通用方法。
调用方式:
- 路由自动调用
- 代码调用:
(new ArticleApp())->display($id)
示例代码:
class ArticleApp extends AppsBase
{
use AppsAppTrait;
/**
* 通用展示方法
* 供路由或其他地方调用
*/
public function display($value, $field = 'id', $tpl = true)
{
$vars = ['tag' => true, 'user' => true];
// 获取主表数据
$article = $this->getData($value, $field, $tpl);
if ($article === false) {
return false;
}
// 获取扩展表数据
$articleData = ArticleDataModel::sharding($article['id'])
->field('body, subtitle')
->where('article_id', $article['id'])
->first();
// 处理数据
self::values($article, $articleData, $vars, $tpl);
self::getCustomData($article, $vars);
// 渲染
return self::render($article, $tpl);
}
}
3.3.5 数据处理方法 (values)
作用: 处理数据,添加通用字段(URL、用户信息、图片等)。
示例代码:
/**
* 静态方法:数据处理
* @param array $article 主表数据
* @param array $data 扩展数据
* @param array $vars 变量配置
* @param mixed $tpl 模板
*/
public static function values(&$article, $data = null, $vars = [], $tpl = false)
{
// 初始化
self::initialize($article, $tpl);
// 处理扩展数据
if ($data) {
$article['body'] = $data['body'];
$article['subtitle'] = $data['subtitle'];
}
// 状态文本
$article['statusText'] = ArticleModel::$statusMap[$article['status']];
// 处理标签
$vars['tag'] && TagApp::getArray($article, $article['node']['name'], 'tags');
// 使用 AppsCommon 处理通用数据
AppsCommon::init($article, $vars)
->link() // 生成 URL 和 link
->user() // 处理用户信息
->comment() // 处理评论数
->pic() // 处理图片
->hits() // 处理点击数
->params(); // 处理参数
return $article;
}
AppsCommon 链式方法:
->link(): 生成url和link字段->user(): 添加用户信息(需要$vars['user'] = true)->comment(): 添加评论数->pic(): 处理图片字段->hits(): 处理点击数->params(): 处理自定义参数->text2link(): 文本转链接(可选)
3.3.6 访问路径说明
| 方法类型 | 方法名示例 | 访问路径 | 说明 |
|---|---|---|---|
do_* |
do_detail() |
api.php/article/detail?id=1 |
页面渲染 |
do_* |
do_list() |
api.php/article/list?cid=1 |
列表页 |
api_* |
api_get_list() |
api.php/article/get_list |
JSON接口 |
api_* |
api_submit() |
api.php/article/submit |
提交接口 |
display() |
display($id) |
路由调用或代码调用 | 通用方法 |
3.3.7 重要提示
- ✅ 方法命名:
do_用于页面,api_用于接口 - ✅ 参数处理: 使用
Request::get()/Request::post() - ✅ 数据验证: 空数据使用
self::alert()返回错误 - ✅ 模板渲染: 使用
self::render() - ✅ API返回: 返回数组,系统自动转 JSON
- ✅ 静态方法: 供模板标签或其他地方调用
- ✅ 链式调用: 使用
AppsCommon::init()->link()->user()->... - ✅ HTTPS处理: 注意资源URL的协议转换
3.4 Func 模板标签开发
3.4.1 标准结构
<?php
class ArticleFunc extends AppsFuncCommon implements AppsFuncInterface
{
/**
* 列表标签
* 用法: {iCMS:article:list loop="true" row="10"}
*/
public static function lists($vars)
{
$model = ArticleModel::field('id');
$where = [['status', 1]];
// 条件处理
isset($vars['cid']) && $where[] = ['cid', $vars['cid']];
isset($vars['userid']) && $where[] = ['userid', $vars['userid']];
self::inited($vars, $model, $where);
self::nodes('cid');
self::tags();
self::orderby();
return self::getResource(__METHOD__);
}
/**
* 资源处理
*/
public static function resource($idsArray = null)
{
$resource = ArticleModel::field('*')
->where($idsArray)
->select();
return self::many(self::$vars, $resource);
}
}
四、前端开发规范
4.1 后台视图模板 (views/*.html)
4.1.1 列表页模板 (index.html)
<?php
defined('iPHP') or exit('What are you doing?');
self::head();
?>
<div class="content">
<div class="block">
<div class="block-header">
<h3 class="block-title"><?=Lang('admincp:article:list')?></h3>
<div class="block-options">
<a href="<?=APP_URL?>/add" class="btn btn-primary">
<i class="fa fa-plus"></i> <?=Lang('admincp:btn:add')?>
</a>
</div>
</div>
<div class="block-content">
<table class="table table-striped">
<thead>
<tr>
<th><?=Lang('fields:id')?></th>
<th><?=Lang('fields:title')?></th>
<th><?=Lang('fields:status')?></th>
<th><?=Lang('admincp:action')?></th>
</tr>
</thead>
<tbody>
<?php foreach($resource as $item): ?>
<tr>
<td><?=$item['id']?></td>
<td><?=$item['title']?></td>
<td><?=$item['statusText']?></td>
<td>
<a href="<?=APP_URL?>/add&id=<?=$item['id']?>">
<?=Lang('admincp:btn:edit')?>
</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
4.1.2 添加/编辑页模板 (add.html)
<form action="<?=APP_DOURL?>" method="POST" i="cms:ui:form">
<input name="rs[id]" type="hidden" value="<?=$this->id?>" />
<div class="form-floating mb-3">
<input type="text" name="rs[title]" class="form-control"
value="<?=$rs['title']?>" data-rule="required" />
<label><?=Lang('fields:title')?></label>
</div>
<div class="form-group">
<label><?=Lang('fields:content')?></label>
<textarea name="rs[content]" class="form-control" rows="10">
<?=$rs['content']?>
</textarea>
</div>
<button type="submit" class="btn btn-primary">
<i class="fa fa-check"></i> <?=Lang('admincp:btn:submit')?>
</button>
</form>
4.2 前端模板标签使用
4.2.1 模板系统概述
模板边界符: <!--{...}-->
基本特性:
- 基于 Template Lite 模板引擎
- 兼容 80% 以上 Smarty 语法
- 采用 HTML 注释形式的边界符
- 执行效率高,支持多种高级模板特性
4.2.2 变量输出
基本变量:
<!--{$variable}-->
数组变量:
<!--{$array.key}-->
<!--{$array[0]}-->
<!--{$array.arr.key}-->
复合变量:
<!--{$var1$var2$var3'text'123}-->
4.2.3 条件判断
<!--{if $article.status == 1}-->
<span class="badge bg-success">已发布</span>
<!--{elseif $article.status == 0}-->
<span class="badge bg-warning">待审核</span>
<!--{else}-->
<span class="badge bg-danger">已删除</span>
<!--{/if}-->
4.2.4 循环结构
foreach 循环:
<!--{foreach $articles as $article}-->
<div class="article-item">
<h3><!--{$article.title}--></h3>
<p><!--{$article.description}--></p>
</div>
<!--{/foreach}-->
for 循环:
<!--{for $i=0; $i<10; $i++}-->
<div>第 <!--{$i}--> 项</div>
<!--{/for}-->
4.2.5 应用标签调用
标签格式:
<!--{iCMS:应用名:方法名 参数='值'}-->
单次调用(不循环):
<!--{iCMS:article:data aid='1' cache='1'}-->
<div class="article-content">
<h1><!--{$article_data.title}--></h1>
<div class="content"><!--{$article_data.body}--></div>
</div>
循环调用(loop='true'):
<!--{iCMS:article:list loop='true' row='10' cid='1'}-->
<div class="article-item">
<h3><a href="<!--{$article_list.url}-->"><!--{$article_list.title}--></a></h3>
<p><!--{$article_list.description}--></p>
</div>
<!--{iCMSelse}-->
<p>暂无内容</p>
<!--{/iCMS}-->
自定义变量名(as="别名"):
<!--{iCMS:article:list loop='true' row='10' as='art'}-->
<div class="article-item">
<h3><a href="<!--{$art.url}-->"><!--{$art.title}--></a></h3>
<p><!--{$art.description}--></p>
</div>
<!--{/iCMS}-->
4.2.6 文章标签示例
文章列表:
<!--{iCMS:article:list loop='true' row='10' cid='1' orderby='id' order='desc'}-->
<div class="article-item">
<div class="article-thumb">
<a href="<!--{$article_list.url}-->">
<img src="<!--{$article_list.pic.0.url}-->" alt="<!--{$article_list.title}-->">
</a>
</div>
<div class="article-info">
<h3><a href="<!--{$article_list.url}-->"><!--{$article_list.title}--></a></h3>
<div class="meta">
<span><!--{$article_list.pubdate|date:'Y-m-d H:i:s'}--></span>
<span><!--{$article_list.hits}--> 阅读</span>
</div>
<p><!--{$article_list.description}--></p>
</div>
</div>
<!--{iCMSelse}-->
<p class="text-center">暂无相关内容</p>
<!--{/iCMS}-->
分页:
<!--{iCMS:article:list loop='true' row='10' page='1'}-->
<!-- 列表内容 -->
<!--{/iCMS}-->
<!--{iCMS:pages page_style='3' item='<li class="page-item %s">%s</li>' link='<a class="page-link" href="%s" data-pageno="%d" %s>%s</a>'}-->
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
<!--{$iCMS.PAGE.NAV}-->
</ul>
</nav>
文章详情:
<!--{iCMS:article:data aid='$article.id' cache='1'}-->
<article class="article-detail">
<h1><!--{$article_data.title}--></h1>
<!--{if $article_data.subtitle}-->
<h2 class="subtitle"><!--{$article_data.subtitle}--></h2>
<!--{/if}-->
<div class="article-meta">
<span>作者: <!--{$article.author}--></span>
<span>发布时间: <!--{$article.pubdate|date:'Y-m-d H:i:s'}--></span>
<span>阅读: <!--{$article.hits}--></span>
</div>
<div class="article-body">
<!--{$article_data.body}-->
</div>
</article>
上一篇/下一篇:
<!--{iCMS:article:prev aid='$article.id' cid='$article.cid'}-->
<a href="<!--{$article_prev.url}-->" class="btn btn-prev">
上一篇: <!--{$article_prev.title}-->
</a>
<!--{/iCMS}-->
<!--{iCMS:article:next aid='$article.id' cid='$article.cid'}-->
<a href="<!--{$article_next.url}-->" class="btn btn-next">
下一篇: <!--{$article_next.title}-->
</a>
<!--{/iCMS}-->
4.2.7 栏目标签示例
栏目列表:
<!--{iCMS:article:category loop='true' stype='top' row='10'}-->
<div class="category-item">
<h3><a href="<!--{$article_category.url}-->"><!--{$article_category.name}--></a></h3>
<p><!--{$article_category.description}--></p>
<span>文章数: <!--{$article_category.count}--></span>
</div>
<!--{/iCMS}-->
栏目树形结构:
<!--{iCMS:node:list loop='true' stype='top' appid='article'}-->
<li>
<a href="<!--{$node_list.url}-->"><!--{$node_list.name}--></a>
<!--{if $node_list.child}-->
<ul>
<!--{foreach $node_list.child as $sub}-->
<li><a href="<!--{$sub.url}-->"><!--{$sub.name}--></a></li>
<!--{/foreach}-->
</ul>
<!--{/if}-->
</li>
<!--{/iCMS}-->
4.2.8 标签嵌套使用
栏目+文章嵌套:
<!--{iCMS:article:category stype='top' row='5'}-->
<div class="category-section">
<h2><a href="<!--{$article_category.url}-->"><!--{$article_category.name}--></a></h2>
<!--{iCMS:article:list cid='$article_category.id' row='3' cache='1'}-->
<ul class="article-list">
<li><a href="<!--{$article_list.url}-->"><!--{$article_list.title}--></a></li>
</ul>
<!--{/iCMS}-->
</div>
<!--{/iCMS}-->
变量传递(在文章详情页):
<h1><!--{$article.title}--></h1>
<div class="content"><!--{$article.body}--></div>
<!-- 相关文章 -->
<!--{iCMS:article:list loop='1' cid='$article.cid' id!='$article.id' row='5'}-->
<div class="related">
<h3>相关文章</h3>
<ul>
<li><a href="<!--{$article_list.url}-->"><!--{$article_list.title}--></a></li>
</ul>
</div>
<!--{/iCMS}-->
4.2.9 常用标签参数
article:list 参数:
loop='true': 循环输出row='10': 获取数量cid='1': 栏目IDpage='1': 分页orderby='id': 排序字段order='desc': 排序方式status='1': 状态筛选userid='1': 用户ID筛选tags='标签': 标签筛选cache='1': 缓存时间(秒)as='art': 自定义变量名
article:category 参数:
loop='true': 循环输出stype='top': 顶级栏目stype='sub': 子栏目pid='1': 父栏目IDrow='10': 获取数量
node:list 参数:
loop='true': 循环输出appid='article': 应用IDstype='top': 顶级节点pid='0': 父节点IDrow='10': 获取数量
4.2.10 重要提示
- ✅ 边界符: 必须使用
<!--{...}-->格式 - ✅ 变量输出:
<!--{$variable}--> - ✅ 标签格式:
<!--{iCMS:app:method param='value'}--> - ✅ 循环标签: 必须添加
loop='true'参数 - ✅ 自定义变量: 使用
as='别名'参数 - ✅ 条件判断: 使用
<!--{if}-->...<!--{/if}--> - ✅ 空数据处理: 使用
<!--{iCMSelse}-->显示默认内容 - ✅ 变量传递: 外层标签变量可用
$引用传递给内层
4.3 模板辅助方法
iCMS 提供了丰富的模板方法,包括 调节器、块处理器 和 函数处理器,用于在模板中对数据进行处理和展示。
4.3.1 调节器 (Modifier)
调节器用于对模板变量进行处理,形式为 <!--{$变量|调节器}-->。
常用调节器:
| 调节器 | 说明 | 示例 |
|---|---|---|
date |
格式化日期 | `` |
cut |
截取字符串 | `` |
truncate |
截取字符串(智能) | `` |
upper |
转大写 | `` |
lower |
转小写 | `` |
capitalize |
首字母大写 | `` |
replace |
替换字符串 | `` |
default |
设置默认值 | `` |
escape |
HTML转义 | `` |
json |
JSON编码 | `` |
markdown |
Markdown解析 | `` |
pinyin |
转拼音 | `` |
thumb |
生成缩略图 | `` |
print_r |
调试输出 | `` |
字符串处理:
<!-- 截取字符串 -->
<!--{$article.title|cut:20:'...'}-->
<!-- 转大写 -->
<!--{$str|upper}-->
<!-- 替换内容 -->
<!--{$content|replace:'旧内容':'新内容'}-->
<!-- 设置默认值 -->
<!--{$description|default:'暂无描述'}-->
<!-- HTML转义 -->
<!--{$user_input|escape:'html'}-->
日期处理:
<!-- 格式化日期 -->
<!--{$article.pubdate|date:'Y-m-d H:i:s'}-->
<!--{$article.pubdate|date:'Y年m月d日'}-->
<!--{$article.created|date:'m/d/Y'}-->
数组处理:
<!-- 提取数组列 -->
<!--{$articles|pluck:'title'}-->
<!-- 提取指定字段 -->
<!--{$data|fields:'id,title,url'}-->
<!-- 提取键名 -->
<!--{$array|keys:'key1,key2':true}-->
<!-- JSON编码 -->
<!--{$data|json}-->
图片处理:
<!-- 生成缩略图 -->
<img src="<!--{$article.pic.0.url|thumb:300:200}-->" alt="<!--{$article.title}-->">
<!-- 不同尺寸 -->
<!--{$image|thumb:100:100}--> <!-- 100x100 -->
<!--{$image|thumb:200:150}--> <!-- 200x150 -->
高级用法:
<!-- 链式调用 -->
<!--{$article.title|cut:30:'...'|upper}-->
<!-- 调用对象方法 -->
<!--{$object|call:'method':'arg1':'arg2'}-->
<!-- Markdown解析 -->
<!--{$article.body|markdown}-->
<!-- 拼音转换 -->
<!--{$title|pinyin:'-'}--> <!-- 输出: zhong-wen-biao-ti -->
4.3.2 块处理器 (Block)
块处理器用于处理模板中的块内容,形式为 <!--{block}-->内容<!--{/block}-->。
cache - 缓存块:
<!-- 缓存3600秒 -->
<!--{cache id="sidebar" time="3600"}-->
<div class="sidebar">
<!--{iCMS:article:list row='5'}-->
<li><!--{$article_list.title}--></li>
<!--{/iCMS}-->
</div>
<!--{/cache}-->
capture - 捕获块:
<!-- 捕获内容到变量 -->
<!--{capture name="page_title"}-->
<!--{$article.title}--> - <!--{'site_name'|lang}-->
<!--{/capture}-->
<!-- 使用捕获的内容 -->
<title><!--{$page_title}--></title>
strip - 去除空格:
<!-- 去除多余空格和换行 -->
<!--{strip}-->
<div>
<span>内容</span>
<span>内容</span>
</div>
<!--{/strip}-->
<!-- 输出: <div><span>内容</span><span>内容</span></div> -->
textformat - 文本格式化:
<!-- 格式化为邮件样式 -->
<!--{textformat style="email"}-->
这是一段很长的文本内容,会被自动格式化为适合邮件显示的格式。
<!--{/textformat}-->
4.3.3 函数处理器 (Function)
函数处理器用于在模板中调用函数,形式为 <!--{function 参数}-->。
array - 创建数组:
<!--{array as="colors" red="红色" blue="蓝色" green="绿色"}-->
<!--{foreach $colors as $key => $value}-->
<span><!--{$key}-->: <!--{$value}--></span>
<!--{/foreach}-->
rand - 随机选择:
<!-- 随机选择一个值 -->
<!--{rand values="1,2,3,4,5" as="random"}-->
<div>随机数: <!--{$random}--></div>
counter - 计数器:
<!-- 从1开始,每次增加2 -->
<!--{foreach $articles as $article}-->
<!--{counter start=1 skip=2}--> <!--{$article.title}-->
<!--{/foreach}-->
cycle - 循环值:
<!-- 循环使用不同的CSS类 -->
<!--{foreach $articles as $article}-->
<div class="<!--{cycle values='odd,even'}-->">
<!--{$article.title}-->
</div>
<!--{/foreach}-->
math - 数学运算:
<!-- 计算总价 -->
<!--{math equation="price * quantity" price=$item.price quantity=$item.quantity assign="total"}-->
<span>总价: <!--{$total}--></span>
<!-- 计算百分比 -->
<!--{math equation="(current / total) * 100" current=50 total=200 assign="percent"}-->
<span>进度: <!--{$percent}-->%</span>
in_array - 数组查找:
<!-- 检查值是否在数组中 -->
<!--{in_array array=$tags match="PHP" returnvalue="存在"}-->
4.3.4 实际应用示例
文章列表页:
<!--{iCMS:article:list loop='true' row='10' cid='1'}-->
<article class="<!--{cycle values='odd,even'}-->">
<div class="thumb">
<img src="<!--{$article_list.pic.0.url|thumb:300:200}-->"
alt="<!--{$article_list.title}-->">
</div>
<div class="info">
<h3>
<a href="<!--{$article_list.url}-->">
<!--{$article_list.title|cut:30:'...'}-->
</a>
</h3>
<div class="meta">
<span><!--{$article_list.pubdate|date:'Y-m-d'}--></span>
<span><!--{$article_list.hits}--> 阅读</span>
</div>
<p><!--{$article_list.description|cut:100:'...'|default:'暂无描述'}--></p>
</div>
</article>
<!--{/iCMS}-->
文章详情页:
<!--{capture name="page_title"}-->
<!--{$article.title}--> - <!--{'site_name'|lang}-->
<!--{/capture}-->
<article class="article-detail">
<h1><!--{$article.title}--></h1>
<div class="meta">
<span>作者: <!--{$article.author|default:'匿名'}--></span>
<span>发布: <!--{$article.pubdate|date:'Y-m-d H:i:s'}--></span>
<span>阅读: <!--{$article.hits}--></span>
</div>
<!--{if $article.pic}-->
<div class="featured-image">
<img src="<!--{$article.pic.0.url|thumb:800:450}-->"
alt="<!--{$article.title}-->">
</div>
<!--{/if}-->
<div class="content">
<!--{$article.body|markdown}-->
</div>
<!--{if $article.tags}-->
<div class="tags">
<!--{foreach $article.tags as $tag}-->
<a href="<!--{$tag.url}-->" class="tag">
<!--{$tag.name}-->
</a>
<!--{/foreach}-->
</div>
<!--{/if}-->
</article>
侧边栏缓存:
<!--{cache id="sidebar_hot" time="3600"}-->
<div class="widget">
<h3>热门文章</h3>
<ul>
<!--{iCMS:article:list loop='true' row='5' orderby='hits' order='desc'}-->
<li>
<a href="<!--{$article_list.url}-->">
<!--{$article_list.title|cut:20:'...'}-->
</a>
<span class="hits"><!--{$article_list.hits}--></span>
</li>
<!--{/iCMS}-->
</ul>
</div>
<!--{/cache}-->
评论列表:
<!--{foreach $comments as $comment}-->
<div class="comment <!--{cycle values='odd,even'}-->">
<div class="author">
<img src="<!--{$comment.avatar|thumb:50:50}-->"
alt="<!--{$comment.username}-->">
<span><!--{$comment.username}--></span>
</div>
<div class="content">
<!--{$comment.content|escape:'html'|nl2br}-->
</div>
<div class="time">
<!--{$comment.created|date:'Y-m-d H:i:s'}-->
</div>
</div>
<!--{/foreach}-->
4.3.5 调试技巧
输出变量内容:
<!-- 调试数组结构 -->
<!--{$article|print_r}-->
<!-- 调试变量 -->
<!--{$article|print_var}-->
<!-- JSON格式输出 -->
<!--{$data|json}-->
条件调试:
<!--{if $iCMS.debug}-->
<div class="debug-info">
<h3>调试信息</h3>
<pre><!--{$article|print_r}--></pre>
</div>
<!--{/if}-->
4.3.6 注意事项
- ✅ 转义字符: 调节器参数中的
|需要用\|转义 - ✅ 链式调用: 可以连续使用多个调节器
- ✅ 性能考虑: 缓存块可以显著提升性能
- ✅ 安全处理: 用户输入必须使用
escape转义 - ✅ 默认值: 使用
default避免空值显示 - ✅ 调试模式: 使用
print_r和print_var调试变量 - ✅ 图片优化: 使用
thumb生成合适尺寸的缩略图
五、国际化(i18n)开发规范
5.1 语言包文件位置
5.1.1 全局语言包
中文语言包: config/lang/zh.json
{
"site_name": "iCMS 演示站点",
"site_description": "一个高效简洁的内容管理系统",
"copyright": "版权所有"
}
英文语言包: config/lang/en.json
{
"site_name": "iCMS Demo Site",
"site_description": "An efficient and concise content management system",
"copyright": "Copyright"
}
5.1.2 后台专用语言包
路径: app/admincp/etc/lang/zh.admincp.json
结构示例:
{
"admincp": {
"title": "iCMS内容管理系统",
"slogan": "一切尽在您的掌控之中。",
"login": {
"welcome": "欢迎使用iCMS管理系统",
"description": "为您提供一套高效、简洁、免费的开源解决方案"
},
"node": {
"route": {
"rule_tip": "伪静态模式时规则必需有",
"index": {
"label": "首页",
"info": "[NODE@NAME]的首页模板"
}
}
},
"dropdown": {
"inbox": "收件箱",
"profile": "个人信息",
"settings": "设置",
"logout": "退出"
}
}
}
5.1.3 应用专用语言包
路径: app/[应用名]/etc/lang/zh.admincp.json
示例 (app/article/etc/lang/zh.admincp.json):
{
"admincp": {
"article": {
"list": "文章列表",
"add": "添加文章",
"edit": "编辑文章",
"delete": "删除文章"
},
"btn": {
"add": "添加",
"edit": "编辑",
"delete": "删除",
"submit": "提交",
"cancel": "取消"
},
"msg": {
"save_success": "保存成功",
"delete_success": "删除成功"
}
},
"fields": {
"id": "ID",
"title": "标题",
"content": "内容",
"status": "状态",
"created": "创建时间"
}
}
5.1.4 模板语言包
路径: template/[模板目录]/lang/
方式一:集中存放 (ALL.json):
{
"zh": {
"site_name": "iCMS 演示站点",
"option": "其它",
"read_more": "阅读更多"
},
"en": {
"site_name": "iCMS Demo Site",
"option": "Other",
"read_more": "Read More"
},
"ja": {
"site_name": "iCMSデモサイト",
"option": "その他",
"read_more": "続きを読む"
}
}
方式二:单独存放 (en.json, zh.json):
// template/blog/lang/en.json
{
"site_name": "iCMS Demo Site",
"option": "Other",
"read_more": "Read More"
}
加载优先级:
- 单独语言包优先(如
en.json) - 集中语言包备用(
ALL.json)
5.2 使用规范
5.2.1 命名空间规则
后台语言包:
admincp:模块:功能(最多三层)- 示例:
admincp:article:list,admincp:btn:submit
字段标签:
fields:字段名(两层结构)- 示例:
fields:title,fields:status
前台标签:
usercp:模块:功能(最多三层)- 示例:
usercp:profile:edit
5.2.2 PHP 代码中使用
// 方式1: 使用 Lang 函数
Lang('admincp:article:list');
Lang('fields:title');
// 方式2: 使用 Lang::get 方法
Lang::get('admincp:btn:submit');
// 方式3: 带默认值
Lang('admincp:custom:key', '默认值');
// 方式4: 带参数替换
Lang('admincp:msg:welcome', ['name' => $username]);
5.2.3 后台 HTML 模板中使用
<!-- 方式1: PHP 短标签 -->
<?=Lang('admincp:article:list')?>
<!-- 方式2: 完整写法 -->
<?php echo Lang('fields:title'); ?>
<!-- 方式3: 在属性中使用 -->
<input type="text" placeholder="<?=Lang('fields:title')?>" />
<!-- 方式4: 在按钮中使用 -->
<button class="btn btn-primary">
<i class="fa fa-plus"></i> <?=Lang('admincp:btn:add')?>
</button>
5.2.4 前台模板中使用
基本用法:
<!-- 输出语言包内容 -->
<h1><!--{'site_name'|lang}--></h1>
<p><!--{'site_description'|lang}--></p>
<!-- 在链接中使用 -->
<a href="/about"><!--{'about_us'|lang}--></a>
<!-- 在按钮中使用 -->
<button><!--{'read_more'|lang}--></button>
不需要翻译的内容:
<!-- 使用 keep 过滤器保持原样 -->
<div><!--{'© 2024 iCMS'|keep}--></div>
<span><!--{'Version 8.0'|keep}--></span>
完整示例:
<!DOCTYPE html>
<html lang="<!--{$iCMS.language}-->">
<head>
<title><!--{'site_name'|lang}--></title>
<meta name="description" content="<!--{'site_description'|lang}-->">
</head>
<body>
<header>
<h1><!--{'site_name'|lang}--></h1>
<nav>
<a href="/"><!--{'home'|lang}--></a>
<a href="/about"><!--{'about'|lang}--></a>
<a href="/contact"><!--{'contact'|lang}--></a>
</nav>
</header>
<main>
<!--{iCMS:article:list loop='true' row='10'}-->
<article>
<h2><!--{$article_list.title}--></h2>
<p><!--{$article_list.description}--></p>
<a href="<!--{$article_list.url}-->">
<!--{'read_more'|lang}-->
</a>
</article>
<!--{/iCMS}-->
</main>
<footer>
<p><!--{'copyright'|lang}--> <!--{'© 2024'|keep}--></p>
</footer>
</body>
</html>
5.2.5 JavaScript 中使用
// 在 JS 中调用语言包
var message = Lang('admincp:msg:save_success');
alert(message);
// 在 AJAX 回调中使用
$.post(url, data, function(response) {
if (response.code === 1) {
alert(Lang('admincp:msg:save_success'));
} else {
alert(Lang('admincp:msg:save_failed'));
}
});
5.3 开发最佳实践
5.3.1 语言包组织原则
- 分层清晰: 按模块、功能分层组织
- 命名规范: 使用小写字母和下划线
- 避免重复: 相同含义的文本使用同一个键
- 保持一致: 同类功能使用相同的命名模式
示例:
{
"admincp": {
"article": {
"list": "文章列表",
"add": "添加文章",
"edit": "编辑文章"
},
"category": {
"list": "分类列表",
"add": "添加分类",
"edit": "编辑分类"
}
}
}
5.3.2 多语言切换支持
模板中添加语言切换:
<div class="language-switcher">
<a href="?lang=zh" class="<!--{if $iCMS.language=='zh'}-->active<!--{/if}-->">中文</a>
<a href="?lang=en" class="<!--{if $iCMS.language=='en'}-->active<!--{/if}-->">English</a>
<a href="?lang=ja" class="<!--{if $iCMS.language=='ja'}-->active<!--{/if}-->">日本語</a>
</div>
5.3.3 注意事项
- ✅ 键名一致性: 确保语言包中的键名与代码中使用的完全一致
- ✅ 默认语言: 缺失翻译时会回退到默认语言(通常为
zh) - ✅ 避免硬编码: 所有用户可见的文本都应使用语言包
- ✅ 特殊字符: 语言包中的特殊字符需要正确转义
- ✅ 缓存清理: 修改语言包后需清理缓存才能生效
- ✅ 模板过滤器: 前台模板使用
|lang过滤器,后台使用Lang()函数 - ✅ 保持原样: 不需要翻译的内容使用
|keep过滤器
六、数据库操作规范
6.1 查询构建器
// 基础查询
$article = ArticleModel::get($id);
// 条件查询
$list = ArticleModel::field('id,title')
->where('status', 1)
->where('cid', 10)
->orderBy('id', 'DESC')
->limit(10)
->select();
// 复杂条件
$where = [
['status', 1],
['cid', '>', 0],
['pubdate', '>=', time()],
];
$list = ArticleModel::where($where)->select();
// 插入
$id = ArticleModel::insert([
'title' => '标题',
'content' => '内容',
]);
// 更新
ArticleModel::update($id, [
'title' => '新标题',
]);
// 删除
ArticleModel::delete($id);
6.2 分表操作
// 获取分表模型
$dataModel = ArticleDataModel::sharding($article_id);
// 查询
$data = $dataModel->where('article_id', $article_id)->get();
// 插入
$dataModel->insert([
'article_id' => $article_id,
'body' => $content,
]);
七、事件系统
7.1 模型事件
class ArticleModel extends Model
{
protected $events = [
'geted' => ['ArticleEvent', 'geted'], // 查询后
'created' => ['ArticleEvent', 'created'], // 创建后
'updated' => ['ArticleEvent', 'updated'], // 更新后
'delete' => ['ArticleEvent', 'delete'], // 删除前
'deleted' => ['ArticleEvent', 'deleted'], // 删除后
'changed' => ['ArticleEvent', 'changed'], // 创建+更新
];
}
7.2 事件处理器
class ArticleEvent
{
public static function created($response, $Builder, $event, $isMulti)
{
// 创建后处理
$id = $response['id'];
// 更新缓存、发送通知等
}
public static function delete($response, $Builder, $event, $isMulti)
{
// 删除前处理
$id = $response['id'];
// 清理关联数据
}
}
八、路由配置
8.1 路由定义 (etc/route/route.json)
路由配置使用 JSON 格式,定义 URL 路径与应用控制器的映射关系。
8.1.1 基础路由格式
{
"路径": "参数字符串"
}
8.1.2 静态路由示例
{
"user": "app=user",
"user/home": "app=user&do=home",
"user/login": "app=user&do=login",
"user/register": "app=user&do=register",
"user/logout": "app=user&do=logout"
}
说明:
- 键: URL路径 (如
user/login) - 值: 查询参数格式 (如
app=user&do=login) app: 应用名称do: 控制器方法名s: 子方法/子页面参数
8.1.3 动态路由 (带参数)
{
"{userid}": "app=user&do=home&userid={userid}",
"{userid}/home": "app=user&do=home&userid={userid}",
"{userid}/comment": "app=user&do=comment&userid={userid}",
"{userid}/favorite/{id}": "app=user&do=favorite&userid={userid}&id={id}"
}
参数说明:
{userid}: 动态参数占位符{id}: 其他动态参数- 参数会自动传递到控制器方法
8.1.4 多级路由
{
"user/manage": "app=user&do=manage",
"user/manage/profile": "app=user&do=manage&s=profile",
"user/manage/message": "app=user&do=manage&s=message",
"user/manage/order": "app=user&do=manage&s=order"
}
8.1.5 第三方登录路由
{
"user/login/qq": "app=user&do=login&sign=qq",
"user/login/weibo": "app=user&do=login&sign=weibo",
"user/login/weixin": "app=user&do=login&sign=weixin",
"user/login/github": "app=user&do=login&sign=github"
}
8.1.6 应用别名路由
{
"UserProfile": "app=UserProfile",
"UserPassport": "app=UserPassport",
"UserNode/manage": "app=UserNode&do=manage"
}
8.2 节点路由配置 (node.json)
用于配置内容节点的URL规则和模板。
{
"article": {
"label": "文章",
"template": "{iTPL}/article.htm",
"rule": "/{CDIR}/{YYYY}/{MM}{DD}/{ID}{EXT}",
"tips": "{ID},{0xID},{LINK},{HASH@ID},{HASH@0xID}"
}
}
变量说明:
{iTPL}: 模板目录{CDIR}: 分类目录{YYYY}: 年份{MM}: 月份{DD}: 日期{ID}: 文章ID{0xID}: 16进制ID{EXT}: 扩展名
8.3 路由使用示例
8.3.1 在控制器中获取路由参数
class UserApp extends AppsBase
{
public function do_home()
{
// 获取路由参数
$userid = Request::get('userid');
$cid = Request::get('cid');
// 业务逻辑
$user = UserModel::get($userid);
// ...
}
}
8.3.2 生成路由URL
// 使用 Route 类生成URL
$url = Route::get('user', ['userid' => 123]);
// 输出: /123
$url = Route::get('user', ['userid' => 123, 'do' => 'comment']);
// 输出: /123/comment
九、开发最佳实践
9.1 代码规范
- 文件编码: UTF-8 without BOM
- 缩进: 4个空格
- 命名: 驼峰命名法 (类名首字母大写)
- 安全检查: 每个文件开头必须有
defined('iPHP') or exit('What are you doing?');
9.2 性能优化
- 使用缓存: 列表数据、详情数据启用缓存
- 分表策略: 大数据量表使用分表
- 字段选择: 只查询需要的字段
- 索引优化: 为常用查询字段添加索引
9.3 安全规范
- 输入验证: 所有用户输入必须验证
- SQL注入: 使用参数化查询
- XSS防护: 输出时进行HTML转义
- 权限检查: 后台操作检查管理员权限
9.4 调试技巧
// 开启调试模式
define('iPHP_DEBUG', true);
// 打印SQL
DB::$debug = true;
// 变量调试
var_dump($data);
print_r($array);
十、快速开发模板
10.1 创建新应用步骤
- 创建应用目录:
app/myapp/ - 创建必需文件:
- MyappModel.php
- MyappAdmincp.php
- MyappApp.php
- MyappFunc.php
- 创建视图:
views/index.html,views/add.html - 配置语言包:
etc/lang/zh-cn.json - 配置菜单:
etc/menu/admincp.php - 配置路由:
etc/route/route.php
10.2 完整示例代码
参考 app/article/ 目录下的完整实现。
十一、常用API参考
11.1 核心类库
| 类名 | 说明 | 常用方法 |
|---|---|---|
| Model | 数据模型基类 | get(), insert(), update(), delete() |
| Request | 请求处理 | get(), post(), sget() |
| Response | 响应处理 | success(), error(), json() |
| Lang | 语言处理 | get(), set() |
| Cache | 缓存处理 | get(), set(), delete() |
| Files | 文件处理 | upload(), delete() |
| Route | 路由处理 | get(), url() |
11.2 辅助函数
// 时间处理
time() // 当前时间戳
str2time($str) // 字符串转时间戳
get_date($time) // 格式化时间
// 字符串处理
addslashes($str) // 转义
stripslashes($str) // 反转义
htmlspecialchars($str) // HTML转义
// 数组处理
array_column($arr, 'key') // 提取列
array_unique($arr) // 去重
十二、总结
iCMS8 是一个功能完善的PHP CMS框架,遵循以上规范可以快速开发出高质量的应用模块。
核心要点:
- 严格遵循MVC架构
- 使用国际化语言包
- 利用事件系统解耦
- 合理使用缓存提升性能
- 注重代码安全性
学习路径:
- 理解iPHP框架核心
- 研究article应用示例
- 实践开发简单应用
- 深入学习高级特性