shipfi

Add Rules

1 +## 数据库和表设计规范
2 +
3 +### 1. 数据库设计规范
4 +
5 +#### 1.1 命名规范
6 +
7 +* 对象名(表、列、函数、视图、序列),一律只使用小写字母,下划线、数字。不以数字开头,不使用保留字。对象名不体现复数的概念,所以名字不以s/es结尾。
8 +
9 + > 表定义示例: ev_return_good / ev_user
10 +
11 +* 表的字段列名,一律只使用小写字母、下划线、数字。
12 +
13 +* 表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 unsigned tinyint
14 + ( 1 表示是,0 表示否)。
15 +
16 +* 删除标志字段,统一使用 del_flag。
17 +
18 +* 命名禁止两个下划线中间只出现数字
19 +
20 +* 创建索引以idx_开头,创建唯一索引以uk_开头.
21 +
22 +* 临时表以tmp_开头。
23 +
24 +* 数据库名以应用或者部门简写为前缀,例如qi_,ev_等
25 +
26 +
27 +
28 +#### 1.2 SQL设计规约
29 +
30 +* 表默认使用InnoDB,表字符集默认使用utf-8
31 +
32 +* 所有表必备三字段: xx_id | created_at | updated_at字段。其中created_at/updated_at字段的nullable=yes
33 +
34 +* 所有的表必须定义主键,主键定义规则如下:
35 +
36 + > ev_site => site_id
37 + >
38 + > ev_site_brand => sb_id
39 + >
40 + > ev_spc_discount => sd_id
41 + >
42 + > ev_spc_delay => sd_id
43 +
44 +* 外键的关联字段设计,关联的字段一定要相同,以group和site为例:
45 +
46 + > ev_group => **group_id** | group_name | ...
47 + >
48 + > ev_site => site_id | **group_id** | site_name | ...
49 +
50 +* 表字段被索引列必须定义为not null,并设置default值
51 +
52 +* 除非特殊需要,才将字段定义为null, 否则,将字段定义为非null, 并设置默认值。
53 +
54 +* 所有表主键都是int并自增性,禁止使用varchar类型作为主键。
55 +
56 +* 小数类型为 decimal,禁止使用 float 和 double。
57 +
58 +* varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长
59 + 度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索
60 + 引效率。
61 +
62 +* 每个表字段都需要有注释。如果是枚举类型的字段,必须存在每种枚举的注释。
63 +
64 +* 表修改时必须有修改日志记录。
65 +
66 +* 业务上具有唯一特性的字段,即使是组合字段,也**必须**建成唯一索引。
67 +
68 +* 超过三个表禁止 join
69 +
70 +* 在 varchar 字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据
71 + 实际文本区分度决定索引长度即可。
72 +
73 +* 以下设计规约来自阿里:
74 +
75 + * 不要使用 count(列名)或 count(常量)来替代 count(\*)。count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。
76 + * 使用 ISNULL()来判断是否为 NULL 值。注意:NULL 与任何值的直接比较都为 NULL
77 + * 不得使用外键与级联,一切外键概念必须在应用层解决。
78 + * 禁止使用存储过程,存储过程难以调试和扩展,更没有移植性。
79 + * in 操作能避免则避免,若实在避免不了,需要仔细评估 in 后边的集合元素数量,控
80 + 制在 1000 个之内
81 +
82 +
83 +
84 +#### 1.4 Model定义规约
85 +
86 +* Model继承自自定义的BaseModel.
87 +
88 +* Model的命名是表名去除前缀和下划线的大驼峰写法
89 +
90 + ```php
91 + // 表名 : ev_group_discount
92 + class GroupDiscount extends BaseMode { }
93 + ```
94 +
95 +* 除了作为基类的Model如BaseModel, 其它表映射的Model都需要定义\$table\$primaryKey 变量
96 +
97 + ```php
98 + class APIManager extends BaseModel {
99 + protected $table = 'api_manager';
100 + protected $primaryKey = 'am_id';
101 + }
102 + ```
103 +
104 +* 所有的插入操作,必须更新created_at / updated_at 字段
105 +
106 +* 所有的更新操作,必须更新updated_at字段.
107 +
108 +* 在应用的查询中,一律不使用 * 作为查询的字段列表。有哪些字段必须明确写明。
...\ No newline at end of file ...\ No newline at end of file
1 +## GIT FLOW规范
2 +
3 +### 1. GIT FLOW 规范
4 +
5 +项目永远存在两个分支
6 +
7 +* 主分支master
8 +* 开发分支 develop
9 +
10 +对于master分支,任何时候这个分支拿到的,都是稳定发布版。
11 +
12 +而develop分支,存放的是最新的开发版。
13 +
14 +
15 +
16 +其中,项目中存在四种短期分支
17 +
18 +* 功能分支 (feature branch)
19 +* 补丁分支(hotfix branch)
20 +* 测试bug分支(bug branch)
21 +* 预发分支(release branch)
22 +
23 +一旦开发完成,以上分支会被合并到develop/master,然后删除
24 +
25 +
26 +
27 +对于版本发布的项目,每有一个稳定的版本,都要从master上打出一个版本,版本号按产品进行定义。
28 +
29 +在master分支上,在新的功能增加前,只有hotfix,才允许将代码合并到这个分支,合并后,要更新小版本号。
30 +
31 +
32 +
33 +### 2. 提交Commit
34 +
35 +提交commit,一定要给出完整扼要的提交信息。项目经理需要检查提交的信息是否足够。每个成员也需要确保自己的提交信息完整。提交信息如下所示:
36 +
37 +```
38 +Present-tense summary under 50 characters
39 +
40 +* More information about commit (under 72 characters).
41 +* More information about commit (under 72 characters).
42 +
43 +http://project.management-system.com/ticket/123
44 +```
45 +
46 +一个正式的提交功能的注释:
47 +
48 +```
49 +HOTFIX3001(UserController|CacheListener) : 解决了头部Cache没有引入的问题
50 +
51 +1. UserController头部没有引入Cache包导致异常
52 +2. CacheListener Log去除
53 +
54 +http://chandao.runsa.cn:8604/pro/bug-view-3001.html
55 +
56 +```
57 +
58 +不建议通过git commit命令提交,而是建议通过SourceTree或者git cz命令进行提交。
59 +
60 +关于git cz命令,查看: [Git Commit](https://mp.weixin.qq.com/s?__biz=MzAwNDYwNzU2MQ==&mid=401622986&idx=1&sn=470717939914b956ac372667ed23863c&scene=2&srcid=0114ZcTNyAMH8CLwTKlj6CTN&from=timeline&isappinstalled=0#wechat_redirect)
61 +
62 +
63 +
64 +### 3. 使用git rebase代替git merge
65 +
66 +当多个分支并行发展,需要合并时,使用rebase功能进行合并,这样在SourceTree跟踪代码变更时,会更清晰易懂。
67 +
68 +
69 +
70 +### 4. 其它
71 +
72 +git分支管理流程可以查看:
73 +
74 +[Git flow 開發流程](https://ihower.tw/blog/archives/5140)
75 +
76 +[GIT分支管理策略](http://www.ruanyifeng.com/blog/2012/07/git.html)
77 +
1 ## LUMEN+API Service规范 1 ## LUMEN+API Service规范
2 2
3 +这里的Service其实包含了两层意义,一种表示的是业务逻辑处理(Service)层,一种是表示通用处理(Manager)层。
4 +
5 +应用层之间的关系如下:
6 +
7 +![](http://of2xnjf2g.bkt.clouddn.com/20170330154524.png)
3 8
4 ### 1. Service规范 9 ### 1. Service规范
5 10
...@@ -8,14 +13,16 @@ ...@@ -8,14 +13,16 @@
8 * Service一般实现包括以下几个方面: 13 * Service一般实现包括以下几个方面:
9 14
10 * 封装用户的权限验证 15 * 封装用户的权限验证
11 - * 封装一些基本操作,如通过curl实现HttpGet,HttpPost、通过Cache实现CacheManager、通过Log实现LogService等。 16 + * 封装一些基本操作,如通过curl实现HttpGet,HttpPost、通过Cache实现CacheManager、通过Log实现LogManager等。
12 * 封装了与其它系统交互的细节,如CRMService, PortalService, SCService等。 17 * 封装了与其它系统交互的细节,如CRMService, PortalService, SCService等。
13 18
14 * 一般简单的工具类,文件存放在app\Libraray中。 19 * 一般简单的工具类,文件存放在app\Libraray中。
15 20
16 * 其它具体的提供服务类,文件存放在app\Service中。 21 * 其它具体的提供服务类,文件存放在app\Service中。
17 22
18 -* 服务不依赖于上层Controller/Model类,按照约定,服务可以在不同项目中复用。 23 +* 通用处理不依赖于上层Controller/Model类,按照约定,通用处理可以在不同项目中复用。
24 +
25 +* 设计服务层时,避免层和层之间互相依赖的关系。一般来说层次结构是 Controller -> Model -> Service,或者Controller -> Service -> Model
19 26
20 * 在应用中,服务的日志需要独立。 27 * 在应用中,服务的日志需要独立。
21 28
......
...@@ -12,8 +12,6 @@ ...@@ -12,8 +12,6 @@
12 12
13 ### 1. 代码规范 13 ### 1. 代码规范
14 14
15 -
16 -
17 ##### 1.1 文件夹命名 15 ##### 1.1 文件夹命名
18 16
19 * 如果有框架定义,则文件夹命名统一按照框架制定的规则,如果框架不定义,则统一使用小写字母。 17 * 如果有框架定义,则文件夹命名统一按照框架制定的规则,如果框架不定义,则统一使用小写字母。
...@@ -21,7 +19,6 @@ ...@@ -21,7 +19,6 @@
21 > 以Lumen为例,项目下的第一级目录全部以小写字母命名。除app文件夹外,其它目录也是全部使用小写字母命名。 app目录下文件夹统一使用首字符大写命名。 19 > 以Lumen为例,项目下的第一级目录全部以小写字母命名。除app文件夹外,其它目录也是全部使用小写字母命名。 app目录下文件夹统一使用首字符大写命名。
22 20
23 21
24 -
25 --- 22 ---
26 23
27 24
...@@ -79,18 +76,17 @@ ...@@ -79,18 +76,17 @@
79 ``` 76 ```
80 77
81 78
82 -
83 --- 79 ---
84 80
85 81
86 82
87 ##### 1.3 变量命名 83 ##### 1.3 变量命名
88 84
89 -* 全局变量命名使用大驼峰,前缀加上_,所有单词首字母大写。 85 +* 全局变量命名使用大驼峰,前缀加上G_, 所有单词首字母大写。
90 86
91 -* 常量统一使用大写,中间分隔使用_ 87 +* 常量统一使用大写,中间分隔使用_,力求语义表达完整清楚,不要嫌名字长。
92 88
93 -* 私有变量命名小驼峰,前缀加上_ 89 +* 私有变量命名小驼峰
94 90
95 * 变量命名确认以英文名词为主。 91 * 变量命名确认以英文名词为主。
96 92
...@@ -102,16 +98,16 @@ ...@@ -102,16 +98,16 @@
102 98
103 ```php 99 ```php
104 // 全局变量 100 // 全局变量
105 - $_System_Config = config('myconfig'); 101 + $G_System_Config = config('myconfig');
106 - $_Root_Path = '/'; 102 + $G_Root_Path = '/';
107 103
108 // 常量 104 // 常量
109 define('CURRENT_SCRIPT','index_php'); 105 define('CURRENT_SCRIPT','index_php');
110 const TRANSCATION_TYPE = 'income'; 106 const TRANSCATION_TYPE = 'income';
111 107
112 // 私有变量(protected不在此列) 108 // 私有变量(protected不在此列)
113 - private $_orderCnt = 0; 109 + private $orderCnt = 0;
114 - protected $_salaryAmount = 0; 110 + protected $salaryAmount = 0;
115 111
116 /** 112 /**
117 * 我的订单列表 113 * 我的订单列表
...@@ -127,24 +123,24 @@ ...@@ -127,24 +123,24 @@
127 ``` 123 ```
128 124
129 125
130 -
131 --- 126 ---
132 127
133 128
134 129
135 -##### 1.4 类、方法、对象命名 130 +##### 1.4 类、方法、对象
136 131
137 * 类统一使用大驼峰形式命名,与文件名必须保持一致。 132 * 类统一使用大驼峰形式命名,与文件名必须保持一致。
138 * 自编写的类一般遵循名词或名词短语来进行命名。 133 * 自编写的类一般遵循名词或名词短语来进行命名。
139 -* 框架中的一些类的命名参考 ()
140 * 类的动作方法 ,一般使用【动词+名词】方式进行命名,例如 sendMessage / getAttr / setAttr / postLogin等 134 * 类的动作方法 ,一般使用【动词+名词】方式进行命名,例如 sendMessage / getAttr / setAttr / postLogin等
141 * 类的属性和变量字段,使用小写字母或者小写驼峰方式命名 135 * 类的属性和变量字段,使用小写字母或者小写驼峰方式命名
142 * 类的private字段和方法,**必须**使用带_前缀的方式命名 136 * 类的private字段和方法,**必须**使用带_前缀的方式命名
143 * 常量值,统一使用大写。 137 * 常量值,统一使用大写。
138 +* 如果方法为API由外部调用,不允许修改方法签名,避免对接口调用方产生影响。
139 +* 所有继承的覆写方法,必须加@Override 注解
140 +* 接口过时必须加@deprecated 注解,并清晰地说明采用的新接口或者新服务是什么
144 * [PHP自定义类示例参考](Samples/my_class_sample.md) 141 * [PHP自定义类示例参考](Samples/my_class_sample.md)
145 142
146 143
147 -
148 --- 144 ---
149 145
150 146
...@@ -155,6 +151,21 @@ ...@@ -155,6 +151,21 @@
155 151
156 * 所有的类、函数、方法定义都需要进行注释。 152 * 所有的类、函数、方法定义都需要进行注释。
157 153
154 +* 类、方法、函数统一使用/** 内容 */ 注释格式, 不得使用 //** 方式
155 +
156 +* 方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释,注意与代码对齐。
157 +
158 +* 与其“半吊子”英文来注释,不如用中文注释把问题说清楚。专有名词与关键字保持英文原文即可。
159 +
160 +* 代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑等的修改。
161 +
162 +* 好的命名、代码结构是自解释的,注释力求精简准确、表达到位。避免出现注释的一个极端:过多过滥的注释,代码的逻辑一旦修改,修改注释是相当大的负担。
163 +
164 +* 两个特殊注释标记的注释格式 : TODO / FIXME
165 +
166 + * TODO : 待办事宜(TODO):( 标记人,标记时间,[预计处理时间]
167 + * FIXME : 错误,不能工作(FIXME):(标记人,标记时间,[预计处理时间]
168 +
158 * 一般php注释遵循phpdocumentor规范, [phpdocumentor](https://phpdoc.org/docs/latest/references/phpdoc/index.html) 169 * 一般php注释遵循phpdocumentor规范, [phpdocumentor](https://phpdoc.org/docs/latest/references/phpdoc/index.html)
159 170
160 * 如果是API的接口,则提供PHP APIDOC的相关注释 [APIDOC](https://github.com/calinrada/php-apidoc) 171 * 如果是API的接口,则提供PHP APIDOC的相关注释 [APIDOC](https://github.com/calinrada/php-apidoc)
...@@ -215,13 +226,25 @@ ...@@ -215,13 +226,25 @@
215 ``` 226 ```
216 227
217 228
218 -
219 --- 229 ---
220 230
221 231
222 232
223 ##### 1.6 代码和语句 233 ##### 1.6 代码和语句
224 234
235 +* if/else/for/while/do 语句中必须使用大括号,即使只有一行代码.
236 +
237 +* 大括号的使用约定。如果是大括号内为空,则简洁地写成{}即可,不需要换行.
238 +
239 +* 左括号和后一个字符之间不出现空格;同样,右括号和前一个字符之间也不出现空格
240 +
241 + ```php
242 + ($age > 18)
243 + ```
244 +
245 +
246 +* 任何运算符左右必须加一个空格。运算符包括赋值运算符=、逻辑运算符&&、加减乘除符号、三目运算符等
247 +
225 * 两元运算符,前后使用空格 248 * 两元运算符,前后使用空格
226 249
227 ```php 250 ```php
...@@ -248,6 +271,14 @@ ...@@ -248,6 +271,14 @@
248 271
249 * 每行代码长度应控制在80个字符以内,最长不超过120个字符, 如超过则另起一行 272 * 每行代码长度应控制在80个字符以内,最长不超过120个字符, 如超过则另起一行
250 273
274 + > 运算符与下文一起换行。
275 + >
276 + > 方法调用的 -> 符号与下文一起换行。
277 + >
278 + > 在多个参数超长,逗号后进行换行。
279 + >
280 + > 在括号前不要换行, 如 append \n ("---");
281 +
251 ```php 282 ```php
252 $qyAuthAppGrpIns = (new QyAuthAppGrp())->getInstanceBySuiteNameCorpId( 283 $qyAuthAppGrpIns = (new QyAuthAppGrp())->getInstanceBySuiteNameCorpId(
253 $suiteName, 284 $suiteName,
...@@ -257,6 +288,14 @@ ...@@ -257,6 +288,14 @@
257 288
258 * 每行结尾不允许有多余空格 289 * 每行结尾不允许有多余空格
259 290
291 +* 方法参数在定义和传入时,多个参数逗号后边必须加空格。
292 +
293 + ```php
294 + method('a', 'b', 'c');
295 + ```
296 +
297 + ?
298 +
260 * 在类中(尤其是在Model),对于每个属性的访问, 统一使用get/set方法 299 * 在类中(尤其是在Model),对于每个属性的访问, 统一使用get/set方法
261 300
262 ```php 301 ```php
...@@ -312,7 +351,7 @@ ...@@ -312,7 +351,7 @@
312 351
313 * 每个 php 文件只允许声明一个类。 352 * 每个 php 文件只允许声明一个类。
314 353
315 -* 任何类变量的声明都**必须**放在类顶部,先于任何函数的声明。 354 +* 任何类变量的声明都**必须**放在类顶部,先于任何函数的声明。
316 355
317 * 类中的方法必须总是用 private,protected 或者 public 来声明其作用域。 356 * 类中的方法必须总是用 private,protected 或者 public 来声明其作用域。
318 357
...@@ -324,13 +363,28 @@ ...@@ -324,13 +363,28 @@
324 } 363 }
325 ``` 364 ```
326 365
327 -* 代码做到复用,对于相同听代码逻辑,严禁出现在两个函数或者两个文件内,如果逻辑相同,使用重构提取共用性。 366 +* 代码做到复用,对于相同听代码逻辑,严禁出现在两个函数或者两个文件内,如果逻辑相同,使用重构提取共用性。必要时抽取共性方法,或者抽象公共类,甚至是共用模块。
328 367
329 * 一个函数的逻辑实现**严禁**超过一屏(非常特殊或者逻辑简单可理解的除外)。如果业务复杂,使用多个函数实现。 368 * 一个函数的逻辑实现**严禁**超过一屏(非常特殊或者逻辑简单可理解的除外)。如果业务复杂,使用多个函数实现。
330 369
331 -* 一个函数中**不能**出现以下复杂的if/else逻辑判断, 简单规则,每个函数只允许一个if/elseif/else嵌套层。 370 +* 不要在条件判断中执行其它复杂的语句
371 +
372 + ```php
373 + if ((file.open(fileName, "w") != null) && (...) || (...)) { } // ERROR
374 +
375 + // RIGHT
376 + $existed = (file.open(fileName, "w") != null) && (...) || (...);
377 + if ($existed) { /*...*/ }
378 + ```
379 +
380 + ?
381 +
382 +* 一个函数中**不能**出现以下复杂的if/else逻辑判断, 一个规则,每个函数只if/elseif/else嵌套不超过三层。
383 +
384 +* 逻辑上超过 3 层的 if-else 代码可以使用卫语句或状态模式来实现,关于 [卫语句](http://blog.csdn.net/jw903/article/details/45506777)。
332 385
333 ```php 386 ```php
387 +
334 if($condition1) { 388 if($condition1) {
335 if($condition2) { 389 if($condition2) {
336 // do sth 390 // do sth
...@@ -346,7 +400,6 @@ ...@@ -346,7 +400,6 @@
346 ``` 400 ```
347 401
348 402
349 -
350 --- 403 ---
351 404
352 405
...@@ -399,9 +452,42 @@ ...@@ -399,9 +452,42 @@
399 452
400 --- 453 ---
401 454
455 +##### 1.8 日志
456 +
457 +* 需要提供统一的日志SDK,作日志API的调用,(现暂时没有)
458 +
459 +* 日志 命名方式:appName_logType_logName.log。
460 +
461 + logType : 推荐的分类有 : stats / desc / monitor /visit , 通过这些类型命名,有利于归类查找。
462 +
463 +* 对日志进行分类,错误日志和业务日志尽量分开存放,便于开发人员查看,也便于通过日志对系统进行及时监控。
464 +
465 +* 生产环境禁止输出 debug 日志;有选择地输出 info 日志;如果使用 warn 来记录刚上线时的业务行为信息,一定要注意日志输出量的问题
466 +
467 +* 以使用 warn 日志级别来记录Request请求时用户输入参数错误的情况。
468 +
469 +* 注意日志输出的级别,error 级别只记录系统逻辑出错、异常等重要的错误信息。
470 +
471 +
472 +
473 +---
474 +
475 +
476 +
477 +##### 1.9 异常
402 478
479 +* 异常不要用来做流程控制,条件控制.
480 +* 不想处理异常,请将该异常抛给它的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的内容。
481 +* 不能在 finally 块中使用 return。finally 块中的 return 返回后方法结束执行,不会再执行 try 块中的 return 语句。
482 +* 在应用代码中使用“抛异常”代替“返回错误码”,应用如果是API,则对异常作出处理,返回匹配的Result结果信息。
403 483
404 -##### 1.8 其它 484 +
485 +
486 +---
487 +
488 +
489 +
490 +##### 1.10 其它
405 491
406 * 对API接口和复杂的返回数据,必须进行注释。以能够在代码中准确的了解接口所实现的功能、接口所接收的数据、接口所返回的数据。 492 * 对API接口和复杂的返回数据,必须进行注释。以能够在代码中准确的了解接口所实现的功能、接口所接收的数据、接口所返回的数据。
407 ![](http://of2xnjf2g.bkt.clouddn.com/20170329172557.png) 493 ![](http://of2xnjf2g.bkt.clouddn.com/20170329172557.png)
...@@ -409,4 +495,5 @@ ...@@ -409,4 +495,5 @@
409 ![](http://of2xnjf2g.bkt.clouddn.com/20170329172345.png) 495 ![](http://of2xnjf2g.bkt.clouddn.com/20170329172345.png)
410 * 未完成的功能使用TODO标记,如果函数接口层已经定义好,则在函数体内抛出暂时无法实现的异常 496 * 未完成的功能使用TODO标记,如果函数接口层已经定义好,则在函数体内抛出暂时无法实现的异常
411 ![](http://of2xnjf2g.bkt.clouddn.com/20170329172942.png) 497 ![](http://of2xnjf2g.bkt.clouddn.com/20170329172942.png)
412 -* ?
...\ No newline at end of file ...\ No newline at end of file
498 +
499 + ?
...\ No newline at end of file ...\ No newline at end of file
......