php - 带有 Ajax 的 PDO 过滤系统。有没有更好的办法?
问题描述
我正在尝试使用选择框过滤用户的一些输入。我正在考虑是否有更好的方法来做到这一点。
if(isset($_POST['action']))
{
$sql = "SELECT * FROM occasions WHERE naam IS NOT NULL";
if(isset($_POST['merk'])){
$merk = $_POST['merk'];
$merkQuery = implode(',', array_fill(0, count($merk), '?'));
$sql .= " AND merk IN(".$merkQuery.")";
}
if(isset($_POST['brandstof'])){
$brandstof = $_POST['brandstof'];
$brandstofQuery = implode(',', array_fill(0, count($brandstof), '?'));
$sql .= " AND brandstof IN(".$brandstofQuery.")";
}
//We prepare our SELECT statement.
$statement = $pdo->prepare($sql);
if(isset($_POST['merk'])){
//Execute statement.
$statement->execute(array_merge(array_values($merk)));
}
if(isset($_POST['brandstof'])){
//Execute statement.
$statement->execute(array_merge(array_values($brandstof)));
}
if(isset($_POST['merk']) && isset($_POST['brandstof']))
{
$statement->execute(array_merge(array_values($merk), array_values($brandstof)));
}
else
{
$statement->execute();
}
}
因为如果有很多选择框需要过滤,代码会变长。我想知道是否有更好的方法来过滤多个选择框。
这是一个例子:链接
解决方案
我建议重命名 post 变量;将它们分组为一个二维数组。
<input type="checkbox" name="data[merk][bmw]" />
<input type="checkbox" name="data[merk][skoda] />
等等。
这是做什么的,它允许您使用 foreach 来遍历检查的任何值。
$data = $_POST['data'] ?? []; // null coalesce defaults to a blank array if post var is null
foreach($data as $category=>$val) {
settype($val, 'array');
$query = implode(',', array_fill(0, count($val), '?'));
foreach($val as $k=>$v) {
$params[] = $k;
}
// DON'T DO THIS!
$sql .= " AND $category IN(".$query.")";
}
您不应该这样做的原因是因为您永远不应该使用用户提供的数据构建查询。
但是,您可以做的是将用户提供的数据与硬编码数据进行映射。
$map = [
// form value => db field
'merk' => 'MERK',
'brandstof' => 'BRANDSTOF',
// ... etc
];
然后在构建查询时,
$sql .= " AND $map[$category] IN($query)";
与此同时,您已经在$params
.
——
最重要的是,我们所做的是重构代码,因为我们注意到事情正在重复。例如,您不得不为每个场合重复代码(?)。一种解决方案是继续检查每个 post 值并调用函数来计算 ?s。但即便如此,输入所有这些isset()
s 也是重复的。
回想起来,做这样的输入可能会更好:
<input type="checkbox" name="data[merk][]" value="bmw" />
<input type="checkbox" name="data[merk][]" value="skoda" />
这无疑会更直观,尽管您仍然需要构建 params 数组。
foreach($val as $v) {
$params[] = $v;
}
推荐阅读
- javascript - 使用正则表达式从 XML 中提取字符串
- django - 在 DRF 创建表单上添加 Django 传单位置选择器
- python - 如何增加 axs[i].title.set_text 上的标题字体大小
- ios - SwiftUI:iPad 弹出框上奇怪的关闭动画
- javascript - 在不丢失原始堆栈的情况下覆盖 console.log 方法 - javascript
- struct - LLVM 后端如何处理具有动态访问权限的结构的 getelementptr?
- cryptography - 无法将 pkcs11-tool 与自定义 hsm 角色一起使用
- automation - 我正在尝试使用 7-zip 和 AutoHotKey 提取文件夹,但脚本仅在新窗口中打开压缩文件夹
- drools - 如何使用 Drools Api 声明窗口
- python - 如何更改 django 选择字段的呈现属性?