php 代码规范
常规规范
https://zhuanlan.zhihu.com/p/222477949
注解
方法注解
/** * @notes:介绍 * @author: qiuyang * @date: 2022/10/18 * @return:Grid */
控制器
/** * @notes: * @author: qiuyang * @date: 2022/10/18 * @api:amin/user/list */ @param 如果是临时自定义参数 需要加上参数
phpstorm配置
/**
@notes:
@author: ${USER}
@date: ${DATE}
${PARAM_DOC}
#if (${TYPE_HINT} != "void") * @return ${TYPE_HINT}
#end
${THROWS_DOC}
*/
代码行数控制
85%代码控制在50行以内 10%代码控制在100行以内 5% 代码控制在100-200行
laravel
控制器: 接收数据表单验证 model: 表定义信息和关联表 (一对一 一对多等等) Repositories: 数据库操作 服务层 : 只写逻辑(sql相关禁止写入)
开发相关变量命名词汇
常见开发相关变量命名词汇
一、名词
name 名称 title 标题 remark 备注 date 日期 time 时间 state 状态 type 类型 result 结果 context 上下文 常用于状态封装 base 基类 常用语模板方法设计模式中的父类命名 handler 处理器,句柄 environment 环境,上下文 location 位置 resource 资源 message 消息 scope 范围,领域 stage 阶段 state 状态 source 来源 dispatcher 分发者 router 路由器 route 路由 resolver 处理器 mapping 映射 adapter 适配器 manager 管理者 prefix 前缀 suffix 后缀 strategy 策略 attribute 属性 snapshot 快照 element 元素 argument 参数 pattern 模式 overview 概述 mode 模式 console 控制台 command 命令 instance 实例 registry 注册中心 range 范围 rank 等级 score 得分,计分 ping ping pong pong monitor 监听器 customizer 定制器 block 区块 node 节点 position 位置 master 主 boss 从 worker 从 region 区域 policy 策略 provider 提供者
二、动词
add 添加 / remove 移除 insert 插入 / delete 删除 create 创建 / destroy 销毁 get 获取 / release 释放 show 显示 / hide 隐藏 start 开始 / stop 停止 open 打开 / close 关闭 lock 锁定 / unlock 解锁 increment 增加 / decrement 减少 login 登录 / logout 退出 next 下一个 / previous 上一个 import 导入 / export 导出 get 获取 / set 设置 read 读取 / write 写入 load 载入 / save 保存 import 导入 / export 导出 play 播放 / pause 暂停 input 输入 / output 输出 encode 编码 / decode 解码 encrypt 加密 / decrypt 解密 pack 打包 / unpack 解包 connect 连接 / disconnect 断开 send 发送 / receive 接收 download 下载 / upload 上传 push 推 / pull 拉 expand 展开 / collapse 折叠 enter 进入 / exit 退出 pop 出栈 / push入栈 store 存储 / query查询 builder 构造 / parser 解析 bind 绑定 resolve 解析,处理 parse 解析 handle 处理 process 处理 display 展示 merge 合并 call 调用 run 调用 refresh 刷新 load 载入,加载,装载 init 初始化 obtain 获取 access 访问,触及 control 控制 dispatch 分发,路由 adapt 适应,适配 manage 管理 detect 探测 trigger 触发 build 构建 封装 render 渲染 restore 恢复 create 创建 fill 填充 execute 执行 assign 分配 generate 生成,产生 link 连接 deduce 推断 report 报告 prepare 准备,预备 apply 应用 实施 申请 delete 删除 dump 转储 migrate 迁移 sort 排序 scan 扫描 append 追加 push 压,推 pop 弹出 offer 提供 subscribe 订阅 publish 发布 watch 监听 eval 执行,评估 echo 回应,反馈 alter 切换 attach 关联 seek 查找 skip 跳过 fetch 获取 provide 提供
单词
select 选取 find 查找 search 搜索 settings 设置 listener 监听 trigger 触发 tap 轻敲
三、形容词
begin 开始 / end 结束 first 第一个 / last 最后一个 up 上面 / down 下面 source 源 / target 目标 old 旧的 / new 新的 min 最小 / max 最大 required 必要的 optional 可选的 default 默认的 meta 元,基础的 enabled 开启的,可用的 primary 主要的 首要的 composite 综合的 合成的 main 主要的 multi 多 多元 extra 额外的 附加的 internal 内部的 inner 内部的 inter 外部的
计算值
totals 总计 简写 Sum averages 平均 简写 Avg
其他
settings,配置 traversal,遍历 proactor,设计模式 adapter,适配器 listener,监听器 trigger,触发器 acceptor,接收器 connector,连接器 dispatch,调度,分派,分发 dispatcher,分派器 reactor,反应器 executor,执行器 parser,解析器 builder,生成器,构造器 handle,句柄 handle,处理 handler,处理器 Invoke,调用 Invoker,调用方 demo,原型 modle,模型 masterplate,模版 pool,池 thread pool,线程池 memory pool,内存池
开发优化重构技巧
注意事项
1 复杂的业务功能可在当前模块中闭环 复用的方法需在Interface定义 (防止乱复用)
2 不相关的业务放回对应模块
思路
第一次优化
1 抽离 最核心的主体 例如 商品详情:currency product customer language set值对象
如果抽离出别的模块 同样提取主题 set
2 公共的工具类方法抽离
3 方法的抽离
注: 如果第一次只拿过来直接简单改 后期消耗时间长 周期大
//初始参数
$this->setCurrency($productDetailDto->code)
->setProduct($productDetailDto->productId)
->setCustomer($productDetailDto->customerId)
->setLanguage($productDetailDto->languageId)
//币种
private function setCurrency($code): ProductServiceInterface
{
$this->currency = Currency::getCurrencyInfo($code);
return $this;
}
//商品信息
private function setProduct(int $productId): ProductServiceInterface
{
$this->product = $this->productRepo->getById($productId);
return $this;
}
//会员信息
private function setCustomer(int $customerId): ProductServiceInterface
{
$this->customer = $this->customerRepo->getById($customerId);
return $this;
}
//语言
private function setLanguage(int $languageId): ProductServiceInterface
{
$this->language = $languageId;
return $this;
}
if else
# 注意:嵌套控制在两层 3层跳出处理
$type=1
match ($type) {
1 => "Oh no!",
2 => "This is what I expected",
3 => "This is what I expected",
};
phpstorm PSR-2
PSR-2 对大小写 缩写 单词 返回 类型 换行 空格 符号 注解 部分新特性 不规范代码等提示
下载地址 windows PHP_CodeSniffer mac php-code-sniffer — Homebrew Formulae 安装说明 在PhpStorm中使用PSR2编码规范phpcbf脚本自动修正代码格式_OwenZhang的技术博客_51CTO博客
laravel 项目规范
核心目录
Controllers
#创建控制器:模块名/控制器名
Product.ProductController 主产品
Product.AttributeController 产品属性
Product.CategoryController 产品分类
# 返回统一使用方法
return $this->result->succeed();
return $this->result->failed("error");
#注意点
1 Services 异常抛出
2 控制器统一 try catch 捕获
例如:
try {
$register = $this->customer->login(new CustomerLogin($params));
return $this->result->succeed($register);
} catch (\Exception $e) {
return $this->result->failed($e->getMessage());
}
3 所有code码必须定义常量ResultCode
4 自动验证 分离
Requests 自动验证
//注册
//控制器方法 注入验证类 CustomerRequest
public function register(CustomerRequest $request): JsonResponse
{
$params = $request->validated();
$register = $this->customer->register(
new CustomerRegister(
firstname: $params['firstname'] ,
lastname: $params['lastname'] ?? 20,
email: $params['email'] ?? "",
password: $params['password'] ?? "",
));
if ($register) {
return $this->result->succeed();
}
return $this->result->failed("error");
}
#自动验证实现
1 如果一个类存在单个自动验证可以直接写入rules 方法
2 存在多个 注释rules 以控制器方法名为命名;
class CustomerRequest extends BaseRequest
{
/**
* @notes: 默认验证
* @return array
* @author: qiuyang
* @date: 2022/11/21
*/
/* public function rules()
{
}
/**
* @notes: 自动验证注册
* @return array
* @author: qiuyang
* @date: 2022/11/21
*/
public function register():array
{
$params = request()->only(["firstname", "lastname", "email", "password", "repassword"]);
return [
'firstname' => 'required|min:1|max:32',
'lastname' => 'required|min:1|max:32',
'email' => ['required', "email:rfc,dns", "unique:customer,email",
//->ignore($params['email'],"email")
Rule::unique('update_account')->where(function ($query) use ($params) {
$query->where('date_added', ">", date('Y-m-d H:i:s', strtotime("-1 day")));
$query->where(["status" => 0]);
$query->where(["email" => $params['email']]);
return $query;
})
],
'password' => 'required|min:6|max:32',
'repassword' => 'required|same:password',
];
}
/**
* @notes: 登录
* @return array
* @author: qiuyang
* @date: 2022/11/21
*/
public function login(): array
{
return [
'email' => ['required', "email:rfc,dns", "unique:customer,email"],
'password' => 'required|min:6|max:32'
];
}
/**
* @notes: 自定义返回消息
* @return string[]
* @author: qiuyang
* @date: 2022/11/21
*/
/* public function messages()
{
return [
'email.required' => '邮箱不能为空',
'password.required' => '密码不能为空',
];
}*/
Models
文件名命名:表名
主要内容
表相关定义
protected $table = 'coupon_fixed';
protected $primaryKey = 'coupon_id';
protected $guarded = [];
const UPDATED_AT = null;
const CREATED_AT = 'date_added';
关联查询
hasOne
hasMany
belongsTo
belongsToMany 等等
注意:常量定义存储在Enums文件 sql查询Repo文件
Services
文件名命名:
模块 + Service
模块 + Service + Interface 接口
例如
Payment.IPayLinksService --IPayLinks支付
Payment.IPayLinksServiceInterface
Payment.MolliePayService --MolliePay支付
Payment.MolliePayServiceInterface
Payment.PayPalService --PayPal支付
Payment.PayPalServiceInterface
Payment.PaymentService --主支付文件
Payment.PaymentServiceInterface
Repo
文件名命名:
表名+Repo
表名+Repo+Interface 接口
例如: CustomerRepo CustomerRepoInterface
主要内容:
增删改查sql
之前存在复杂的sql查询 必须简化控制在3张表之内 主表操作或查询必须是当前Repo 对应其他主表关系拆分到对应的Repo文件中
过多的查询 拆分后可在Services层进行耦合
注意:所有相关Repo 在Services层引用时 定义必须带Repo(防止接口 和 Repo 混乱)
例如: MollieOrderRepoInterface $mollieOrderRepo
Enums 枚举
例如
Customer.CustomerCoupon
Customer.CustomerOperation
ResultCode.php --code返回定义
RedisKeyEnum.php --Redis key 值 Redis项目中必须使用常量
public const ORDER_CREATE_PAY = 'order:pay_order:id_%s';
public const CURRENCY_EXCHANGE_RATE = 'currency:exchange_rate';
Lib 三方扩展
所有三方项目的各种数据方法等等 都在对应文件夹中完成闭环
可参考 vendor下三方封装
提供demo
Dto(数据传输对象)
命名
文件名命名:
模块 + DTO 接口
class MollieOrderLineAmountDto
{
public function __construct(
/**
* 单价
*/
public string $unitPrice,
/**
* 单商品总金额
*/
public string $totalAmount,
/**
* 优惠金额
*/
public string $discountAmount,
/**
* 税费
*/
public string $vatAmountValue,
/**
* 税率
*/
public string $vatRate,
)
{
}
new MollieOrderLineAmountDto(
unitPrice: $unitPrice ?? "0.00",//设置默认值
totalAmount: $totalAmount,
discountAmount: $discountAmount,
vatAmountValue: $vatAmountValue,
vatRate: $vatRate
);
Common
Currency.php 汇率
LanguageAbbr.php 语言
Result.php 统一返回结果
Tools.php 统一公共工具
Exceptions 异常捕获
ApiException 自定义
AppException 自定义
Handler 全局所有的处理
PaymentException
数据 传值 返回 定义
控制器
1 禁止使用$request->all()传值3个以上 或不能确认的统一定义对象传值
服务层
返回值 非数据库直接查询或分页列表 需要定义返回值
#Repo------------------------------------
接收--------------
create array
insert array
改
update array
查
get mixed
first model|null返回类型------------
增
sava bool
create Model
insert bool删
delete int改
update int查
get mixed
first model|null
路由规范
控制器命名 模块+Controller 不要随意附带任何其他自定义进来
路由定义 统一按照模块进行分组
Route::group(["prefix" => 'v1_2/l9', "namespace" => 'App\Http\ApiControllers\v1_1'], function () {
//客户
Route::prefix('customer')->group(function () {
Route::post('register', 'CustomerController@register');
Route::post('login', 'CustomerController@login');
Route::post('logOut', 'CustomerController@logOut');
});
//商品
Route::prefix('product')->group(function () {
Route::get('', 'ProductController@index');
Route::get('product/category', 'ProductController@getCategoryProduct');
});
//分类
Route::prefix('category')->group(function () {
Route::get('', 'CategoryController@index');
Route::get('show'}', 'CategoryController@show');
});
//中间件
Route::group(["middleware" => "auth.api"], function () {
/* Route::prefix('customer')->group(function () {
Route::post('register', 'CustomerController@register');
Route::post('login', 'CustomerController@login');
Route::post('logOut', 'CustomerController@logOut');
});*/
});
});
注意事项:
控制器 :只做接收参数 验证参数 调用模块 可做单一查询的处理
服务层 : 只做业务处理 不做增删改查
Repo :只做数据库操作
model : 数据表的定义 关联查询等等