PHP 开发规范
TanzCMS PHP 代码的控制器、服务、数据库、安全和模板边界。
PHP 开发规范
本文说明 TanzCMS 二次开发时 PHP 代码应该怎么写。核心目标是:业务边界清楚、模板不被 PHP 接管、插件和模块可以独立启停。
一、职责边界
| 层级 | 应该负责 | 不应该负责 |
|---|---|---|
| Controller | 请求校验、权限检查、调用服务、返回响应 | 拼整页 HTML、直接写复杂 SQL、塞大量业务流程 |
| Service | 业务规则、事务、缓存失效、事件、数据组装 | 读取请求对象、输出页面结构 |
| Model/Query | 单表或查询表达 | 决定页面视觉和业务按钮文案 |
| Template Tag | 参数解析、结构化取数、循环上下文 | 接收 SQL、输出整块固定页面 |
Theme .html |
页面结构、列表卡片、按钮和视觉 | PHP 业务逻辑、数据库查询 |
二、控制器写法
控制器保持薄:
<?php
namespace Modules\Demo\Http\Controllers;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Modules\Demo\Services\DemoItemService;
class DemoItemController extends Controller
{
public function index(Request $request, DemoItemService $service): JsonResponse
{
$filters = $request->validate([
'keyword' => ['nullable', 'string', 'max:80'],
'page' => ['nullable', 'integer', 'min:1'],
]);
return response()->json($service->paginate($filters));
}
}
控制器不要直接拼页面:
// 不推荐
$html = '<div class="card">'.$title.'</div>';
return $html;
需要展示结构时,把数据交给模板或后台通用组件。
三、服务写法
服务负责业务和事务:
<?php
namespace Modules\Demo\Services;
use Illuminate\Support\Facades\DB;
class DemoItemService
{
public function create(array $data): int
{
return DB::transaction(function () use ($data): int {
$id = DB::table('demo_items')->insertGetId([
'title' => trim((string) $data['title']),
'status' => 1,
'created_at' => now(),
'updated_at' => now(),
]);
// 这里可以触发事件、清理缓存、写审计日志。
return (int) $id;
});
}
}
服务不要依赖某个主题、栏目 slug 或页面路径。
四、数据库写法
- 使用查询构造器、模型或服务层封装,不拼接用户输入到 SQL。
- 表名按系统表前缀规则处理,不在 SQL 字符串中写死物理表名。
- 字段名、排序字段、筛选操作符必须经过白名单或字段定义校验。
- 大表列表默认只查轻字段,正文、大 JSON、大附件进入详情或批量加载。
推荐:
$rows = DB::table('demo_items')
->where('status', 1)
->orderByDesc('id')
->paginate(20);
不推荐:
// 不推荐:用户输入不能拼进 SQL
DB::select('select * from demo_items where title like "%'.$keyword.'%"');
五、异常和响应
后台和 API 接口返回 JSON:
return response()->json([
'message' => '保存成功',
'data' => $data,
]);
验证失败使用 Laravel 验证规则返回 422;无权限返回 403;记录不存在返回 404。不要把异常堆栈直接输出给访客。
六、安全规则
- 后台表单和敏感接口必须有 CSRF 和权限校验。
- 插件公开回调必须有签名、幂等和日志。
- 上传必须走系统上传服务,不自行拼目录保存。
- 密钥、Token、AppSecret 不输出到前台模板和页面源码。
- 普通变量默认安全转义,只有已清洗 HTML 才允许
{html ...}。
七、模板与 PHP 边界
PHP 可以做:
- 查询数据。
- 格式化结构化变量。
- 生成 URL、状态、权限布尔值。
- 输出低层安全 HTML 小片段,例如分页、图标、字段控件。
PHP 不应做:
- 为某个栏目硬编码页面布局。
- 为某个主题拼整块 HTML。
- 为某个外链、slug、URL 写控制器分支。
- 把插件禁用后仍必须依赖的逻辑写进核心。
如果页面只是视觉不同,应改主题模板或后台模板配置,而不是改 PHP。