Lumen+Dingo构建API返回值转换成字符串
简介在于前端攻城狮的兄弟们开发接口的时候,总会遇到一些奇怪的问题。比如IOS对某个字段要求要整数,如果PHP这边返回过去是字符串那么APP就会崩溃。虽然他们可以捕获异常,但是有些时候我们更想后端的攻城狮能否提供一种统一的数据类型,前端想怎么转换就是他们自己的事情,本文我们将给大家带来这方面的处理。
文章简介已经说明了本文需要干什么,这里就不废话了。
一、PHP转换多维数组值的类型
我们给出一些接口返回的数据:
{
"status": 200,
"data": {
"name": "zhang",
"age": 20,
"sex": null,
"address": "四川成都",
"money": false,
"school": {
"1": {
"name": "小学xx学校",
"address": false
},
"2": {
"name": "初中xx学校",
"address": null
}
}
},
"message": "成功"
}
上面是一个API返回的数据,从上面可以看出,里面有字符型,还有整数,还有NULL和false。什么数据类型都有,这样对前端的程序员处理也是一种非常麻烦的事情。既然对于像null和false这样的类型,php可以使用strval转换过来,如果是null或者false,转换成字符串就为空字符串,其他数字转换过来也是如此。思路就是这样,将数组下的值都转成成字符串,null和false都转换成空字符串。
但是作为返回值,有可能是多维数组,我们如何来对每个值进行转换呢?可能大家会使用递归等方法,这样处理是否比较麻烦呢?其实不用怕,PHP自带了一个函数就是用来干这个的,而且效率特别高。这个函数就是:array_walk_recursive,不知道的可以自行百度哈!
使用例子
$data = [
'name' => 'zhang',
'age' => 20,
'sex' => null,
'address' => '四川成都',
'money' => false,
'school' => [
'1' => ['name' => '小学xx学校', 'address' => false],
'2' => ['name' => '初中xx学校', 'address' => null]
],
];
var_dump($data);
array_walk_recursive($data, function (&$item) {
$item = strval($item);
});
var_dump($data);
执行结果:
#转换前打印结果: 转换后打印结果:
array(6) { array(6) {
["name"]=> ["name"]=>
string(5) "zhang" string(5) "zhang"
["age"]=> ["age"]=>
int(20) string(2) "20"
["sex"]=> ["sex"]=>
NULL string(0) ""
["address"]=> ["address"]=>
string(12) "四川成都" string(12) "四川成都"
["money"]=> ["money"]=>
bool(false) string(0) ""
["school"]=> ["school"]=>
array(2) { array(2) {
[1]=> [1]=>
array(2) { array(2) {
["name"]=> ["name"]=>
string(14) "小学xx学校" string(14) "小学xx学校"
["address"]=> ["address"]=>
bool(false) string(0) ""
} }
[2]=> [2]=>
array(2) { array(2) {
["name"]=> ["name"]=>
string(14) "初中xx学校" string(14) "初中xx学校"
["address"]=> ["address"]=>
NULL string(0) ""
} }
} }
} }
从上面可以观察到转换后,数据类型都统一成了string,这样也有利于前端人员对数据的处理。
二、那么Lumen+Dingo来处理API返回内容
如果大家对Dingo不太了解,先看这篇文章:响应,特别是最后的事件。
第一步:首先在app/Listeners目录下新建文件ResponseValueConversion.php,内容如下:
namespace App\Listeners;
use Dingo\Api\Event\ResponseWasMorphed;
class ResponseValueConversion
{
public function handle(ResponseWasMorphed $event)
{
array_walk_recursive($event->content, function (&$item) {
$item = strval($item);
});
}
}
第二步、添加事件监听器到/app/Listeners/EventServiceProvider.php中如下代码:
protected $listen = [
'Dingo\Api\Event\ResponseWasMorphed' => [
'App\Listeners\ResponseValueConversion'
]
];
第三步、确保bootstrap/app.php中
$app->register(App\Providers\EventServiceProvider::class);
前面的注释是否删掉,否这事件监听器就不能生效
以上三步完成后,就可以开始查看自己API的返回值的类型,下面是我API返回的数据格式:
{
"status": "200",
"data": {
"name": "zhang",
"age": "20",
"sex": "",
"address": "四川成都",
"money": "",
"school": {
"1": {
"name": "小学xx学校",
"address": ""
},
"2": {
"name": "初中xx学校",
"address": ""
}
}
},
"message": "成功"
}
这里的方式只是利用了Dingo的事件机制来做的数据,还有其他的方式处理,比如可以自定义一个父类,在父类中进行处理,但是个人觉得使用Dingo提供的这种机制更友好。