php - MySQL 表上可选的多个过滤器
问题描述
所以我有一个包含以下列的数据库表:
ID
Foo
Bar
Gux
Foo 可以保存值 [a, b, c]、Bar [1, 2, 3] 和 Gux [x, y, z]。
在我的界面中,我有一个 HTML 选择框来过滤 Foo、Bar 和 Gux。问题是用户可以按随机顺序过滤一个、两个或三个参数。
这给了我一个问题来进行有效的 SQL 查询和 bind_param。
我可以做这样的事情:
//Pseudo code
$sql = "";
if (isset($_GET['foo'])) {
$sql = "SELECT * FROM ... WHERE foo=?";
}
if (isset($_GET['bar'])) {
$sql = "SELECT * FROM ... WHERE bar=?";
}
if (isset($_GET['gux'])) {
$sql = "SELECT * FROM ... WHERE gux=?";
}
但是如果使用选择了 foo 和 bar 呢?这也将非常难看且难以实现 bind_params。
理想将是一个通配符,所以我可以做
//Pseudo code
$sql = "SELECT * FROM ... WHERE foo=* AND bar=* AND gux=*";
并且仅在*
选择该列的过滤器时将其替换为实际值。但这不支持整数。
我想到的另一个选择是执行以下操作:
//Pseudo code
$sql = "SELECT * FROM ... WHERE foo=filter1 OR bar=filter2 OR gux=filter3";
并在选择该列的值时以编程方式替换OR
。AND
这也将解决 bind_param 问题。但我不知道这是否是最好的方法。
解决方案
正如 RiggsFolly 所提到的,动态构建 WHERE 子句。此代码假定至少有 1 个选项(否则也有条件地添加 WHERE。)
每个部分都与相应的绑定数组一起添加到列表中,这显示了数据,您需要为数据库添加实际的 API 部分。WHERE 部分使用implode()
withAND
作为胶水放在一起...
$binds = [];
$where = [];
$types = '';
if (isset($_GET['foo'])) {
$where[] = "foo=?";
$binds[] = $_GET['foo'];
$types .= "s";
}
if (isset($_GET['bar'])) {
$where[] = "bar=?";
$binds[] = $_GET['bar'];
$types .= "s";
}
if (isset($_GET['gux'])) {
$where[] = "gux=?";
$binds[] = $_GET['gux'];
$types .= "i";
}
$sql = "SELECT * FROM ... WHERE " . implode(" AND ", $where);
echo $sql.PHP_EOL;
print_r($binds);
foo 值中的 1 给出...
SELECT * FROM ... WHERE foo=?
Array
(
[0] => 1
)
然后使用类型和绑定bind_param()
...
bind_param($types, ...$binds);
推荐阅读
- ios - 在 swift 中使用 SWReveal 设置根视图控制器时出错
- python - 与 apply() 多次匹配时向数据框添加新值
- java - 使用java删除String中行之间的换行符
- mysql - 对嵌套 SQL Oracle 查询中的多行值求和
- swiftui - 如何更改 SwiftUI 列表中文本数量的最大限制?
- css - 媒体查询继续以不应该的视口大小应用
- android - 在特定设备中通话期间未显示抬头通知
- ios - 如何在 swift 中使用 UserDefaults 实现登录/注销导航?
- python - 如何等待 twilio 回调,直到它从 TBD 变为实际价格?
- graphql - apollo 客户端 nodejs 使用过滤器查询本地状态