Skip to content

开发规范

项目结构

youlai-think/
├── app/                     # 应用核心目录
│   ├── controller/          # 控制器
│   ├── service/             # 业务服务
│   ├── model/               # 数据模型
│   ├── middleware/          # 中间件
│   ├── common/              # 公共模块
│   │   ├── enums/           # 枚举类
│   │   ├── security/        # 认证/权限/异常
│   │   └── ...
│   └── validate/            # 验证器
├── config/                  # 配置文件
├── public/                  # Web 入口目录
├── route/                   # 路由定义
├── runtime/                 # 运行时缓存
├── .env                     # 环境变量
└── composer.json            # 依赖管理

目录约定

目录说明
app/controller控制器(接收请求)
app/service业务服务(业务逻辑)
app/model数据模型(ORM)
app/middleware中间件(认证/权限)
app/common公共模块(枚举/工具类)
app/common/security认证/权限/异常处理
config/配置文件
route/路由定义

开发规范

架构分层

  • Controller:接收请求,调用 Service,返回响应
  • Service:业务逻辑处理
  • Model:数据库操作

重要:Controller 禁止直接操作数据库,必须通过 Service 调用。

控制器示例

php
<?php
namespace app\controller;

use app\service\UserService;
use support\Request;
use support\Response;

class UserController
{
    protected UserService $userService;

    public function __construct()
    {
        $this->userService = new UserService();
    }

    public function list(Request $request): Response
    {
        $params = $request->get();
        $result = $this->userService->list($params);
        return json($result);
    }
}

服务示例

php
<?php
namespace app\service;

use app\model\User;
use think\facade\Db;

class UserService
{
    public function list(array $params): array
    {
        $query = User::where('is_deleted', 0);
        
        // 业务逻辑处理
        $total = $query->count();
        $list = $query->select()->toArray();
        
        return [
            'total' => $total,
            'list' => $list,
        ];
    }
}

命名规范

文件命名

  • 大驼峰:UserController.php, UserService.php
  • 模型:User.php, Role.php

类命名

  • 大驼峰:UserController, UserService, UserModel

方法命名

  • 小驼峰:getUserById, listUsers, createUser

参数校验

使用验证器

php
<?php
namespace app\validate;

use think\Validate;

class UserValidate extends Validate
{
    protected $rule = [
        'username' => 'require|max:50',
        'password' => 'require|min:6|max:20',
        'email' => 'email',
    ];

    protected $message = [
        'username.require' => '用户名不能为空',
        'username.max' => '用户名最多50个字符',
        'password.require' => '密码不能为空',
        'password.min' => '密码至少6个字符',
    ];
}

控制器验证

php
public function create(Request $request): Response
{
    $validate = new UserValidate();
    if (!$validate->check($request->post())) {
        return json(['code' => 'A0400', 'msg' => $validate->getError()]);
    }
    
    // 业务处理
}

统一响应

所有接口返回统一格式:

php
// 成功响应
return json([
    'code' => '00000',
    'msg' => '操作成功',
    'data' => $result
]);

// 错误响应
return json([
    'code' => 'A0001',
    'msg' => '认证失败',
    'data' => null
]);

异常处理

业务异常

php
<?php
namespace app\common\exception;

use Exception;

class BusinessException extends Exception
{
    protected string $code;
    protected string $msg;

    public function __construct(string $code, string $msg = '')
    {
        $this->code = $code;
        $this->msg = $msg;
        parent::__construct($msg);
    }

    public function getErrorCode(): string
    {
        return $this->code;
    }
}

异常捕获

php
try {
    $result = $this->userService->create($data);
    return json(['code' => '00000', 'msg' => '操作成功', 'data' => $result]);
} catch (BusinessException $e) {
    return json(['code' => $e->getErrorCode(), 'msg' => $e->getMessage(), 'data' => null]);
}

接口幂等

  • 优先使用数据库唯一约束兜底
  • 对高风险写操作使用 Redis 分布式锁
php
$lockKey = "lock:order:{$orderId}";
$locked = Redis::setnx($lockKey, 1);
if (!$locked) {
    throw new BusinessException('A0004', '操作进行中,请勿重复提交');
}
Redis::expire($lockKey, 30);

try {
    // 业务处理
} finally {
    Redis::del($lockKey);
}

相关文件

文件说明
app/common/exception/BusinessException.php业务异常
app/common/enums/ResultCode.php错误码定义
app/middleware/中间件

参考资料

基于 MIT 许可发布