关于 yii\data\ActiveDataFilter 类的 filter 参数传递规则增加 [ 2.0 版本 ]
缘由:在做rest接口时,在actionIndex
方法中使用dataFilter
,其默认使用的是ActiveDataFilter::class
, 现有的ActiveDataFilter::class
类属性$filterAttributeName
默认值为filter
,在实际的过滤参数传递时,格式为:
1、filter[username][like]=yii
表示username like yii
;
2、filter[username]=yii
表示username = yii
;
问题是,get传递的参数实在是太长,如何可以通过GET参数 username=yii
来做到同样的效果呢?
经过实际的代码,实现如下:
1、定义一个类,处于app\models
命名空间下,名称为IndexActiveDataFilter
;
2、具体代码实现:
<?php
namespace app\models;
use yii\base\InvalidConfigException;
use yii\data\ActiveDataFilter;
use Yii;
class IndexActiveDataFilter extends ActiveDataFilter
{
/**
* 新增字段查询映射,具体参数可参考 filterControls
* 比如要设定username的like查询
* ['username' => 'like']
* 若不设定某个查询属性,则使用默认值,系统中会自动解析
* @var array
*/
public array $fieldFilterControls = [];
public function init()
{
parent::init();
$request = Yii::$app->getRequest();
$requestParams = $request->getBodyParams() ?: $request->getQueryParams();
$this->prepareFilter($requestParams);
}
/**
* 该方法会对$this->filterAttributeName对目标过滤值'filter'填充
* 如同在load()执行后,填充$this->filterAttributeName一样;
* 在逻辑上对处理,该方法会获取参数进行填充,依旧受到searchModel对规则限制,在此处不做合法性验证,
* 因为在后面对build方法执行时,会自动验证,这时yii2框架自带的功能;
* 如果有传递filter[field]=?类似的过滤条件,会自动覆盖原有的值,即filter的权重更高;
* @throws InvalidConfigException
*/
protected function prepareFilter($data = []): array
{
$model = $this->getSearchModel();
$model->load($data, '');
$filter= [];
$attrs = $model->getAttributes();
foreach ($attrs as $attr => $value) {
if (null === $value) {
continue;
}
if (isset($this->fieldFilterControls[$attr])) {
$control = $this->fieldFilterControls[$attr];
$filter[$attr] = [$control => $value];
} else {
$filter[$attr] = $value;
}
}
return $this->{$this->filterAttributeName} = $filter;
}
}
我们假定搜索用户表的两个字段username
和status
,使用代码如下:
<php
namespace app\controllers;
use yii\rest\ActiveController;
class UserController extends ActiveController
{
public $modelClass = app\modles\User::class;
public function actions(): array
{
$actions = parent::actions();
$model = (new DynamicModel([
'username', 'status'
]))->addRule(['username'], 'filter', ['filter' => 'trim', 'skipOnArray' => true])
->addRule('username', 'string', ['min' => 2, 'max' => 30])
->addRule('status', 'in', ['range' => [0, 1]]);
$actions['index']['dataFilter'] = [
'class' => IndexActiveDataFilter::class,
'searchModel' => $model,
// 本次新增的属性,用于设定组成Query的查询方式
'fieldFilterControls' => [
// 如果username不设定,则系统会自动判断
'username' => 'like',
// status设定为eq,表示'=';
//若该参数以stats[]=0&status[]=1传入,该值则应为'in',表示数组查询;
'status' => 'eq'
]
];
return $actions;
}
}
按以上操作,即完成了参数传递方式的改写;
注意:
1、系统中的 fitler[username][like]=yii
的方式并未改变;
2、get
参数和 filter
中具有同样的 key,比如,都传入了 username,则以 fitler 中的为准;
3、其他的未可见风险,暂时没有发现;
若有什么错误,请指出!
谢谢阅读!
鬼一浪人 魔都
注册时间:2015-03-28
最后登录:2023-12-26
在线时长:57小时24分
最后登录:2023-12-26
在线时长:57小时24分
- 粉丝29
- 金钱3960
- 威望85
- 积分5380
共 0 条评论