# 框架版本及依赖

## 核心框架

- **项目名称**：`thinkcmf/thinkcmf`
- **项目类型**：Content Management Framework (CMF)
- **基于框架**：ThinkPHP 8.x
- **开源协议**：MIT License
- **官方网站**：http://www.thinkcmf.com/

## PHP 版本要求

- **最低版本**：PHP >= 8.1.0
- **推荐版本**：PHP 8.2+

## 必须的 PHP 扩展

- `ext-json` - JSON 支持
- `ext-curl` - cURL 支持
- `ext-pdo` - PDO 数据库抽象层
- `ext-mbstring` - 多字节字符串支持
- `ext-zip` - ZIP 压缩支持

## 核心依赖包

### ThinkCMF 核心组件

- `thinkcmf/cmf-app` - ThinkCMF 应用模块 (8.0.x-dev)
- `thinkcmf/cmf-install` - ThinkCMF 安装程序 (^8.0)
- `thinkcmf/cmf-api` - ThinkCMF API 模块 (8.0.x-dev)
- `thinkcmf/cmf-appstore` - ThinkCMF 应用商店 (^2.0)
- `thinkcmf/cmf-root` - ThinkCMF 根组件 (^2.0)

### 开发依赖

- `topthink/think-trace` - ThinkPHP 调试工具 (^1.0)

## Composer 配置

### 自动加载配置

```json
"autoload": {
    "psr-4": {
        "app\\": "app",
        "api\\": "api",
        "plugins\\": "public/plugins",
        "themes\\": "public/themes"
    },
    "psr-0": {
        "": "extend/"
    }
}
```

### 脚本命令

在 Composer 自动加载后自动执行：

```bash
php think service:discover    # 服务发现
php think vendor:publish      # 发布资源
php think migrate:run         # 执行数据库迁移
```

## 常用 Composer 命令

```bash
# 安装依赖
composer install

# 更新依赖
composer update

# 添加新依赖
composer require vendor/package

# 移除依赖
composer remove vendor/package

# 优化自动加载
composer dump-autoload
```

## 常用 Think 命令

```bash
# 查看所有可用命令
php think

# 服务管理
php think service:discover    # 发现服务

# 数据库迁移
php think migrate:create CreateUsersTable  # 创建迁移文件
php think migrate:run                      # 执行迁移
php think migrate:rollback                 # 回滚迁移

# 资源发布
php think vendor:publish      # 发布资源文件

# CLI 工具
php think cli                 # 轻量级 CLI 工具
```

## 稳定性要求

- **minimum-stability**: dev
- **prefer-stable**: true

这意味着项目优先使用稳定版本，但允许使用开发版本的依赖包。

## 注意事项

1. **PHP 版本**：必须使用 PHP 8.1 或更高版本
2. **扩展检查**：安装前确保所有必需的 PHP 扩展已启用
3. **Composer 版本**：推荐使用 Composer 2.x 版本
4. **依赖更新**：定期执行 `composer update` 更新依赖包
5. **生产环境**：生产环境不需要安装 `require-dev` 中的开发依赖，使用 `composer install --no-dev`

# ThinkCMF 项目目录结构

## 根目录结构

```
thinkcmf 根目录
├─api                     API 目录
│  ├─demo                 演示应用 API 目录 [可删除]
│  │  ├─controller        控制器目录
│  │  ├─model             模型目录
│  │  └─ ...              更多类库目录
│  └─ ...                 更多 API 应用
├─app                     应用目录
│  ├─demo                 演示应用目录 [可删除]
│  │  ├─controller        控制器目录
│  │  ├─model             模型目录
│  │  └─ ...              更多类库目录
│  ├─ ...                 更多应用
│  ├─common.php           应用公共(函数)文件 [可选]
│  ├─event.php            事件定义文件 [可选]
│  ├─middleware.php       全局中间件定义文件 [可选]
│  ├─provider.php         容器 Provider 定义文件 [可选]
│  └─service.php          系统服务定义文件 [可选]
├─data                    数据目录（可写）
│  ├─config               动态配置目录（可写）
│  ├─route                动态路由目录（可写）
│  ├─runtime              应用运行时目录（可写）
│  ├─upload               私有文件上传目录（可写）
│  └─ ...                 更多
├─config                  配置目录 [可选]
├─public                  WEB 部署目录（对外访问目录）
│  ├─plugins              插件目录
│  │  ├─swagger           Swagger API 文档插件，支持 PHP 8.1 及以上
│  │  ├─system_info       系统信息插件
│  │  └─demo              演示插件 [应用中心下载安装]
│  ├─static               官方静态资源目录 (css/js/image)，勿放自己项目文件
│  ├─themes               前后台主题目录
│  │  ├─admin_default     后台默认主题
│  │  └─default           前台默认主题
│  ├─upload               文件上传目录
│  ├─api.php              API 入口文件
│  ├─index.php            应用入口文件
│  ├─robots.txt           爬虫协议文件
│  ├─router.php           快速测试文件
│  └─.htaccess            Apache 重写文件
├─extend                  扩展类库目录 [可选]
├─vendor                  第三方类库目录（Composer）
│  ├─topthink             ThinkPHP 目录及相关扩展包
│  ├─thinkcmf             ThinkCMF 相关扩展包
│  └─ ...                 更多第三方包
├─composer.json           Composer 定义文件
├─LICENSE                 授权说明文件
├─README.md               README 文件
└─think                   命令行入口文件
```

## 目录说明

### API 目录 (`api/`)

- 存放 API 应用相关代码
- 每个 API 应用独立目录，包含 controller、model 等标准结构
- 演示应用 `demo` 可删除

### 应用目录 (`app/`)

- 存放前台应用相关代码
- 支持多应用架构，每个应用独立目录
- 可选全局文件：`common.php`（公共函数）、`event.php`（事件）、`middleware.php`（中间件）、`provider.php`（容器）、`service.php`（服务）

### 数据目录 (`data/`)

- **注意**：此目录及子目录必须可写
- `config/`：动态生成的配置文件
- `route/`：动态生成的路由文件
- `runtime/`：应用运行时缓存、日志等
- `upload/`：私有文件上传存储

### 公共访问目录 (`public/`)

- **Web 服务器根目录**，唯一对外可访问目录
- `plugins/`：插件目录，插件相关资源存放位置
- `static/`：**官方静态资源专用**，不要放置项目自定义文件
- `themes/`：主题模板目录，包含前后台主题
- `upload/`：公开文件上传目录
- `index.php`：应用入口
- `api.php`：API 入口

### 扩展目录 (`extend/`)

- 存放项目自定义扩展类库
- 可选目录

### 第三方库目录 (`vendor/`)

- Composer 管理的第三方依赖包
- `topthink/`：ThinkPHP 框架及扩展
- `thinkcmf/`：ThinkCMF 核心扩展包

### 配置目录 (`config/`)

- 存放静态配置文件
- 可选目录，优先级高于 `data/config/`

### 命令行工具 (`think`)

- ThinkPHP 命令行入口
- 用于执行各种命令行任务，如：`php think migrate:create`

## 目录权限要求

必须设置为可写的目录：

- `data/` 及其所有子目录
- `public/upload/`

## 注意事项

1. **静态资源存放**：项目自定义静态资源不要放在 `public/static/` 目录，该目录仅供官方使用
2. **演示代码清理**：生产环境部署前，建议删除 `api/demo/`、`app/demo/`、`public/plugins/demo/` 等演示代码
3. **上传目录**：区分公开上传 (`public/upload/`) 和私有上传 (`data/upload/`)
4. **入口文件**：应用入口 `index.php` 和 API 入口 `api.php` 分别处理不同类型的请求

# 应用开发规范

## 应用概念

应用是 `app/` 目录下的一个模块，具有以下特点：

- 独立于其他应用存在，拥有自己独立的运行空间
- 采用 MVC 架构设计
- 视图 (View) 层独立于应用之外，存放在主题目录中

## 应用目录结构

以 `blog` 应用为例：

```
app/
└─blog                     应用目录
   ├─config.php            应用配置文件
   ├─controller            控制器目录
   ├─lang                  语言包目录
   ├─model                 模型目录
   ├─validate              验证器目录
   └─ ...                  更多类库目录
```

## 视图目录规范

ThinkCMF 中应用的视图 (View) 独立于应用之外，分为前台视图和后台视图：

### 前台视图

- 存放路径：`public/themes/{前台主题}/{应用名}/`
- 示例：`public/themes/default/blog/`

### 后台视图

- 存放路径：`public/themes/{后台主题}/{应用名}/`
- 后台主题带 `admin` 前缀
- 示例：`public/themes/admin_default/blog/`

## 创建应用步骤

### 1. 创建应用目录结构

在 `app/` 目录下创建应用目录，按照上述目录结构组织代码。

### 2. 创建控制器

在应用的 `controller/` 目录下创建控制器文件。

**示例**：创建 `blog` 应用的首页控制器 `IndexController.php`

```php
<?php
namespace app\blog\controller;

use cmf\controller\HomeBaseController;

class IndexController extends HomeBaseController
{
    /**
     * 首页
     */
    public function index()
    {
        return "this is blog index !";
    }
}
```

### 3. 访问应用

访问 URL 格式：`http://你的域名/{应用名}/{控制器名}/{方法名}`

**示例**：`http://你的域名/blog/index/index`

## 命名空间规范

应用命名空间遵循 PSR-4 规范：

- 应用控制器：`namespace app\{应用名}\controller;`
- 应用模型：`namespace app\{应用名}\model;`
- 应用验证器：`namespace app\{应用名}\validate;`
- 应用服务：`namespace app\{应用名}\service;`

**示例**：

```php
namespace app\blog\controller;  // 控制器
namespace app\blog\model;       // 模型
namespace app\blog\validate;    // 验证器
namespace app\blog\service;     // 服务
```

## 注意事项

1. **应用名命名**：应用目录名使用小写+下划线
2. **视图分离**：视图文件不放在应用目录下，而是放在 `public/themes/` 目录中
3. **URL 访问**：URL 路径遵循 `/{应用名}/{控制器名}/{方法名}` 格式
4. **多应用隔离**：每个应用拥有独立的运行空间，避免相互干扰

## 控制器基类

ThinkCMF 提供了多个控制器基类，位于 `cmf\controller` 命名空间下，用于不同的应用场景。

### 基类列表

- `BaseController` - CMF 控制器基类
- `HomeBaseController` - 前台控制器基类
- `UserBaseController` - 前台用户控制器基类
- `AdminBaseController` - 后台控制器基类
- `PluginBaseController` - 插件控制器基类
- `PluginAdminBaseController` - 插件后台控制器基类
- `RestBaseController` - RESTful 控制器基类
- `RestUserBaseController` - 用户 REST 控制器基类
- `RestAdminBaseController` - 后台 REST 控制器基类

### 继承关系

```
think\Controller                              ThinkPHP 控制器基类
│  ├─BaseController                           CMF 控制器基类
│  │  ├─AdminBaseController                   后台控制器基类
│  │  ├─HomeBaseController                    前台控制器基类
│  │  │  └─UserBaseController                 前台用户控制器基类
│  │  ├─PluginBaseController                  插件控制器基类
│  │  │  └─PluginAdminBaseController          插件后台控制器基类
│  ├─RestBaseController                       RESTful 控制器基类
│  │  ├─RestUserBaseController                用户 REST 控制器基类
│  │  ├─RestAdminBaseController               后台 REST 控制器基类
```

### 基类功能说明

#### AdminBaseController - 后台控制器基类

- **用途**：管理后台控制器必须继承此类
- **模板路径**：自动指向后台主题目录 `public/themes/admin_default/`
- **功能特性**：
    - 自动处理后台权限验证
    - 调用 `fetch()` 方法时自动查找后台模板
    - 提供后台常用功能和方法

**使用示例**：

```php
namespace app\admin\controller;

use cmf\controller\AdminBaseController;

class UserController extends AdminBaseController
{
    /**
     * 用户列表
     */
    public function index()
    {
        // 自动从 public/themes/admin_default/admin/user/ 下查找模板
        return $this->fetch();
    }
}
```

#### HomeBaseController - 前台控制器基类

- **用途**：前台控制器继承此类
- **模板路径**：自动指向前台主题目录 `public/themes/default/`
- **功能特性**：
    - 调用 `fetch()` 方法时自动查找前台模板
    - 实现前后台模板分离
    - 提供前台常用功能

**使用示例**：

```php
namespace app\blog\controller;

use cmf\controller\HomeBaseController;

class IndexController extends HomeBaseController
{
    /**
     * 首页
     */
    public function index()
    {
        // 自动从 public/themes/default/blog/ 下查找模板
        return $this->fetch();
    }
}
```

#### UserBaseController - 前台用户控制器基类

- **用途**：需要用户登录才能访问的前台功能
- **继承自**：`HomeBaseController`
- **功能特性**：
    - 自动判断用户是否已登录
    - 验证用户是否有权限访问该 URL
    - 未登录自动跳转到登录页面
    - 提供用户相关操作的基础方法

**使用示例**：

```php
namespace app\user\controller;

use cmf\controller\UserBaseController;

class ProfileController extends UserBaseController
{
    /**
     * 个人资料
     */
    public function index()
    {
        // 此方法自动验证用户登录状态和权限
        return $this->fetch();
    }
}
```

#### PluginBaseController - 插件控制器基类

- **用途**：插件前台控制器继承此类
- **功能特性**：
    - 提供插件相关的基础功能
    - 自动处理插件路径和资源

#### PluginAdminBaseController - 插件后台控制器基类

- **用途**：插件后台控制器继承此类
- **继承自**：`PluginBaseController`
- **功能特性**：
    - 提供插件后台管理功能
    - 自动处理后台权限验证

#### RestBaseController - RESTful 控制器基类

- **用途**：RESTful API 控制器继承此类
- **功能特性**：
    - 支持 RESTful 风格的 API 开发
    - 自动处理 HTTP 方法（GET、POST、PUT、DELETE）
    - 提供统一的响应格式

#### RestUserBaseController - 用户 REST 控制器基类

- **用途**：需要用户认证的 RESTful API
- **继承自**：`RestBaseController`
- **功能特性**：
    - 提供用户认证机制
    - 验证用户 Token

#### RestAdminBaseController - 后台 REST 控制器基类

- **用途**：后台管理 RESTful API
- **继承自**：`RestBaseController`
- **功能特性**：
    - 提供后台权限验证
    - 管理员 Token 认证

### 基类选择指南

| 场景 | 推荐基类 | 说明 |
|------|---------|------|
| 前台页面 | `HomeBaseController` | 普通前台功能 |
| 前台用户中心 | `UserBaseController` | 需要登录验证 |
| 后台管理 | `AdminBaseController` | 后台管理功能 |
| 插件前台 | `PluginBaseController` | 插件前台功能 |
| 插件后台 | `PluginAdminBaseController` | 插件后台管理 |
| RESTful API | `RestBaseController` | 开放 API |
| 用户 API | `RestUserBaseController` | 需要用户认证的 API |
| 后台 API | `RestAdminBaseController` | 需要管理员认证的 API |

### 注意事项

1. **模板自动定位**：继承 `AdminBaseController` 或 `HomeBaseController` 后，`fetch()` 方法会自动定位到对应的主题目录
2. **权限验证**：继承 `UserBaseController`、`AdminBaseController` 等基类时，会自动进行相应的权限验证
3. **命名空间**：所有基类都位于 `cmf\controller` 命名空间下
4. **不要直接继承 ThinkPHP 基类**：应该继承 CMF 提供的基类，以便使用 CMF 的扩展功能

# 插件开发规范

## 插件目录

插件目录位于：`public/plugins/`

## 插件命名规范

### 插件类名命名

- 采用大驼峰命名法（PascalCase）
- 带 `Plugin` 类名后缀
- 示例：`DemoPlugin`、`CustomAdminLoginPlugin`

### 插件目录命名

- 将插件类名转化为小写+下划线形式
- 示例：`demo`、`custom_admin_login`

### 插件主文件命名

- 位置：插件根目录
- 格式：`{插件类名}.php`
- 示例：`DemoPlugin.php`、`CustomAdminLoginPlugin.php`

## 插件目录结构

```
public/plugins/demo/          插件根目录
├─controller/               控制器目录 [可选]
├─view/                     视图模板目录 [可选]
├─config.php                插件配置文件 [可选]
└─DemoPlugin.php            插件主类文件 [必须]
```

## 插件主类文件

插件主类必须继承 `cmf\lib\Plugin` 基类。

**示例**：创建 `DemoPlugin.php`

```php
<?php
namespace plugins\demo;

use cmf\lib\Plugin;

class DemoPlugin extends Plugin
{
    /**
     * 插件信息
     */
    public $info = [
        'name'        => 'Demo',        // 插件英文名
        'title'       => '插件演示',      // 插件中文名
        'description' => '插件演示',      // 插件描述
        'status'      => 1,             // 状态：1-启用，0-禁用
        'author'      => 'ThinkCMF',    // 作者
        'version'     => '1.0'          // 版本号
    ];

    /**
     * 插件是否有后台管理界面
     */
    public $hasAdmin = 1;

    /**
     * 插件安装
     * @return bool 安装成功返回 true，失败返回 false
     */
    public function install()
    {
        // 执行安装逻辑，如创建数据表、初始化数据等
        return true;
    }

    /**
     * 插件卸载
     * @return bool 卸载成功返回 true，失败返回 false
     */
    public function uninstall()
    {
        // 执行卸载逻辑，如删除数据表、清理数据等
        // 注意：不要 try catch 数据库异常，直接抛出，上层会处理异常后回滚
        return true;
    }

    /**
     * 实现的钩子方法
     * @param array $param 钩子参数
     */
    public function footerStart($param)
    {
        $config = $this->getConfig();
        $this->assign($config);
        echo $this->fetch('widget');
    }
}
```

### 主类属性说明

| 属性 | 类型 | 必须 | 说明 |
|------|------|------|------|
| `$info` | array | 是 | 插件信息数组 |
| `$hasAdmin` | int | 否 | 是否有后台管理界面，1-有，0-无 |

### 主类方法说明

| 方法 | 说明 | 返回值 |
|------|------|----------|
| `install()` | 插件安装时调用 | `true` 成功，`false` 失败 |
| `uninstall()` | 插件卸载时调用 | `true` 成功，`false` 失败 |
| 钩子方法 | 实现系统钩子，方法名为钩子名的驼峰形式 | 无 |

## 插件配置文件

插件配置文件位于插件根目录，文件名：`config.php`，不需要配置的插件可不添加此文件。

**示例**：`config.php`

```php
<?php
return [
    'text' => [
        'title' => '文本',                    // 表单标签
        'type'  => 'text',                  // 表单类型
        'value' => 'hello, ThinkCMF!',      // 默认值
        'tip'   => '这是文本组件的演示'      // 帮助提示
    ],
    'password' => [
        'title' => '密码',
        'type'  => 'password',
        'value' => '',
        'tip'   => '这是密码组件'
    ],
    'number' => [
        'title' => '数字',
        'type'  => 'number',
        'value' => '1.0',
        'tip'   => '这是数字组件的演示'
    ],
    'select' => [
        'title'   => '下拉列表',
        'type'    => 'select',
        'options' => [
            '1' => 'ThinkCMFX',
            '2' => 'ThinkCMF',
            '3' => '跟猫玩糗事',
            '4' => '门户应用'
        ],
        'value'   => '1',
        'tip'     => '这是下拉列表组件'
    ],
    'checkbox' => [
        'title'   => '多选框',
        'type'    => 'checkbox',
        'options' => [
            '1' => 'genmaowan.com',
            '2' => 'www.thinkcmf.com'
        ],
        'value'   => '1',
        'tip'     => '这是多选框组件'
    ],
    'radio' => [
        'title'   => '单选框',
        'type'    => 'radio',
        'options' => [
            '1' => 'ThinkCMFX',
            '2' => 'ThinkCMF'
        ],
        'value'   => '1',
        'tip'     => '这是单选框组件'
    ],
    'textarea' => [
        'title' => '多行文本',
        'type'  => 'textarea',
        'value' => '这里是你要填写的内容',
        'tip'   => '这是多行文本组件'
    ],
    'date' => [
        'title' => '日期',
        'type'  => 'date',
        'value' => '2017-05-20',
        'tip'   => '这是日期组件的演示'
    ],
    'datetime' => [
        'title' => '时间',
        'type'  => 'datetime',
        'value' => '2017-05-20',
        'tip'   => '这是时间组件的演示'
    ],
    'color' => [
        'title' => '颜色',
        'type'  => 'color',
        'value' => '#103633',
        'tip'   => '这是颜色组件的演示'
    ],
    'image' => [
        'title' => '图片',
        'type'  => 'image',
        'value' => '',
        'tip'   => '这是图片组件的演示'
    ],
    'location' => [
        'title' => '地理坐标',
        'type'  => 'location',
        'value' => '',
        'tip'   => '这是地理坐标组件的演示'
    ],
];
```

### 配置项支持的类型

| 类型 | 说明 | 是否需要 options |
|----------|------|-------------------|
| `text` | 文本输入框 | 否 |
| `password` | 密码输入框 | 否 |
| `number` | 数字输入框 | 否 |
| `textarea` | 多行文本框 | 否 |
| `select` | 下拉选择框 | 是 |
| `radio` | 单选按钮 | 是 |
| `checkbox` | 复选框 | 是 |
| `date` | 日期选择器 | 否 |
| `datetime` | 时间选择器 | 否 |
| `color` | 颜色选择器 | 否 |
| `image` | 图片上传 | 否 |
| `location` | 地理坐标选择 | 否 |

### 获取插件配置

**在插件控制器中**：

```php
$config = $this->getPlugin()->getConfig();
```

**在插件主类中**：

```php
$config = $this->getConfig();
```

### 自定义配置处理

如果需要完全自定义插件配置处理，在配置文件中添加以下选项：

```php
return [
    'custom_config' => [
        'title' => '自定义配置处理',
        'type'  => 'text',
        'value' => '1',  // 值为 1 表示由插件自己处理配置
        'tip'   => '自定义配置处理'
    ],
    // ... 其他配置项
];
```

自定义配置的界面入口在 `AdminIndex/setting`，即插件的 `AdminIndexController` 的 `setting` 方法。

## 插件开发流程

### 1. 确定功能和命名

- 确定插件的功能需求
- 给插件起英文名和中文名，例如：`Demo` / `插件演示`
- 在 `public/plugins/` 目录下创建插件目录，例如：`demo`

### 2. 创建配置文件

- 如果插件需要后台配置，在插件根目录添加 `config.php`
- 参考上述配置文件示例

### 3. 创建插件主类

- 在插件根目录创建主类文件，例如：`DemoPlugin.php`
- 参考上述插件主类示例

### 4. 添加视图模板

- 如果需要模板，在插件根目录添加 `view/` 目录

### 5. 添加控制器

- 如果需要外部访问，添加 `controller/` 目录
- 创建控制器文件，继承 `PluginBaseController` 或 `PluginAdminBaseController`

### 6. 添加钩子

- 在模板中添加钩子，例如：`<hook name="footer_start"/>`
- 在插件主类中实现对应的钩子方法

### 7. 安装插件

- 访问后台插件管理页面
- 刷新页面即可看到新添加的插件
- 点击安装启用

## 注意事项

1. **命名空间**：插件命名空间为 `plugins\{插件目录名}`
2. **继承基类**：插件主类必须继承 `cmf\lib\Plugin`
3. **数据表前缀**：插件数据表必须使用 `plugin_{插件名}_` 前缀
4. **卸载处理**：`uninstall()` 方法中不要 try-catch 数据库异常，直接抛出
5. **学习参考**：可从系统后台应用中心下载 Demo 插件作为开发参考
6. **钩子命名**：钩子名为下划线命名，方法名为驼峰命名，例如 `footer_start` 对应 `footerStart()`

## 插件目录位置说明

- **插件代码**：`public/plugins/{插件名}/`
- **插件控制器**：`public/plugins/{插件名}/controller/`
- **插件视图**：`public/plugins/{插件名}/view/`
- **插件配置**：`public/plugins/{插件名}/config.php`

# 命名规范

ThinkCMF遵循PSR-2命名规范和PSR-4自动加载规范及 ThinkPHP的开发规范，并且注意如下规范：

## 目录和文件

- 目录使用小写+下划线
- 类库、函数文件统一以.php为后缀
- 类的文件名均以命名空间定义，并且命名空间的路径和类库文件所在路径一致
- 类（包含接口和Trait）文件采用驼峰法命名（首字母大写），其它文件采用小写+下划线命名
- 类名（包括接口和Trait）和文件名保持一致，统一采用驼峰法命名（首字母大写）

## 函数和类、属性命名

- 类的命名采用驼峰法（首字母大写），例如 `User`、`UserType`
- 函数的命名使用小写字母和下划线（小写字母开头）的方式，例如 `get_client_ip`
- 方法的命名使用驼峰法（首字母小写），例如 `getUserName`
- 属性的命名使用驼峰法（首字母小写），例如 `tableName`、`instance`
- 特例：以双下划线 `__` 打头的函数或方法作为魔术方法，例如 `__call` 和 `__autoload`

## 常量和配置

- 常量以大写字母和下划线命名，例如 `APP_PATH`
- 配置参数以小写字母和下划线命名，例如 `url_route_on` 和 `url_convert`
- 环境变量定义使用大写字母和下划线命名，例如 `APP_DEBUG`

## 数据表和字段

- 数据表和字段采用小写加下划线方式命名，并注意字段名不要以下划线开头，例如 `think_user` 表和 `user_name` 字段
- 不建议使用驼峰和中文作为数据表及字段命名

## URL规范

- 除 api 的 url，其它 url 不能以 `api/` 开头

## 模板规范

- 模板 assign 变量：命名小写+下划线
- 每个 assign 变量必须名称相同，例如：`$this->assign('post', $post);`

## 表单规范

- 表单 name 命名：小写+下划线

## 类命名规范

### 控制器命名

- 类名：控制器名（驼峰法，首字母大写） + `Controller`
- 文件名：类名 + `.php`
- 示例：`IndexController`、`UserController.php`

### 其他类命名

- Model、Validate、Logic、Service：采用驼峰法（首字母大写）并加类名后缀
- 示例：`UserModel`、`UserValidate`、`UserLogic`、`UserService`

## 代码规范

- 请不要在任何 PHP 代码里使用 `exit`、`die`
- 请避免使用 PHP 保留字

# 数据库规范

## 表规范

### 表命名规范

- 命名统一使用小写+下划线
- 非 CMF 核心应用，统一带应用表前缀，例如：`portal_`
- 插件表，统一带插件表前缀，例如：`plugin_demo_`

### 表基础配置

- 表默认编码：`utf8mb4`
- 默认排序规则：`utf8mb4_general_ci`
- 引擎统一使用：`InnoDB`
- 必须写表注释

## 字段规范

### 字段命名规范

- 命名统一使用小写+下划线
- 非自增主键一定要写字段注释

### 字段类型规范

- 数据类型尽量使用数字类型，数字类型比字符类型快很多
- 数据类型尽量小（在满足可预见的未来需求前提下，但不能太小）
- 尽量不要允许 `NULL`
- 固定长度的字符串使用 `char` 不使用 `varchar`

### 字段命名约定

- 布尔类型的值均以 `is_`、`has_`、`exist_` 或者 `can_` 开头
- `create_time` 作为记录创建时间
- `update_time` 作为记录更新时间
- `delete_time` 作为记录软删除时间（需要软删除的表统一添加此字段）
- `status` 表示记录状态
- `remark` 代表备注，给管理员区分记录类型使用
- `description` 代表描述，给前台用户使用
- `list_order` 代表记录排序字段，类型 `float`，默认值 `10000`，默认排序按从小到大
- `image` 代表图片，`thumbnail` 代表缩略图，`photos` 代表相册
- `more` 代表表扩展属性，类型为 `text` 或 `longtext`
- 除 `user` 表，其他表使用 `user_id` 代表用户 ID
- `parent_id` 代表父级 ID

### 多语言字段规范

- 多语言排序要求字符串类型，统一使用 `utf8mb4_unicode_ci`

## 内容保存规范

### 基础规范

- ThinkCMF 所有字段内容都使用 `htmlspecialchars()` 方法处理

### 富文本字段保存规范

富文本字段在保存时的处理流程：

1. 使用 `htmlspecialchars_decode()` 解密
2. 使用 `cmf_replace_content_file_url()` 处理（注意第二个参数要设置为 `true`）
3. 再使用 `htmlspecialchars()` 方法处理后保存到数据库

```php
// 示例
$content = htmlspecialchars(cmf_replace_content_file_url(htmlspecialchars_decode($content), true));
```

### 富文本字段显示规范

富文本字段从数据库取出时的处理流程：

1. 使用 `htmlspecialchars_decode()` 解密
2. 使用 `cmf_replace_content_file_url()` 处理

```php
// 示例
$content = cmf_replace_content_file_url(htmlspecialchars_decode($content));
```

## 文件路径保存规范

### 路径存储格式

- 所有上传的文件在数据库中保存为相对路径，相对于 `upload` 目录
- 例如：`/upload/20170912/b249b3a5bd5ab59f726afb5c73eae699.jpg` 在数据库中应保存为 `20170912/b249b3a5bd5ab59f726afb5c73eae699.jpg`

### 路径转换函数

从数据库取出文件路径后，可以使用以下函数转化为可访问的 URL：

- `cmf_get_image_url()` - 转化为可访问的图片 URL
- `cmf_get_file_download_url()` - 转化为可下载的文件 URL

```php
// 示例
$imageUrl = cmf_get_image_url($imagePath);
$downloadUrl = cmf_get_file_download_url($filePath);
```