前言
关于规范
目的
- 提供更加高质量的软件交付。
- 实现团体智慧的延续和精进(工作总结,开发效率、程序执行效率、扩展性和安全性的最佳实践)。
优势
- 高效编码:避免了过多的选择;
- 风格统一:最大程度统一了开发团队成员代码书写风格和思路;
- 减少错误:减小初级工程师的犯错几率。
开发哲学
- 不写重复的逻辑代码;
- 优先选择框架提倡的做法,不过度配置;
- 提倡简单易读,不写高深、晦涩难懂的代码,不过度设计;
- 让有经验的人来为你选择方案,不独创方案;
- 优先选择官方推崇的方案。
过于灵活是一件糟糕的事情
对于框架设计来说,灵活能提供给开发者不同的选项,适用更多的用户场景。但对于团队协同开发,大部分时候更多的选项反而是累赘。
假如你在为项目开发 用户授权 相关功能,仅 注册用户权限 这块你就会有以下三个选项:
- 选项 1. 使用闭包
- 选项 2. 自定义类方法
- 选项 3. Policy 授权策略类
没有规范的情况下,开发者会根据各自的喜好去选择,会造成整个团队产出的代码可读性极低,代码结构混乱,也为后面的项目代码的维护带来了难度。
项目规范
Laravel 版本选择
商业项目
建议选择 LTS 长期支持版。
个人项目
推荐使用最新版的 Laravel。
例如安装laravel 6.x:
composer create-project --prefer-dist laravel/laravel local.blog.com "6.*"
开发和线上环境
环境说明
一般情况下,一个项目应该有以下三个基本的项目环境:
- 开发环境
- 线上测试环境
- 线上生产环境
开发环境
使用域名 .test 作为后缀;
使用 本地host解析test域名
线上测试环境
除了域名等其他独立应用配置以外,环境 必须 跟 Production 保持高度一致性,可以的话 应该 与 Production 使用同台机器。
线上生产环境
适当的性能调优和安全优化,只开放必要的端口(80,443)。如果业务需要可以开启其他端口,例如22但要做好安全工作。
当然注释统一,代码格式化统一等也是很重要的。
使用软件
服务器系统
应该优先考虑 Ubuntu,并且是 LTS 支持的系统。
PHP
优先考虑 PHP7+,低的版本将会很快停止维护。
MySQL
优先考虑 MySQL 5.7。
其他软件
优先选择流行稳定版本。线上环境绝不使用Beta或者其他不稳定发行版。
开发专用扩展包
有一些扩展包是开发环境中专用,生产环境中并不会使用到,为了避免无用的负载, 必须严格控制其安装和加载。
安装
安装开发专用扩展包时 必须 使用 --dev 参数
composer require laracasts/generators --dev
加载
根据环境动态载入,演示代码
public function register()
{
if ($this->app->environment() == 'local') {
$this->app->register('Laracasts\Generators\GeneratorsServiceProvider');
}
}
配置信息与环境变量
问题说明
假如我们有个配置项,在 Laravel 中有以下几种方法:
- 写死在代码中。
- 写死在 config/app.php 文件中。
- 存储于 .env 文件中,使用 env() 方法直接读取。
- 存储在 .env 和 config/app.php 文件中,然后使用 config() 函数来读取。
第一种方法
代码可维护性极低,一旦配置变更就只能全局替换。
第二种方法
无法区分环境,例如本地使用开发环境配置,线上需要正式环境配置。
第三种方法
虽解决了环境变量的问题,也具备一定的灵活性,但是不够灵活,随着项目快速迭代。.env文件会变大,难以维护。
第四种方法
既支持环境变量,又具备极高的灵活性,假如遇到同样的 CDN 多域名随机问题,你只需要写一个辅助方法,然后在 config/app.php 中调用即可,不需要动到任何一行业务逻辑代码。
代码示例一
将配置写入.env
每个环境的 .env
文件内容各不相同,.env
文件中设置:
CDN_DOMAIN=cdndomain.com
config/app.php 文件中设置:
'cdn_domain' => env('CDN_DOMAIN', null)
程序中两种获取 相同配置 的方法:
env('CDN_DOMAIN')
config('app.cdn_domain')
代码示例二
将配置存入代码库
.env 文件中设置:
# 开发环境
CDN_DOMAIN=develop
# 预发布
CDN_DOMAIN=beta
# 生产环境
CDN_DOMAIN=stale
config/app.php 文件结构变为如下:
config/packages/cdn/develop.php
config/packages/cdn/beta.php
config/packages/cdn/stale.php
通过env('CDN_DOMAIN')
拿到当前运行环境,自动载入不同的配置,这里不再描述。
辅助函数
必须 把所有的『自定义辅助函数』存放于 app 文件夹中。并在 composer.json 文件中加载(非必须方式)。
也可以根据功能特性分为多个文件,但是代码风格,注释描述保持团队规范。
# 写入描述文件
{
...
"autoload": {
"files": [
"app/helpers.php"
]
}
...
}
# 自动加载
composer dump-autoload
项目文档
1 推荐使用markdown
格式
2 模板风格保持统一
3 描述内容尽量丰富:描述、运行环境、环境安装、架构说明,对接方式等等。
工具统一
硬件、系统、IDE、编辑器代码格式化、代码风格检测工具、命令行工具:iTerm2、浏览器:Chrome、虚拟机或容器、MySQL GUI、Redis GUI、MongoDB GUI、设计工具、zsh配置等信息。
编码规范
codeigniter
phpDocumentor
sonarphp
PSR
Google Python Style Guide
Python PEP8
ESLint
Uber Go 编码规范
等等。
其他
安全实践
- 关闭
DEBUG
模式。 -
XSS
,用户输入文本进行转义。 -
SQL
注入,采用PDO
扩展。 - 批量赋值,更新字段白名单
Auth::user()->update(Request::all());
会更新所有符合条件的table字段。 -
CSRF
,必要条件默认对所有『非幂等的请求』强制使用VerifyCsrfToken
中间件防护。
程序优化
1. 配置信息缓存
php artisan config:cache
缓存文件存放在 bootstrap/cache/
文件夹中。
取消配置信息缓存
php artisan config:clear
注意
配置信息缓存不会随着更新而自动重载,所以,开发时候建议关闭配置信息缓存,一般在生产环境中使用。
每次上线代码时执行 config:clear
命令。
** 2. 路由缓存**
生产环境中的 应该 使用『路由缓存』来加速 Laravel 的路由注册。
php artisan route:cache
缓存文件存放在 ·
bootstrap/cache/` 文件夹中。
另外,路由缓存不支持路由匿名函数编写逻辑。
清除路由缓存:
php artisan route:clear
注意
路由缓存不会随着更新而自动重载,所以,开发时候建议关闭路由缓存,一般在生产环境中使用。
每次上线代码时执行 route:clear
命令。
** 3. 类映射加载优化**
optimize 命令把常用加载的类合并到一个文件里,通过减少文件的加载,来提高运行效率。生产环境中的 应该 使用 optimize 命令来优化类的加载速度:
php artisan optimize {--force}
会在 bootstrap/cache/
文件夹中生成缓存文件。
你可以通过修改 config/compile.php
文件来添加要合并的类。在 production 环境中,参数 --force 不需要指定,文件就会自动生成。
清除类映射加载优化:
php artisan clear-compiled
此命令会删除上面 optimize 生成的两个文件。
注意:
此命令要运行在 php artisan config:cache
后,因为 optimize 命令是根据配置信息(如:config/app.php 文件的 providers 数组)来生成文件的。
4. 自动加载优化
适用于所有使用 composer 来构建的程序。
此命令会把 PSR-0 和 PSR-4 转换为一个类映射表,来提高类的加载速度。
composer dumpautoload -o
注意: php artisan optimize --force
命令里已经做了这个操作。
5 介入
NOSQL
数据库
Redis、Memcache、Rethinkdb
6 程序层面优化
- 采用新的稳定的laravel,php版本
- 冷热数据分离
- 缓存热点数据
- 数据库优化(SQL,索引,设计,硬件,配置,存储,结构压缩)
- 精简框架(例如无用中间件,无用第三方包)
- 采用高性能的cache驱动
- 耗时任务处理: 异步执行任务,优化长耗时的http任务交互方式,例如推拉模型,发布订阅模型,队列系统介入
- 耗时监控:(SQL,HTTP,RPC,UI,Download等)
- 对于静态资源也要有针对性的处理(例如压缩,CDN托管),这里不叙述.
参考:
https://learnku.com/docs/laravel-specification/5.5