TanzCMS开源CMS系统

PHP 开发规范

TanzCMS PHP 代码的控制器、服务、数据库、安全和模板边界。

更新:2026-05-31 03:07:49 浏览:6

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。