如何在 Yii2 中安全地生成带有客户端定义的查询字符串参数的 ActiveQuery?

How to generate ActiveQuery with client defined query string parameters safely in Yii2?

有没有一种安全的方法可以为带有查询字符串参数的Yii2 ORM生成条件子句? 例如,我们需要一些食品的列表,按它们的属性过滤:

GET /food/?weight[>]=1000&calories=[<]=200

产品有很多不同的属性:重量、卡路里、数量、价格。

我希望可以编写类似(简化代码)的内容:

 $query = new \yii\db\Query();
 foreach ($_GET as $parameter => $condition){
    foreach ($condition as $operator => $value){
        $query->where(new SimpleCondition($parameter, $operator, $value));
    }
 }

但我怀疑这种方法安全

所以,有三个问题:

  1. 如何安全地定义 url 中的属性?我们可以在 ActiveQuery::where 子句中使用之前清理查询字符串参数 names(不是 values)吗?
  2. 如何正确定义像 IN, AND, OR, >, <, >=, <=, etc. 这样的运算符?
  3. 是否有用于过滤的任何原生 Yii2 组件,还是我应该使用第三方模块?

终于,我找到了解决办法。 Yii2 似乎通过 DataFilter class 提供了这样的功能。 官方documentation of the class and the guide使用起来

根据文档

  1. 定义验证模型。

    class SearchModel extends \yii\base\Model
    {
        public $id;
        public $name;
    
        public function rules()
        {
            return [
                [['id', 'name'], 'trim'],
                ['id', 'integer'],
                ['name', 'string'],
            ];
        }
    }
    
  2. 创建过滤器:

    $filter = new DataFilter(['searchModel' => $searchModel]);
    
  3. 用数据填充过滤器,验证

    if ($filter->load(\Yii::$app->request->get())) { 
       $filterCondition = $filter->build();
       if ($filterCondition === false) { // if error occure
           // the errors are stored in the filter instance
           return $filter;
       }
    }
    
  4. Query 过滤器中使用内置条件

    $query->andWhere($filterCondition);