您现在的位置:首页 > >

Laravel / Lumen 实践总结

发布时间:

2019独角兽企业重金招聘Python工程师标准>>>



不要造轮子

业务*挥Ω煤脑诼肿又圃焐


典型、常见的功能首先考虑Laravel框架是否已有实现,其次搜索开源的轮子Composer兴起:PHP进入现代化开发阶段、大家可以共享优秀的轮子使用现成的轮子
框架内置的轮子:适度定制满足业务,以后框架升级最为方便大牛开源的轮子:功能丰富、架构规范、拓展性强、文档完善、持续维护!!

现成轮子不满足部分需求或有Bug?


不要直接修改!!vendor目录下框架内部组件第三方包
造成包无法进行后续更新Compser重装vendor包后,定制修改将会丢失新建逻辑分层进行定制(比如Libraries目录)
    目录结构组织参照vendor下的原始实现类extends原始实现类覆盖需要定制的方法,或者直接implements其整个Constract约定在业务逻辑中(而不是vendor目录)替换为自定义类

几个轮子参考站点


Laravel专属包搜索:http://packalyst.comComposer官方搜索:https://packagist.orgGithub搜索:https://github.comLaravel一些开源项目:http://openlaravel.comSpatie开源的Laravel项目:https://spatie.be/en/opensource/laravelPHP优秀包联盟:http://thephpleague.com
Laravel主流分层思想

系统架构需要逻辑分层,每个分层遵循单一职责原则


Web分层


Controller层作为业务逻辑的总调度,可注入ServiceRepositoryService层辅助Controller层,抽象复杂业务逻辑、抽象公共服务、处理第三方功能调用等Repository层具体处理CURDSQL业务、第三方数据调用等资源操作逻辑,可注入Model
需要面向接口开发, 依照接口声明处理 DB、Cache、Api等实现Model层作为业务实体,处理常量定义关联关系配置定义View层处理视图展现

Api分层


1. 业务:Dingo路由 + Controller调度 + Service业务逻辑 -> Transformer数据修饰输出

2. 数据逻辑:Query过滤参数&Repository查询 + Hydrator数据校验并存储 -> Policy鉴权策略

3. 数据:Model(域、常量、关联) + Migration、Factory、Seeder

4. 配置:Config配置 > ENV环境变量

*. 其它:Test(状态码、数据结构、过滤条件)

Laraval权限分层

1. 顶层基于Auth中间件的用户身份认证
2. 主体**基于角色**的RBAC权限架构设计
- 基于角色分类组织权限节点
- 决定某个角色能使用什么功能、能做什么操作
3. 底层**基于用户**的鉴权
* 基于Gate的资源无关操作鉴权
- 鉴权用户能否某种操作,一般与资源实例无关
- 定义了单一权限节点的鉴权逻辑
* 基于Policy的Model实例资源鉴权
- 鉴权用户能否对Model实例资源进行某种操作
- 封装资源的多个权限节点鉴权逻辑于一个策略中,并与Model绑定

错误和异常处理

使用异常的好处


不用针对正常、错误的返回而使用类似[status=>sucees, data => $data]这种结构业务中引入异常体系后,逻辑更加语义化

异常处理原则


业务设计之内的异常,自己抛出自己捕获处理
正常场景就返回数据, 错误场景就抛出异常抛出的异常在外层业务进行捕获并进一步处理业务设计以外的异常, 自己未能捕获,冒泡至Handler顶层异常处理器处理异常基类
需要显示的异常继承自SymfonyComponentHttpKernelExceptionHttpException业务逻辑中组织的异常继承自Exception、RuntimeException等

错误日志系统


典型的报错日志系统(有缺陷
日志源抓取 Laravel StorageLogPHP error.logNginx error.log只提供错误点的调用栈信息缺少当时场景的关键信息,调试排错困难使用Laravel顶层异常处理器衔接报错日志系统推荐
PHP7下所有ErrorException都是Throwalbe接口的实现,均可被Catchreport()方法中进行异常上报可实现当时场景关键上下文信息串联,提高排查效率
当时的用户对象当时完整的用户请求数据当时的异常堆栈信息
依赖注入

自动依赖注入 常用于容器自动注入空Model实体对象业务逻辑模块


构造函数注入public function __construct(User $user)接口注入
控制器方法中:public function index(Request $request)队列Jobhandle()方法中:public function handle(MailService $mailService)等等

手工依赖注入 常用于手工注入具化Model实体对象同接口下 不同的业务模块实现


Set注入public function setUser(User $user);

使用场景区别举例

查询场景下 - 自动依赖注入
通过构造函数来注入空Model实体通过空Model实体发起newQuery进行查询更新场景下 - 手工依赖注入
通过Setter来注入具化Model实体idRepository注入的具化Model实体将作为数据更新目标
集成测试
即便做不到TDD,至少粗粒度上的集成测试来保证接口可用性,避免人工测试的困难核心逻辑模块可以考虑更细粒度的单元测试

1. 指定测试方法 `phpunit --filter clsTest::testMethod`
2. 测试临时忽略指定检查,添加注解 @SupressWarnings("规则名")
3. 测试覆盖范围
- 常规场景数据返回: 数据 & 结构 & 状态码
- 异常场景数据返回:数据不存在
- 所有过滤字段
- 分页功能:指定分页 & 单页条数
- 数据录入 & 更新 正常

遇过的坑

连不上mysql容器实例,找不到host,无法完成migrate迁移操作
需要在宿主机下做哥容器hostname的host解析

factory数据异常 考虑*鬱ocker容器

factory中faker一个datetime数据时, 留意给出format格式

进入tinker交互式环境后代码更新没有及时展现出来
tinker将以进入环境时内存中的代码逻辑来运转,后期代码的更新不会在tinker环境中生效

删除某个文件后, 程序运行报错类不存在
删除composer缓存文件,composer dumpautoload --optimize

集成测试时的测试数据准备
需要留意, 除了主体测试数据需要准备外,还需要准备关联数据

报错调试
查看报错信息一定从框架自带日志着手, 因为报错细节已被框架截获转发到自带日志上, php日志及程序返回中已抹除报错细节

Transformer里留意数字类型字段输出的强制类型转换

如果migration操作涉及到SQLite驱动,则务必将每个字段调整封装进单独一个Schema闭包中,否则将出现各种异常

宿主机测试通过,容器内不通过, 错误提示信息是类不存在。


检查命名空间检查文件名路径
PHPStorm
安装Laravel Plugin,并在项目中启用(每个项目都得单独启用)Settings->Directories中标示app为Sources目录, 指定其Package Prefix为AppAlt+Insert快捷键 自动生成代码Alt+Enter快捷键 智能补全注释Ctl+MouseOver快捷键 函数提示






转载于:https://my.oschina.net/u/2400083/blog/830898






相关资源:lumen-api-starter:Lumen 8基础上扩展出的API启动项目,精心设计的目录结构,规范统一的响应数据格式,存储库模式架构的最佳实践-源码


友情链接: 医学资料大全 农林牧渔 幼儿教育心得 小学教育 中学 高中 职业教育 成人教育 大学资料 求职职场 职场文档 总结汇报