
本文介绍 yii2 框架下通过控制器接收前端下拉筛选参数(product/month/year),安全构建 sql 查询并返回标准 json 响应的完整实践,涵盖参数绑定、避免 sql 注入、响应格式配置等关键要点。
在 Yii2 中实现动态数据筛选,核心在于安全接收参数、参数化查询、规范返回 JSON 响应。以下是一个专业、可扩展的实现方案:
✅ 正确做法:参数化 + 响应格式自动处理
首先,将筛选条件作为动作方法的参数声明,Yii2 会自动从 GET/POST 请求中解析(支持 URL 路由或表单提交):
<?php
public function actionProducts($product = null, $month = null, $year = null)
{
// 构建基础查询(注意:WHERE 条件需动态拼接,避免空值导致逻辑错误)
$conditions = [];
$params = [];
if ($year !== null && is_numeric($year)) {
$conditions[] = 'year = :year';
$params[':year'] = (int)$year;
}
if ($month !== null && is_numeric($month)) {
$conditions[] = 'month = :month';
$params[':month'] = (int)$month;
}
if ($product !== null && is_string($product) && trim($product) !== '') {
$conditions[] = 'product = :product';
$params[':product'] = trim($product);
}
$whereClause = !empty($conditions) ? 'WHERE ' . implode(' AND ', $conditions) : '';
$sql = "SELECT product, cost, supplier, month, year
FROM products
{$whereClause}
GROUP BY product, month, year";
$data = Data::findBySql($sql, $params)->asArray()->all();
// ✅ 推荐:使用 Yii 内置 JSON 格式化(自动设置 Content-Type、处理编码、支持 JSON_NUMERIC_CHECK)
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
return ['data' => $data];
}⚠️ 注意事项与最佳实践
- 不要手动 header() + json_encode():Yii 的 Response::FORMAT_JSON 会自动处理 MIME 类型、字符编码、HTTP 状态码及 JSON_NUMERIC_CHECK 等细节,更健壮;
- 避免硬编码参数值(如 2022):始终从请求中获取,并做类型/空值校验,防止 SQL 错误或全表扫描;
- 防止 SQL 注入:所有用户输入必须通过命名参数(:param)绑定,绝不可字符串拼接;
- 空筛选时返回全量? 当前示例默认无条件时不加 WHERE,即返回全部;如需“至少一个条件必选”,可在开头添加校验并抛出 BadRequestHttpException;
-
前端调用示例(AJAX):
fetch('/site/products?year=2023&month=12&product=WidgetA') .then(r => r.json()) .then(res => console.log(res.data));
? 总结
Yii2 的 actionProducts() 应以声明式参数接收 → 动态条件组装 → 参数化查询 → FORMAT_JSON 统一响应为标准流程。该模式兼顾安全性、可维护性与框架特性,是构建 API 筛选接口的推荐范式。










