## 响应处理器
响应处理器可以格式化响应输出结构,规范请求输出。 目录 `app\Responses` .
示例:
```php
/**
* 商品详情响应结构
*/
namespace App\Responses\Goods;
use App\Responses\Response;
class GoodsShowResponse extends Response
{
public function messages()
{
return [
'id' => [ 'integer', 'required' => true, 'default' => 0, 'demo' => 1, 'min' => 0, 'max' => 200, 'label' => '商品id', 'callback' => null,],
'type' => [ 'integer', 'required' => true, 'default' => 0, 'demo' => 1, 'min' => 0, 'max' => 200, 'label' => '商品类型:0虚拟,1实物', 'callback' => null,],
'cateid' => [ 'integer', 'required' => true, 'default' => 0, 'demo' => 1, 'min' => 0, 'max' => 200, 'label' => '分类id', 'callback' => null,],
'title' => [ 'string', 'required' => true, 'default' => '', 'demo' => 1, 'min' => 0, 'max' => 64, 'label' => '标题', 'callback' => null,],
'atitle' => [ 'string', 'required' => true, 'default' => '', 'demo' => 1, 'min' => 0, 'max' => 64, 'label' => '副标题', 'callback' => null,],
'sale' => [ 'integer', 'required' => true, 'default' => 0, 'demo' => 400, 'min' => 100, 'max' => 1000, 'label' => '销售数量', 'callback' => null,],
'months' => [ 'integer', 'required' => true, 'default' => 0, 'demo' => 49, 'min' => 1, 'max' => 64, 'label' => '时长', 'callback' => null,],
'price' => [ 'string', 'required' => true, 'default' => 0, 'demo' => 49, 'min' => 1, 'max' => 64, 'label' => '市场价格', 'callback' => null,],
'mprice' => [ 'string', 'required' => true, 'default' => 0, 'demo' => 0, 'min' => 0, 'max' => 10, 'label' => '市场价格', 'callback' => null,],
'tprice' => [ 'string', 'required' => true, 'default' => 0, 'demo' => 0, 'min' => 0, 'max' => 10, 'label' => '平均价格', 'callback' => null,],
'pinprice' => [ 'string', 'required' => true, 'default' => 0, 'demo' => 0, 'min' => 0, 'max' => 10, 'label' => '拼团价格', 'callback' => null,],
'ispin' => [ 'integer', 'required' => true, 'default' => 0, 'demo' => 0, 'min' => 0, 'max' => 10, 'label' => '是不是拼团', 'callback' => null,],
'ismsg' => [ 'integer', 'required' => true, 'default' => 0, 'demo' => 0, 'min' => 0, 'max' => 10, 'label' => '是否发短信', 'callback' => null,],
'state' => [ 'integer', 'required' => true, 'default' => 0, 'demo' => 0, 'min' => 0, 'max' => 10, 'label' => '状态 1正常 0下架', 'callback' => null,],
'sort' => [ 'integer', 'required' => true, 'default' => 0, 'demo' => 0, 'min' => 0, 'max' => 10, 'label' => '商品排序', 'callback' => null,],
'onpic' => [ 'string', 'required' => true, 'default' => '', 'demo' => '', 'min' => 0, 'max' => 10, 'label' => '商品封面', 'callback' => null,],
'ronpic' => [ 'string', 'required' => true, 'default' => '', 'demo' => '', 'min' => 0, 'max' => 10, 'label' => '首页推荐图片', 'callback' => null,],
'bgpic' => [ 'string', 'required' => true, 'default' => '', 'demo' => '', 'min' => 0, 'max' => 10, 'label' => '背景图', 'callback' => null,],
'vurl' => [ 'string', 'required' => true, 'default' => '', 'demo' => '', 'min' => 0, 'max' => 10, 'label' => '视频地址', 'callback' => null,],
'tdata' => [ 'string', 'required' => true, 'default' => '', 'demo' => '', 'min' => 0, 'max' => 10, 'label' => 'HTML介绍', 'callback' => null,],
'intro' => [ 'string', 'required' => true, 'default' => '', 'demo' => '', 'min' => 0, 'max' => 10, 'label' => '商品简介', 'callback' => null,],
'btime' => [ 'string', 'required' => true, 'default' => '', 'demo' => '', 'min' => 0, 'max' => 10, 'label' => '售卖开始时间', 'callback' => null,],
'etime' => [ 'string', 'required' => true, 'default' => '', 'demo' => '', 'min' => 0, 'max' => 10, 'label' => '售卖结束时间', 'callback' => null,],
'utime' => [ 'integer', 'required' => true, 'default' => 0, 'demo' => 0, 'min' => 0, 'max' => 10, 'label' => '更新时间', 'callback' => null,],
'ctime' => [ 'integer', 'required' => true, 'default' => 0, 'demo' => 0, 'min' => 0, 'max' => 10, 'label' => '添加时间', 'callback' => null,],
];
}
}
```
核心代码:
```php
/**
* Created by PhpStorm.
* User: wll
* Date: 2019-05-09
* Time: 10:39
*/
namespace App\Fend\Http;
class FormResponse
{
/**
* 原始响应数据
*
* @var array
*/
protected $rawBody = [];
/**
* 响应数据
*
* @var array
*/
protected $body = [];
/**
* 接口返回字段说明
*
* @return array
*/
public function messages(){
return [
'name' => [
'string', // 类型:string, integer, array, object
'required' => true, // 是否一定会返回
'default' => '', // 默认值
'demo' => 'wll', // 示例值,自动生成时填写: ?? (双问号)
'min' => 0, // 最大 [生成demo数据时可能用上]
'max' => 10, // 最小 [生成demo数据时可能用上]
'label' => '姓名', // 标签
'callback' => null, // 回调函数
],
'age' => [
'integer', // 类型:string, integer, array, object
'required' => true, // 是否一定会返回
'default' => '', // 默认值
'demo' => 12, // 示例值,自动生成时填写: ?? (双问号)
'min' => 0, // 最大 [生成demo数据时可能用上]
'max' => 200, // 最小 [生成demo数据时可能用上]
'label' => '年龄', // 标签
'callback' => null, // 回调函数
],
'avatar' => [
'string', // 类型:string, integer, array, object
'required' => true, // 是否一定会返回
'default' => 'images/user/default.jpg', // 默认值
'demo' => 'images/user/abc.jpg', // 示例值,自动生成时填写: ?? (双问号)
'min' => 0, // 最大 [生成demo数据时可能用上]
'max' => 50, // 最小 [生成demo数据时可能用上]
'label' => '姓名', // 标签
'callback' => function($val){ return 'https://img.txbapp.cn/'.$val; }, // 回调函数
],
'wll' => [
'object',
'required' => true, // 是否一定会返回
'default' => '', // 默认值
'demo' => 'wanglele', // 示例值,自动生成时填写: ?? (双问号)
'min' => 0, // 最大 [生成demo数据时可能用上]
'max' => 50, // 最小 [生成demo数据时可能用上]
'label' => '望乐乐', // 标签
'callback' => null,
],
'wll.name' => [
'string', // 类型:string, integer, array, object
'required' => true, // 是否一定会返回
'default' => '', // 默认值
'demo' => 'wll', // 示例值,自动生成时填写: ?? (双问号)
'min' => 0, // 最大 [生成demo数据时可能用上]
'max' => 10, // 最小 [生成demo数据时可能用上]
'label' => 'w姓名', // 标签
'callback' => null, // 回调函数
],
'wll.age' => [
'integer', // 类型:string, integer, array, object
'required' => true, // 是否一定会返回
'default' => '', // 默认值
'demo' => 88, // 示例值,自动生成时填写: ?? (双问号)
'min' => 0, // 最大 [生成demo数据时可能用上]
'max' => 200, // 最小 [生成demo数据时可能用上]
'label' => 'w年龄', // 标签
'callback' => null, // 回调函数
],
'wll.length' => [
'object',
'required' => true, // 是否一定会返回
'default' => 'images/user/default.jpg', // 默认值
'demo' => 'images/user/abc.jpg', // 示例值,自动生成时填写: ?? (双问号)
'min' => 0, // 最大 [生成demo数据时可能用上]
'max' => 50, // 最小 [生成demo数据时可能用上]
'label' => 'w长度', // 标签
'callback' => null,
],
'wll.length.min' => [
'integer',
'required' => true, // 是否一定会返回
'default' => '', // 默认值
'demo' => 12, // 示例值,自动生成时填写: ?? (双问号)
'min' => 0, // 最大 [生成demo数据时可能用上]
'max' => 200, // 最小 [生成demo数据时可能用上]
'label' => 'w最小长度', // 标签
'callback' => null, // 回调函数
],
'wll.length.max' => [
'integer',
'required' => true, // 是否一定会返回
'default' => '', // 默认值
'demo' => 12, // 示例值,自动生成时填写: ?? (双问号)
'min' => 0, // 最大 [生成demo数据时可能用上]
'max' => 200, // 最小 [生成demo数据时可能用上]
'label' => 'w最大长度', // 标签
'callback' => null, // 回调函数
],
];
}
/**
* 响应提示
*
* @return string
*/
public function notes()
{
return '';
}
/**
* 设置响应数据
*
* @param $body
*/
public function setRawBody( $body )
{
$this->rawBody = (array)$body;
}
/**
* 获取响应数据
*
* @return array
*/
public function getBody()
{
return $this->body;
}
/**
* 格式化响应数据
*
* @param array $body
* @return array
* @throws \Fend_Exception
*/
public function format($body = [])
{
if( !empty($body) ){
$this->setRawBody($body);
}
return $this->body = $this->cFormatData($this->getStructure(), $this->rawBody);
}
/**
* 生成格式化数据
*
* @param $message
* @param $rawBody
* @return array
* @throws \Fend_Exception
*/
protected function cFormatData($message, $rawBody)
{
if( empty($message) ){
return [];
}
$data = [];
// 遍历结构体生成数据
foreach($message as $key => $val) {
// 如果值不存在,也不是必须的则不用列出key
if( !isset($rawBody[$key]) && $val['required'] === false){
continue;
}
// 当响应结构没有值时,用默认值补全
if(!isset($rawBody[$key])){
$rawBody[$key] = $val['default'];
}
switch (strtolower($val[0])){
case 'string':
$data[$key] = $this->rValue($val['callback'], strval(getValue($rawBody, $key, $val['default'])));
break;
case 'integer':
$data[$key] = $this->rValue($val['callback'], getValue($rawBody, $key, $val['default']) + 0);
break;
case 'array':
$tArr = [];
// 数组的话遍历数据格式化
foreach($rawBody[$key] as $v) {
$tArr[] = $this->cFormatData($val['item'], $v);
}
$data[$key] = $tArr;
break;
case 'object':
$data[$key] = $this->cFormatData($val['item'], $rawBody[$key]);
break;
default:
break;
}
}
return $data;
}
/**
* 获取 demo 数据
*/
public function demo()
{
return $this->cDemoData($this->getStructure());
}
/**
* 生成演示数据
*
* @param $message
* @return array
*/
protected function cDemoData($message)
{
if( empty($message) ){
return [];
}
$data = [];
// 遍历结构体生成数据
foreach($message as $key => $val) {
switch (strtolower($val[0])){
case 'string':
$value = strval($val['demo'] != '??' ? $val['demo'] : $this->cStringValue($val['default'], $val['min'], $val['max']));
$data[$key] = $this->rValue($val['callback'], $value);
break;
case 'integer':
$value = ($val['demo'] != '??' ? $val['demo'] : $this->cIntegerValue($val['default'], $val['min'], $val['max'])) + 0;
$data[$key] = $this->rValue($val['callback'], $value);
break;
case 'array':
$data[$key] = $this->cArrayValue($this->cDemoData($val['item']), $val['min'], $val['max']);
break;
case 'object':
$data[$key] = $this->cDemoData($val['item']);
break;
default:
break;
}
}
return $data;
}
/**
* 生成随机字符串
*
* @param $val
* @param $min
* @param $max
* @return string
*/
protected function cStringValue($val, $min, $max)
{
return rand_str(rand($min, $max));
}
/**
* 生成随机数字
*
* @param $val
* @param $min
* @param $max
* @return int
*/
protected function cIntegerValue($val, $min, $max)
{
return rand($min, $max);
}
/**
* 填充数据
*
* @param $val
* @param $min
* @param $max
* @return array
*/
protected function cArrayValue($val, $min, $max)
{
return array_fill(0, $max, $val);
}
/**
* 执行回调
*
* @param $callback
* @param $value
* @return mixed
*/
protected function rValue($callback, $value)
{
if(is_string($callback)){
switch (strtolower($callback)){
case 'image': return \Misc_Image::Factory()->getUrl($value); break;
case 'video': return \Misc_Image::Factory()->getvideo($value); break;
case 'json': return json_decode($value, true); break;
}
}
if(! is_callable($callback) ){
return $value;
}
return $callback($value);
}
/**
* 获取参数结构
*/
protected function getStructure()
{
$messages = $this->messages();
if(empty($messages)){
return [];
}
// 预定义处理之后的规则
$sMessages = [];
// 排序
ksort($messages);
foreach($messages as $key => $item){
if(strpos($key, '.') < 1){
$sMessages[$key] = $item;
}else{
// 过滤处理 key
$keyArr = array_filter(explode('.', $key), function($val){
return $val != '*';
});
// 多维数组赋值
data_set($sMessages, implode('.item.', $keyArr), $item);
}
}
return $sMessages;
}
}
```