黄沙百战穿金甲,不破楼兰终不还。这篇文章主要讲述PHP 基于 SW-X 框架,搭建高性能API架构相关的知识,希望能为你提供帮助。
前言
官网地址:??SW-X框架-专注高性能便捷开发而生的PHP-SwooleX框架??
希望各大佬举起小手,给小弟一个star:??https://github.com/swoolex/swoolex??
架构图谱
【PHP 基于 SW-X 框架,搭建高性能API架构】
版本更新规则
每个新版本迭代以??v1.0.1?
?的大中小版本起名,应用代码存储在??/app/http/?
?版本号目录下,??.?
?改为??_?
?。
新版本需要拷贝上一个版本的可用代码,进行修改,并保留原代码。
版本发布
每个新版本开发完成后,需要在??/box/route.php?
?文件中,修改镜像路由地址,使其生效到对外接口地址中,如下:
use \\x\\Route;
// 对前端开放版本映射
Route::mirror([
/v1_0_1/controller/ =>
/api/,
]);
控制器命名
控制器统一存储在??/app/http/版本号/controller/?
?目录下,以一个接口一个文件的方法进行定义。
例如,需要编写一个??Shop?
?模块的??create?
?接口,那应该创建文件如下:
文件地址:??/app/http/版本号/controller/shop/create.php?
?,代码如下:
namespace app\\http\\v1_0_1\\controller\\shop;
use x\\controller\\Http;
class create extends Http
/**
* index方法默认会在路由中忽略
*/
public function index()
return $this->
fetch(演示控制器);
未通过镜像路由映射前的访问地址是:??/v1_0_1/controller/shop/create?
?
通过镜像路由映射后的访问地址是:??/api/shop/create?
?
请求类型限制
对于??GET|POST|AJAX?
?请求类型的限制,统一使用??@Get?
?、??@Post?
?、??@Ajax?
?的方式声明。
例如限制只允许??POST-AJAX?
?问题的接口:
namespace app\\http\\v1_0_1\\controller\\shop;
use x\\controller\\Http;
class create extends Http
/**
* index方法默认会在路由中忽略
* @Post
* @Ajax
*/
public function index()
return $this->
fetch(演示控制器);
参数默认值预设
控制器中,禁止使用以下习惯申明参数默认值:
namespace app\\http\\v1_0_1\\controller\\shop;
use x\\controller\\Http;
class create extends Http
/**
* index方法默认会在路由中忽略
*/
public function index()
$param = \\x\\Request::get();
// 场景一
if (!isset($param[status])) $param[status] = 1;
// 场景二
$param[status] = (isset($param[status]) == false) ? 1 : $param[status];
// 场景三
$param[status] = $param[status] ??1;
对于以上??isset()?
?判断参数是否未传递后,设置默认值的场景,要统一使用??@Param?
?注解提前声明,例如:
namespace app\\http\\v1_0_1\\controller\\shop;
use x\\controller\\Http;
class create extends Http
/**
* index方法默认会在路由中忽略
* @Param(name="status", value="https://www.songbingjia.com/android/1")
*/
public function index()
$param = \\x\\Request::get();
// 如果未提交的情况下,可以直接获取到默认值
var_dump($param[status]);
警告:??@Param?
?注解参数预设,只对??isset()?
?场景有效,??empty()?
?、??is_null()?
?等为空场景无效。
表单校验
禁止在控制器中编写表单格式校验的任何代码,表单校验需要统一在??/box/validate/?
?目录中创建校验器。
校验器的具体使用方法,可以参考SW-X官网文档:??校验器??。
例如创建一个司机相关的校验器,文件:??/boxx/validate/Driver.php?
?,代码如下,包含了3种校验场景:
namespace box\\validate;
use x\\Validate;
class Driver extends Validate
// 定义字段对应的规则
protected $rule = [
id=>
require|int,
driver_sn=>
require|between:1,120,
phone=>
require|phone
];
// 自定义错误值声明
protected $message=[
id.require=>
:preset未提交,
id.int=>
:preset不是整数格式,
driver_sn.require=>
:preset未提交,
driver_sn.between=>
:preset长度只能在0-1位之间,
phone.require=>
:preset未提交,
phone.phone=>
:preset格式错误,
];
// 可以设置message时的字段别名,会把字段名占位符替换后一起抛出
protected $alias = [
id =>
司机ID,
driver_sn =>
司机编号,
phone =>
司机手机号码,
];
// 场景定义
protected $scene = [
// 编辑
edit =>
[id,driver_sn, phone], // 需要校验的字段
// 新增
create =>
[driver_sn, phone],
// 查询表单
select =>
[
field =>
[driver_sn, phone], // 需要校验的字段
delete_rule =>
[ // 删除校验规则
driver_sn =>
require,
phone =>
require,
],
],
];
创建完成后,使用??@Validate?
?注解,在控制器中进行场景绑定:
namespace app\\http\\v1_0_1\\controller\\shop;
use x\\controller\\Http;
class create extends Http
/**
* index方法默认会在路由中忽略
* @Validate(class="\\box\\validate\\Driver", scene="create")
*/
public function index()
return $this->
fetch(演示控制器);
权限校验
API统一绑定了全局中间件??/box/middleware/Auth.php?
?,如果需要跳过权限校验的Api,需要修改该中间件内部的??$_skip?
?成员属性即可。
Api-Restful管理
API统一使用Restful模块进行管理,目录在??/restful/?
?目录下,状态码与返回值说明存放在??/restful/default/?
?目录下。
例如现在要添加一个??DRIVER_ERROR?
?的状态码,对应CODE为??30001?
?,MSG为??司机不存在?
?。
同时,该状态码下,还有一个MSG为??司机余额不足?
?。
那么应该这样定义,修改??/restful/default/code.php?
?文件为如下代码:
return [
// default表示默认使用的msg
DRIVER_ERROR =>
[
default =>
司机不存在, // 默认值
balance_not =>
司机余额不足,
]
];
在控制器中就可以这样使用:
namespace app\\http\\v1_0_1\\controller\\shop;
use x\\controller\\Http;
use x\\Restful;
class create extends Http
/**
* index方法默认会在路由中忽略
*/
public function index()
// 会默认使用default的MSG
return Restful::code(Restful::DRIVER_ERROR())->
callback();
// 也可以指定抛出的MSG
return Restful::code(Restful::DRIVER_ERROR())->
msg(balance_not)->
callback();
// 如果要抛出数据集
return Restful::code(Restful::DRIVER_ERROR())->
data(数据集)->
callback();
更多关于Restful的使用方法,可以参考SW-X官网文档:??Restful支持??。
关于Restful返回值强类型转换
系统会自动把返回值中字符串类型(??string?
?)的??int?
?、??float?
?数据转换回真实类型。
空字符串,转换回??null?
?。
注意,如果是??string?
?的??*.00?
?会被强制转换成??int?
?类型的??*?
?
也就是??0.00?
?会被转成??0?
?,??18.00?
?会被转成??18?
?,这是PHP数据结构的先天上问题。
例如:
"code": 0,
"msg": "请求成功",
"data":
"user_id": "100",
"money": "19.01",
"list": [
"id": "1",
"money": "0.00"
,
"id": "2",
"money": "18.00"
],
"region_id": ""
会被转换成:
"code": 0,
"msg": "请求成功",
"data":
"user_id": 100,
"money": 19.01,
"list": [
"id": 1,
"money": 0
,
"id": 2,
"money": 18
],
"region_id": null
数据模型
控制器中,禁止直接使用Db基类操作,任何数据库相关的操作,都应该统一创建对应的Model类进行逻辑采集处理。
Model的存储目录为:??/app/http/版本号/model/?
?目录下。
例如司机表的新增操作,应该创建一个??DriverModel.php?
?文件:
namespace app\\http\\v1_0_1\\model;
use x\\Model;
class DriverModel extends Model
// 添加司机
public function add($data)
return $this->
insert($data);
// 编辑司机
public function edit($data)
return $this->
where(id, $data[id])->
update($data);
下一章节,我们再来开始,一步步的搭建整个API项目架构。
推荐阅读
- 冬奥快结束了还没有抢到冰墩墩(程序员一招让你不用排队不用愁!)
- 北亚数据恢复NTFS文件系统误操作导致raid5阵列中的分区被格式化的逆向操作服务器数据恢复方法
- Netty 简介《Netty In Action》 #yyds干货盘点#
- 肝魂一晚上总结(全网最全最细手把手教你PyQt5安装与使用??《??记得收藏??》)
- OpenHarmony移植案例(如何适配服务启动引导部件bootstrap_lite)
- 回顾2021 Github最受欢迎的前端项目,谷歌 zx 位居榜首!
- 如何编写sdk()
- 简单的JS鸿蒙小游戏——拼图(冬奥一起拼)
- #yyds干货盘点#HCIE-Security Day14(防火墙双机热备实验防火墙直路部署,上下行连接路由器)