Lumen+Dingo构建API返回值转换成字符串

xiaohai 2018-09-09 17:36:15 2547人围观 标签: Laravel  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提供的这种机制更友好。