从 2.0.13 版本开始,可以使用 yii\data\DataFilter 组件过滤资源集合。它允许验证和构建通过请求传递的过滤条件,并在其扩展版本 yii\data\ActiveDataFilter 的帮助下,将它们以适合 yii\db\QueryInterface::where() 的格式使用。
如 集合 部分所述,我们可以使用 数据提供者 来输出排序和分页的资源列表。我们也可以用它来过滤该列表。
$filter = new ActiveDataFilter([
'searchModel' => 'app\models\PostSearch',
]);
$filterCondition = null;
// You may load filters from any source. For example,
// if you prefer JSON in request body,
// use Yii::$app->request->getBodyParams() below:
if ($filter->load(Yii::$app->request->get())) {
$filterCondition = $filter->build();
if ($filterCondition === false) {
// Serializer would get errors out of it
return $filter;
}
}
$query = Post::find();
if ($filterCondition !== null) {
$query->andWhere($filterCondition);
}
return new ActiveDataProvider([
'query' => $query,
]);
PostSearch
模型用于定义哪些属性和值允许用于过滤
use yii\base\Model;
class PostSearch extends Model
{
public $id;
public $title;
public function rules()
{
return [
['id', 'integer'],
['title', 'string', 'min' => 2, 'max' => 200],
];
}
}
如果你不需要任何特殊的业务逻辑,可以在不准备用于搜索规则的独立模型的情况下使用 yii\base\DynamicModel。
$filter = new ActiveDataFilter([
'searchModel' => (new DynamicModel(['id', 'title']))
->addRule(['id'], 'integer')
->addRule(['title'], 'string', ['min' => 2, 'max' => 200]),
]);
为了控制允许最终用户使用的过滤条件,必须定义 searchModel
。
通常情况下,最终用户需要通过一种或多种允许的方法(应在 API 文档中明确说明)在请求中提供可选的过滤条件。例如,如果过滤是通过使用 JSON 的 POST 方法处理的,它可以类似于以下内容
{
"filter": {
"id": {"in": [2, 5, 9]},
"title": {"like": "cheese"}
}
}
上述条件是
id
必须是 2、5 或 9 并且title
必须包含单词 cheese
。作为 GET 查询的一部分发送的相同条件是
?filter[id][in][]=2&filter[id][in][]=5&filter[id][in][]=9&filter[title][like]=cheese
你可以通过设置 yii\data\DataFilter::$filterAttributeName 来更改默认的 filter
关键字。
允许的过滤控制关键字的默认列表如下所示
过滤控制 | 翻译成 |
---|---|
和 | AND |
或 | OR |
不 | NOT |
lt | < |
gt | > |
lte | <= |
gte | >= |
eq | = |
neq | != |
in | IN |
nin | NOT IN |
like | LIKE |
你可以通过扩展选项 yii\data\DataFilter::$filterControls 来扩展该列表,例如,你可以为同一个过滤器构建键提供多个关键字,创建多个别名,例如
[
'eq' => '=',
'=' => '=',
'==' => '=',
'===' => '=',
// ...
]
请记住,任何未指定的关键字都不会被识别为过滤器控制,并将被视为属性名称 - 应避免控制关键字和属性名称之间的冲突(例如:如果您有控制关键字like
和名为like
的属性,则不可能指定此属性的条件)。
注意:在指定过滤器控制时,请牢记您的 API 使用的实际数据交换格式。确保每个指定的控制关键字对格式有效。例如,在 XML 中,标签名称只能以字母字符开头,因此像
>
、=
或$gt
这样的控制会破坏 XML 模式。
注意:在添加新的过滤器控制词时,请确保检查是否还需要更新yii\data\DataFilter::$conditionValidators和/或yii\data\DataFilter::$operatorTypes,以根据操作符的复杂性和其工作方式来实现预期的查询结果。
虽然在 JSON 语句中使用null
很容易,但无法使用 GET 查询发送它,因为会将文字null
与字符串"null"
混淆。从 2.0.40 版本开始,您可以使用yii\data\DataFilter::$nullValue选项来配置将用作文字null
替换的词语(默认情况下为"NULL"
)。
无论您是想使用其他名称为属性设置别名还是过滤连接的数据库表,都可以使用yii\data\DataFilter::$attributeMap设置别名映射。
[
'carPart' => 'car_part', // carPart will be used to filter car_part property
'authorName' => '{{author}}.[[name]]', // authorName will be used to filter name property of joined author table
]
ActiveController
配置过滤器 ¶yii\rest\ActiveController提供了一套方便的常用 REST 操作,您可以轻松地配置它们以使用过滤器,方法是通过yii\rest\IndexAction::$dataFilter属性。其中一种方法是使用yii\rest\ActiveController::actions()
public function actions()
{
$actions = parent::actions();
$actions['index']['dataFilter'] = [
'class' => \yii\data\ActiveDataFilter::class,
'attributeMap' => [
'clockIn' => 'clock_in',
],
'searchModel' => (new DynamicModel(['id', 'clockIn']))->addRule(['id', 'clockIn'], 'integer', ['min' => 1]),
];
return $actions;
}
现在您的集合(通过index
操作访问)可以按id
和clockIn
属性进行过滤。
发现错别字或您认为此页面需要改进?
在 github 上编辑 !
注册或登录以发表评论。