我有一个应用程序,显示从数据库表的文件列表。我希望用户能够通过选择将过滤文件列表的选项来创建一个组,并且只显示匹配的选项。组选项被添加到另一个表中以供以后使用。
选项如下:name
year
type
room
day
time
除了name
之外,其余都是可选的,用户可以将其留空。有些选项可以包含多个用,
分隔的值。
下面是我添加这些信息的代码:
if ($addGrp = $m->prepare("SELECT * FROM pro_files WHERE userid=?, name=? ...")) {
$addGrp->bind_param('is ...',$userid, $name ...;
}
作为参考,为了选择这些动态列,我将使用:
WHERE room in (g23,f43,g43) AND type in ('pptx,ppt,ai,pdf')
和用于绑定它们的变量是逗号分隔的值(根据用户选择的内容生成,如果用户什么都不选择,则变量将不存在):
$room = 'g23,f43,g43';
$type = 'pptx,ppt,ai,pdf';
使用旧的MYSQL方法,我可以创建一个查询字符串没有问题。当我还需要处理bind_param
行时,如何创建动态查询?
为了演示,我在需要动态生成查询的地方添加了...
。
我不能使用PDO,因为应用程序的其余部分目前正在使用mysql,这项工作太大了。
或者,是否可以在in子句中使用通配符?在这种情况下,我可以在PHP中创建'' = '*'
。然而,room in ('*')
不工作
对于普通的mysqli准备好的语句,这将是一个相当困难的挑战。
但是使用一些DBAL或ORM可以简化它。例如,通过使用我编写的DBAL,可以以一种非常简洁的方式完成:
首先根据用户输入定义变量。
$name = 'Bill';
$year = NULL;
$room = ['g23','f43','g43'];
$type = NULL;
$day = 4;
$time = NULL;
然后编写一个查询,其中每个变量使用两次
$sql = "SELECT * pro_files WHERE name=?s
(AND ?s is NULL OR year = ?s)
(AND ?a is NULL OR type = ?a)
(AND ?a is NULL OR room = ?a)
(AND ?s is NULL OR day = ?s)
(AND ?s is NULL OR time = ?s)";
最后运行查询:
$data = $db->getAll($sql,$name,$year,$year,$room,$room,$type,$type,$day,$day,$time,$time);
它将根据提供的非空值返回搜索结果。
我只需要提到准备好的语句在这里只是模拟的,但它和本地语句一样安全。
顺便说一下,我想看看其他DBAL或ORM的方法。推荐一个是一回事,展示一个可行的例子是另一回事。