如何在 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));
}
}
但我怀疑这种方法安全。
所以,有三个问题:
- 如何安全地定义 url 中的属性?我们可以在
ActiveQuery::where
子句中使用之前清理查询字符串参数 names(不是 values)吗?
- 如何正确定义像
IN, AND, OR, >, <, >=, <=, etc.
这样的运算符?
- 是否有用于过滤的任何原生 Yii2 组件,还是我应该使用第三方模块?
终于,我找到了解决办法。
Yii2 似乎通过 DataFilter
class 提供了这样的功能。
官方documentation of the class and the guide使用起来
根据文档
定义验证模型。
class SearchModel extends \yii\base\Model
{
public $id;
public $name;
public function rules()
{
return [
[['id', 'name'], 'trim'],
['id', 'integer'],
['name', 'string'],
];
}
}
创建过滤器:
$filter = new DataFilter(['searchModel' => $searchModel]);
用数据填充过滤器,验证
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;
}
}
在 Query
过滤器中使用内置条件
$query->andWhere($filterCondition);
有没有一种安全的方法可以为带有查询字符串参数的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));
}
}
但我怀疑这种方法安全。
所以,有三个问题:
- 如何安全地定义 url 中的属性?我们可以在
ActiveQuery::where
子句中使用之前清理查询字符串参数 names(不是 values)吗? - 如何正确定义像
IN, AND, OR, >, <, >=, <=, etc.
这样的运算符? - 是否有用于过滤的任何原生 Yii2 组件,还是我应该使用第三方模块?
终于,我找到了解决办法。
Yii2 似乎通过 DataFilter
class 提供了这样的功能。
官方documentation of the class and the guide使用起来
根据文档
定义验证模型。
class SearchModel extends \yii\base\Model { public $id; public $name; public function rules() { return [ [['id', 'name'], 'trim'], ['id', 'integer'], ['name', 'string'], ]; } }
创建过滤器:
$filter = new DataFilter(['searchModel' => $searchModel]);
用数据填充过滤器,验证
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; } }
在
Query
过滤器中使用内置条件$query->andWhere($filterCondition);