0 关注者

过滤集合

从 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操作访问)可以按idclockIn属性进行过滤。

发现错别字或您认为此页面需要改进?
在 github 上编辑 !