## 引言 今天老王同学跟我说,他的代码好糟糕,像一坨xiang。问我要怎么 提高自己的代码质量,让自己代码看得顺眼一点,舒服一点, 就像 看到大长腿MM,两眼放光那种。 于是我: 你先这样,然后这样,然后再那样。。。。。。 老王同学: 别闹, 到底是哪样? 好的, 我要开始装13了。。。 ![](https://www.classmatelin.top/images/20210501192044.jpg) ## 基本规范 先说一下最基本的东西: - 变量名使用驼峰命名。不懂的单词不要用拼音,而是要查词典找到对应的单词。 - 常量命名使用大写下划线方式命名。如:`SYSTEM_EROOR = 50000`。 - 缩进使用Tab键,不要打一堆空格做缩进。 - 类名首字母大写驼峰命名,需要见名知其意,注释说明这个类的功能。例如: ![](https://www.classmatelin.top/images/20210501183210.png) - 方法名驼峰命名,方法行数尽量控制在80行左右,注释说明函数干嘛用的。 ![](https://www.classmatelin.top/images/20210501183222.png) - 花括号独占一行,例如: ![](https://www.classmatelin.top/images/20210501183244.png) - foreach慎用引用,例如以下代码会有问题: ![](https://www.classmatelin.top/images/20210501183302.png) 预期结果是输出: `2 4 6`,实际结果是`2 4 4`, 至于为什么可 以看我之前的文章: `PHP中`&符号你真的了解吗?`。 可以使用`array_walk`方法避免这个问题, 示例: ![](https://www.classmatelin.top/images/20210501183323.png) - 避免`if`, `elese`嵌套过深,很多嵌套可以通过提前终止来消除, 举个简单的例子: ![](https://www.classmatelin.top/images/20210501192220.jpg) 建议使用第二种方式,不符合条件的直接返回,剩下的就是符号条件的,那么避免了在if里面写很多代码。 - 多个`if/else`使用switch来替代,PHP8.0版本可以使用`match`更为简洁。 - `phpstorm`中安装`SonarLint`插件。如果你写的代码出现虚线,说明不太理想,那么可以根据提示修改,相信有强迫症的同学一定会改,久而久之代码就很规范了。例如: ![](https://www.classmatelin.top/images/20210501155413.png) 方法未使用,方法名不规范已经告诉你了,可以快捷修改,也可以自己修改。 ## 框架规范 - 前面说得都是比较基础的东西,接下来才是主要的内容。 - 相信很多同学都用过常用的`thinkphp`丶`laravel`丶`yii`等流行框架之一。 - 这些框架都是MVC架构的,看过很多人的代码,要么把业务逻辑写在控制器里面,要么写在Model里面, 写在Model里面相比写控制器里面的还相对好一点。其实对于大型项目都不太友好。 - 下文以Laravel框架为例。 ### 参数验证 - API需要进行参数验证,但是参数验证写在哪里比较优雅呢?可能很多人在controller定义规则,然后在调用验证方法,那么验证那段代码将在每个API里面出现,例如我同事写的。 ![](https://www.classmatelin.top/images/20210501182411.png) 这段代码在每个API里面均会出现一次,岂不是很啰嗦,那么如何解决呢? ![](https://www.classmatelin.top/images/20210501192246.jpg) - 在Laravel的http目录下建立一个`Requsts`目录,用于存放请求的参数验证类。建立一个`BaseRequest`类: ![](https://www.classmatelin.top/images/20210501192311.jpg) 比如登录需要参数验证再建立一个`LoginRequest`类继承这个`BaseRequest`。 ![](https://www.classmatelin.top/images/20210501192328.jpg) - 使用的时候只要在Controller的方法中注入这个请求类即可。 ![](https://www.classmatelin.top/images/20210501192345.jpg) 这里获取请求参数的时候会对表单进行验证,否则参数验证失败会调用刚刚Request积累定义的方法抛Json异常,返回信息给客户端。 ### 控制器 控制器的主要工作负载获取请求数据和返回内容,不应做更多的事情,那么可以定义一个Service层来处理业务逻辑。 所以我的控制器的代码只有一行。 - 在Laravel的app目录下建立一个Services文件夹用于存放Service类,建立一个BaseService类: ![](https://www.classmatelin.top/images/20210501185543.png) 然后建立一个UserService来处理用户相关的业务逻辑。 ![](https://www.classmatelin.top/images/20210501192410.jpg) 在UserController中注入这个UserService使用: ![](https://www.classmatelin.top/images/20210501192424.jpg) ### Model Model不建议写业务逻辑。Model主要是用来定义一些内容,不应该操纵数据。 Model的数据操纵应该放在Repository中,在Laravel的app目录下建立一个文件夹`Repositories`。 定义BaseRepository: ![](https://www.classmatelin.top/images/20210501192440.jpg) 定义UserRepository,用于用户数据相关的操作, 在构造方法中注入UserModel: ![](https://www.classmatelin.top/images/20210501192458.jpg) ### 常量 项目中很多常量该怎么定义? 在app目录创建一个Constant目录, 再建立一个Contstant类来保存这些自定义常量。 这样的好处是: - 自定义常量可以集中的管理。 - 修改常量值的时候,只需要在这个类中找修改一次即可,代码更新维护性好。 ![](https://www.classmatelin.top/images/20210501191452.png) ## 附录 ![](https://www.classmatelin.top/images/20210501192520.jpg)