# 代码开发规范


# 1.1 路由

# 1.1.1 类似 Restful 的路由规范

  • 单动作类,命名仿下图
  • 目录[大驼峰]、文件名[大驼峰]以单数为主。
  • 两级(资源一级、动作一级)
  • url小驼峰
  • queryString字段,camel命名,ID带前缀,如userId
  • body字段 - camel命名。
HTTP URI/路由名称 动作 文件路径 说明
GET photo/index index app/Action/Photo/Index.php 查询 - 多条 (列表 - 分页搜索)
GET photo/show show app/Action/Photo/Show.php 查询 - 单条
GET photo/create create app/Action/Photo/Create.php 添加 - 页面
POST photo/store store app/Action/Photo/Store.php 添加 - 动作
GET photo/edit edit app/Action/Photo/Edit.php 修改 - 页面
PUT/PATCH photo/update update app/Action/Photo/Update.php 修改 - 动作
DELETE photo/destroy destroy app/Action/Photo/Destroy.php 删除 - 动作

#

# 1.1.3 路由位置

注解路由

<?php
    /**
     * @RequestMapping(path="/user/index", methods="GET")
     * @Middleware(PermissionMiddleware::class)
     * @return array 返回数组
     */
    public function handle(): array
    {

    }

# 1.2 Request验证

验证基本的非业务类的数据类型验证,此层写在控制器层

<?php
    /**
     * 验证规则.
     */
    public function rules(array $inputs): array
    {
        return [
            'id'   => 'required|int',
            'name' => 'required|max:25',
        ];
    }
        
    
    /**
     * 属性替换.
     * @return array|string[] ...
     */
    public function attributes(): array
    {
        return [
            'name' => '姓名',
        ];
    }
    
    /**
     * 验证场景.
     * @return array|array[] 场景规则
     */
    public function scene(): array
    {
        return [
             // 保存
            'store' => ['name'],
        ];
    }

# 1.3 Controller控制器层

# 1.3.1 约束

  • 参数不应该$this->all(),明确具体参数,建议使用$this-request->inputs(['字段名称'])
  • 验证类在内
<?php
use MoChat\Framework\Request\ValidateSceneTrait;

...
public function handle(): array
{
    // 接收参数
    $params = $this->request->inputs(['name'], ['name' => '']);
    // 验证
    $this->validated($params, 'store');
    return [];
}

# 1.3.2 命名规范

  • 类名与文件名称相同。
  • 类名为大驼峰;属性、方法为小驼峰;静态变量为大写字母、"_"下划线组合

# 1.4 Model 与 Service 模型层命名规范

# 基本约束
  • 所有表、字段操作通过迁移文件
  • 通过某种方式获取或者修改数据,要获取数据+By+方式 例如获取用户 getUserByUid
  • 修改表的某个字段: update+修改的表+字段 修改用户昵称,updateUserNickname
  • 查询:分页之外,所有查询方法不应该封装 function(array $where){}
  • 修改:单字段修改,不应该使用全量修改方法
  • 自定义写新方法;命名时 - 条件少时,如 byNameAge;条件多时,抽象功能,如 bySortList
# 查询约束
  • 获取单条数据命名:get+要获取的数据【单数】+ById 比如获取用户数据 getUserById [id, columns]
  • 获取多条数据: get+要获取的数据【复数】+ById 比如获取用户数据 getUsersById [id、columns、orderBy、limit]
  • 获取分页数据: get+要获取的数据【单数】+List 比如获取用户列表 getUserList 【where, page, pageSize, orderBy, columns】
  • 自定义方法:get + 要获取的数据[单数为一条,复数为多条] + By...
# 添加、修改、删除约束
  • 单条添加 : create+要添加的表 比如添加用户 createUser
  • 单条修改 : update+要修改的表 比如修改用户 updateUserById
  • 单条删除:delete+要删除的表【单数】+ById 比如删除用户 deleteUserById
  • 多条删除:delete+要删除的表【复数】+ById 比如删除用户 deleteUsersById
  • 删除:只允许通过ID

# 1.4.2 利用 Trait 来扩展数据模型

有时候数据模型里的代码会变得很臃肿,应该 利用 Trait 来精简逻辑代码量,提高可读性,类似于 Ruby China 源码。

借鉴于 Rails 的设计理念:「Fat Models, Skinny Controllers」。

所有模型相关的 Traits 必须存放于 /path/Models/Traits 目录下。


# 其它

  • 基本的 PSR 规范
  • 接口文档 - apidoc,项目接口文档存于 ./app/storage/apidoc
  • 注释采用:phpdoc
  • 格式化工具: friendsofphp/php-cs-fixer
  • 类型提示必须;declare(strict_types=1);
  • 枚举、契约。目录一级