在项目中,后台接口输出的数据键遇到多个单词统一转换为了驼峰,前端请求的 json
数据中的键同样是驼峰,但是数据库里的字段都是用的小写字母加下划线去分割,这样表单提交数据给AR模型直接 load()
使用就有问题,所以在接收到数据之后,应该做一下预处理,将数据中驼峰转换成下划线加小写字母。
在Yii2中通过实现 RequestParserInterface
接口,自定义一个 RequestParser
来解决这个问题。
解决
在根目录新建一个 components
组件文件夹,新建一个 RequestParamsParser.php
文件,在官方 yiiwebJsonParser
解析器的基础上做一些修改,代码如下:
<?php
namespace appcomponents;
use yiibaseInvalidArgumentException;
use yiihelpersJson;
use yiiwebBadRequestHttpException;
use yiiwebRequestParserInterface;
class RequestParamsParser implements RequestParserInterface
{
public $asArray = true;
public $throwException = true;
/**
* Parses a HTTP request body.
* @param string $rawBody the raw HTTP request body.
* @param string $contentType the content type specified for the request body.
* @return array parameters parsed from the request body
* @throws BadRequestHttpException if the body contains invalid json and [[throwException]] is `true`.
*/
public function parse($rawBody, $contentType)
{
try {
$parameters = Json::decode($rawBody, $this->asArray);
if($parameters === null) {
return [];
} else {
$this->upperToUnderline($parameters);
return $parameters;
}
} catch (InvalidArgumentException $e) {
if ($this->throwException) {
throw new BadRequestHttpException('Invalid JSON data in request body: ' . $e->getMessage());
}
return [];
}
}
// 驼峰转下划线
public function upperToUnderline(&$array)
{
foreach ($array as $key => &$value) {
if(!is_int($key)) {
// 关联数组
$newKey = strtolower(preg_replace('/([A-Z])/', '_$1', $key));
if($key !== $newKey) {
$array[$newKey] = $value;
unset($array[$key]);
if(is_array($array[$newKey])) {
$this->upperToUnderline($array[$newKey]);
}
} elseif(is_array($value)) {
$this->upperToUnderline($value);
}
} else {
// 数字数组
$this->upperToUnderline($value);
}
}
}
}
修改配置
修改 web.php
下的 components
中 request
下的 parsers
配置为刚才新建的解析器:
'components' => [
'request' => [
'parsers' => ['application/json' => 'appcomponentsRequestParamsParser',],
...
],
...
]
测试
这样请求body中的 json
数据就会被解析器预处理,执行:
$data = Yii::$app->getRequest()->getBodyParams();
var_dump($data);
打印处理后的结果:
总结
在Yii2中通过自定义 RequestParser
可以对请求中的数据进行统一预处理,这样就避免了在每个接口中进行重复的操作了,非常方便。
标题:Yii2通过自定义RequestParser对请求数据进行预处理
原文链接:https://beltxman.com/2720.html
若无特殊说明本站内容为 行星带 原创,未经同意请勿转载。