下面给出一份「AI 编辑器 + ThinkPHP8」场景下的 rules 编写模板,可直接放进 Cursor、Copilot、ChatGPT 自定义指令或 .cursorrules
文件里。
目标:让 AI 始终按 ThinkPHP8 官方最佳实践 输出代码,不踩坑、不犯低级错误、不回头返工。
✅ 文件名建议
.cursorrules
或 .tphp8-rules.md
(放在项目根目录,AI 会自动读取)
✅ ThinkPHP8 开发 Rules(AI 编辑器专用)
# ThinkPHP8 开发强制规范(AI 必须遵守)
## 1. 框架版本与运行环境
- PHP ≥ 8.1,必须开启 `mbstring`、`openssl`、`pdo`、`json`、`tokenizer`
- 只使用 ThinkPHP8.0+ 官方文档已出现的 API,禁止混用 5.x/6.x 废弃写法
- 所有代码必须兼容 `php think run` 启动方式
## 2. 目录与命名
- 控制器:`app\controller\{模块}\{驼峰}Controller.php`,类名 `FooBarController`
- 模型:`app\model\{驼峰}.php`,类名 `FooBar`,继承 `think\Model`
- 验证器:`app\validate\{驼峰}.php`,类名 `FooBarValidate`,继承 `think\Validate`
- 业务层:`app\service\{驼峰}.php`,类名 `FooBarService`,禁止在控制器写 SQL
- 路由定义文件:`route\app.php`(多模块则 `route\{模块}.php`)
- 视图:`view\{控制器小写}\{方法小写}.html`,使用 `layout+{block}` 机制,禁止 PHP 原生标签
## 3. 路由风格
- 必须显式注册,禁用 `route.php` 中的 `__pattern__` 模糊路由
- RESTful 资源路由优先:
Route::resource('article', 'Article');
- 任何带参数路由必须给变量规则:
Route::get('news/
## 4. 控制器规范
- 必须继承 `think\Controller`,类库引入使用 `use` 声明
- 任何 DB 操作必须调用模型或 Service,控制器里禁止 `Db::table()` 裸写
- 返回类型统一:
- 视图:`return view('', [...]);`
- JSON:`return json([...]);`
- 重定向:`return redirect('/');`
- 所有方法必须写注释,标注:
@route GET /foo/bar
@return \think\response\Json
## 5. 模型规范
- 主键默认 `id`,若不符必须声明 `protected $pk = 'xxx';`
- 时间戳字段默认 `create_time/update_time`,若不符声明:
protected $autoWriteTimestamp = 'datetime';
protected $createTime = 'add_time';
protected $updateTime = 'edit_time';
- 任何聚合查询(sum、count)必须使用 **查询作用域** 或 **静态方法** 封装,禁止在 Service 外部写原生 SQL
- 关联模型必须使用 `with()` 预载入,避免 N+1:
User::with('profile')->select();
## 6. 验证 & 安全
- 所有用户输入必须走验证器,禁止 `$request->param()` 后直接入库
- 文件上传必须使用 `think\facade\Filesystem`:
$path = \think\facade\Filesystem::disk('public')->putFile('topic', $file);
- SQL 注入:禁止使用 `whereRaw("id={$id}")` 等字符串拼接;占位符写法:
where('id', $id)
- XSS:视图输出默认自动转义,若必须输出 HTML,使用 `{$content|raw}` 并确保已 `strip_tags` 过滤危险标签
## 7. 配置与 env
- 敏感信息(数据库、redis、密钥)必须写在 `.env`,禁止 hard-code
- 配置缓存:生产环境必须生成 `php think optimize:config`
- 路由缓存:生产环境必须生成 `php think optimize:route`
## 8. 异常与日志
- 业务异常抛 `think\Exception` 并带 HTTP 状态码:
throw new \think\Exception('订单已支付', 400);
- 日志使用 `think\facade\Log` 渠道名统一为当前模块:
Log::channel('payment')->info('wechat notify', $data);
## 9. 前端约定
- 视图里只使用 `{$var}` 或 `{:url('')}` 两种标签,禁用原生 PHP 语法
- 静态资源路径统一 `/static/{模块}/css|js|images/...`
- 开启资产版本号:
## 10. 命令行 & 脚本
- 自定义指令继承 `think\console\Command`,注册到 `config/console.php`
- 长耗时脚本必须配合 `php think queue:work` 使用 Redis 驱动,禁止在 Web 控制器里同步执行
## 11. 单元测试
- 使用 PHPUnit 9.5+,测试类放在 `tests/`,命名 `*Test.php`
- 任何 Service 层公共方法必须同步提供测试用例,覆盖率 ≥ 80%
## 12. AI 输出格式
- 只返回 **PHP 代码块** + **路由片段** + **SQL 迁移**(若涉及),不要解释废话
- 代码里必须带 **命名空间** 与 **use 声明**
- 若需多文件,按「文件路径 => 代码」Map 格式返回,方便一次性粘贴
✅ 使用示例(AI 收到指令后)
用户:
写一个 ThinkPHP8 文章 RESTful 接口,带分页、搜索、软删。
AI 按 rules 输出:
// route/app.php
Route::resource('article', 'Article')->pattern(['id' => '\d+']);
// app/controller/Article.php
namespace app\controller;
use app\model\Article;
use app\validate\ArticleValidate;
use think\facade\Request;
class Article extends BaseController
{
public function index()
{
$kw = Request::get('kw');
$list = Article::when($kw, fn($q) => $q->where('title', 'like', "%$kw%"))
->paginate(15);
return json($list);
}
public function read($id)
{
return json(Article::findOrFail($id));
}
public function save()
{
validate(ArticleValidate::class)->check(Request::post());
$article = Article::create(Request::post());
return json($article, 201);
}
public function update($id)
{
validate(ArticleValidate::class)->check(Request::put());
Article::update(Request::put(), ['id' => $id]);
return json([], 204);
}
public function delete($id)
{
Article::destroy($id);
return json([], 204);
}
}
// app/model/Article.php
namespace app\model;
use think\Model;
use think\model\concern\SoftDelete;
class Article extends Model
{
use SoftDelete;
protected $deleteTime = 'delete_time';
protected $autoWriteTimestamp = true;
}
// app/validate/ArticleValidate.php
namespace app\validate;
use think\Validate;
class ArticleValidate extends Validate
{
protected $rule = [
'title' => 'require|length:2,100',
'body' => 'require',
];
}
✅ 一键导入
把上面的 .cursorrules
保存到项目根目录后,Cursor / Copilot / ChatGPT 自定义指令 里再写一句:
所有 ThinkPHP 代码必须严格遵循 .cursorrules
里的规范,否则拒绝输出。
即可让 AI 永远按 ThinkPHP8 官方最佳实践写代码,零踩坑。