Yii2通过自定义RequestParser对请求数据进行预处理

在项目中,后台接口输出的数据键遇到多个单词统一转换为了驼峰,前端请求的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;
    publicthrowException = true;


    /**
     * Parses a HTTP request body.
     * @param string rawBody the raw HTTP request body.
     * @param stringcontentType 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 (InvalidArgumentExceptione) {
            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下的componentsrequest下的parsers配置为刚才新建的解析器:

'components' => [
    'request' => [
        'parsers' => ['application/json' => 'appcomponentsRequestParamsParser',],
        ...
    ],
    ...
]

测试

这样请求body中的json数据就会被解析器预处理,执行:

$data = Yii::$app->getRequest()->getBodyParams();
var_dump($data);

打印处理后的结果:

自定义RequestParser处理结果

总结

在Yii2中通过自定义RequestParser可以对请求中的数据进行统一预处理,这样就避免了在每个接口中进行重复的操作了,非常方便。

Yii2通过自定义RequestParser对请求数据进行预处理

原文链接:https://beltxman.com/2720.html,若无特殊说明本站内容为 行星带 原创,未经同意禁止转载。

Scroll to top