项目的规划和设计草案
前言
在第(一)章中我们已经实现了 hellow world!
但是现在不用急着撸代码,
而是要把我们设计这款框架的想法捋顺。
期望效果
按照重要性给各项指标进行打分,其中星星越多代表重要性越高。
开发舒适度:★★★★★
这是最关键的一条!
使用了我们的框架,
开发者撸代码会变成愉♂悦的过程!
我给它起个口号:
享受令人愉♂悦的开发过程。 — by FireRabbit-Engine 火兔引擎
但是怎么个舒适法得有一个定义,不然就太宽泛了。
- 能够帮助开发者快速排查错误以及调试的能力
- 在框架层面自动帮用户解决掉麻烦问题,比如 SQL 注入、用户权限、跨域问题、表单校验等等
- 指令式开发,开发者可以在控制台输入指令自动生成对应的文件,比如输入
make:model
就会生成一个数据库查询模型
高性能:★★★★★
我们既然选择了 swoole 扩展,
自然要体现出它应该具有的高性能特点,
高性能的指标是响应速度,期望效果是 1-30 ms。
(以接口的响应速度为判定指标)
它要非常的快!不快怎么装 X 呢!
高并发:★★★★★
同样是 swoole 的特色,
我们的框架也应该支持强大的并发连接。
框架完成后我们会用 ab 测试来查看高并发情况下的性能。
扩展性:★★★★★
人没梦想跟咸鱼有什么区别!
万一框架火了呢!?
我们这套框架应该是能让开发者 DIY 的。
框架的扩展性要非常的强,
各个模块之间尽可能的解耦。
安全性:★★★★★
手撸框架要十分注意的地方!
市面的框架基本上已经把安全隐患在框架层面解决了,
以至于我们完全忽视了本应该注意的漏洞。
就比如 SQL 注入,你用的框架封装好的 ORM 自动帮你处理了。
但是我们自己从零开始撸框架就不一样了,
我们要让这个框架使用起来非常安全。
代码规范:★★★
为了后期可维护,代码规范也是十分必要的,
毕竟老夫也不是什么大神,只能说在认知的范围内尽量吧……
如果后期觉得设计不合理,会推翻重做。
小白化:★★★
让一个没学过 swoole 的人也能上手。
(其实我自己就是现学现卖)
我们再给它起个口号:
有手就能撸。 — by FireRabbit-Engine 火兔引擎
“会增删改查吗?”
“明天可以来上班了。” —— 根据本人亲身经历改编。
半自动化:★★★
谁说做开发就一定要手撸代码的?
要我说的话,
开发的最高境界是“无码”
其实是我开发游戏的时候得到的灵感,
比如关卡的设计,每个场景都要单独写一个吗?
那如果是几千个关卡的游戏呢?
只要一个配置文件就能搞定!
而我们只需要写一个关卡解释器,
将配置的参数实例化为游戏的场景。
所以我有一个预感,以后的开发者不需要写太多的代码,
只要配置文件就可以解决大部分的问题。
在开发这个框架的时候,我会把这个思想融入到设计层面。
亲,我们这个框架高清无码。— by FireRabbit-Engine 火兔引擎
模块设计
框架是由模块构成的,
我们要把每个模块都拆分成独立的,以后还能拆分成单独的包。
入口文件
swoole 已经是单一入口了,
所以直接用就行了。
配置文件
有一个专门用来读取配置文件的模块,
除了框架的配置还支持用户自定义配置。
不同的模块有不同的配置文件,全部单独区分:
1 | # 文件目录 config/ |
自动加载
直接使用 composer 实现自动加载即可。
遵循 psr-4
加载规范。
路由模块
需要一个路由解析器来处理 swoole 收到的请求路径,
将请求分发到控制器和对应的方法,还有处理路径上的参数。
1 | # 用户浏览一篇博客文章 |
以上就是路由解析器的大概原理。
真正要实现是很复杂的,因为路由是各种各样奇奇怪怪的:
1 | # 文章详情 |
如果我们的网站不打算使用路径参数,
那就简单得多了,但是用 query 参数很不美观。
比如 TP 框架的这种路径:
1 | # c 代表控制器,a 代表方法,id 是查询参数 |
请求和响应
这个就是面试的时候经常考的问题了,
就不再详细介绍了,
简单地说就是用户访问我们的网站,
我们要给它输出什么样的结果。
- 请求要经过过滤器(中间件、数据/权限验证)
- 响应返回的格式(content-type)
表单验证
对用户提交的表单字段验证。
如果每个表单都要这样:
1 | # 用户注册 |
一个框架没有表单处理模块,你离升仙也就不远了。
中间件
通俗的将就是请求拦截器。
表单验证也是拦截请求,
但是在拦截的层面上不一样,
表单验证一般是在控制器里面拦截的,
而中间件是在还没进入到控制器的时候就开始拦截。
比如一个抢购活动在晚上 9 点开始:
1 | $startTime = date('Y-m-d 21:00:00') |
你可以在控制器里面写上这样的代码来判断活动是否开始,
但是这种硬编码绝对会让你原地爆炸,
即使你自己觉得没啥,你同事绝对会想在月黑风高的时候把你弄死……
我们为什么不这样做呢?
1 | # 定义一个“规则”,把它命名为:2021_12_12_active |
中间件就是一套“规则”,你可能会问那跟表单验证有什么不同?
其实表单验证就是中间件的子集,除了表单验证之外,还有权限验证。
比如你可以规定一个请求不带 token 就不让它通过。
表单验证和权限验证虽然都属于中间件,
但我们还是会单独拆分出来,
因为他们在细节还是有些不同的,
而且我们还可以通过封装实现更加简单的操作。
表单验证和权限验证均可以在控制器里面处理,如果是在控制器层面处理的话就不叫做中间件的,为了实现复用性,我们会把表单验证跟用户验证以中间件的形式实现
日志
不论是本地调试还是线上查询问题所在,
日志都是非常重要的,日志系统可以支持数据库和文件。
我们暂时只支持文件日志。
常量
需要一个专门的类来保存框架使用的各种常量。
比如返回的错误码之类的,redis 的键等等。
如果不统一管理常量的话,后期会变得非常麻烦。
缓存
将缓存的调用封装起来,
我们自定义一个 Cache 类,
外部只要调用暴露出来的接口即可。
而 Cache 内部则可以支持不同的缓存数据库,
包括 Redis 集群的调用等等。
目前仅考虑:Redis
数据库(Model)
同缓存系统,
数据库模型直接暴露一个供外部调用的接口,
然后通过配置文件来自定义包括集群甚至是数据库类型等等配置。
数据库类型目前仅考虑:MySQL
模型文件主要是定义字段以及处理一些关联关系。
不将复杂的代码放到这里。
比较复杂的数据库逻辑可以再定义一个 Action 层来处理。
模板引擎(View)
为了支持搜索引擎的 SEO,
我们不采用前后端分离的设计,
当然也不能直接写 phtml(即 php 和 html 混合的代码)
第一次学 PHP 的时候,我们都接触过这样的:
1 | # index.php |
phtml 文件把 php 的逻辑代码与 html 代码混合在一起,
如果是循环或者增加条件判断,简直不忍直视……
而使用模板引擎的情况下,我们只要传入参数,
然后模板渲染结果就可以了,
模板引擎当然也可以改成可配置的。
目前仅考虑:blade
控制器(Controller)
在我设计的这个框架里,
控制器不是用来处理业务逻辑的,
而是验证+分发请求+返回响应。
不过,验证可以完全交给中间件来处理,
这样控制器的代码就可以更加简洁。
期望效果:
1 | public function index() { |
所有控制器的方法内的代码不超过 10 行。
逻辑处理(Service)
处理逻辑代码的地方,本质是一个类。
队列
按照原生开发的话,应该会使用 redis + 死循环来实现队列,
但是考虑到 swoole 自带了任务处理机制,
等我学习之后再具体考虑怎么实现。
单元测试
没有。
总结
大致就想到这么多,后期如果有需要再进行补充。