【发布时间】:2013-09-12 17:43:07
【问题描述】:
我目前正在尝试编写从 $_GET 变量生成的复杂 MySQL WHERE 子句(这些变量本身来自选择下拉菜单)。首先,一些代码让你知道我在说什么:
if(!isset($_GET['order'])){
$order= 'start asc';
} elseif ($_GET['order'] == "dateasc") {
$order= 'start asc';
} elseif ($_GET['order'] == "titleasc") {
$order= 'title asc';
} elseif ($_GET['order'] == "titledesc") {
$order= 'title desc';
};
if(!isset($_GET['cat'])){
$cat= '0';
} else {
$cat = $_GET['cat'];
};
if(!isset($_GET['loc'])){
$loc= '0';
} else {
$loc = $_GET['loc'];
};
if (isset($_GET['sd']) || isset($_GET['ed']) || isset($_GET['cat']) || isset($_GET['loc']) || isset($_GET['order']) ) {
$where = 'WHERE ';
if (isset($_GET['sd'])) {
$where .= "start = " . $_GET['sd'];
};
if (isset($_GET['ed'])) {
$where .= "AND end = " . $_GET['ed'];
};
if (isset($_GET['cat'])) {
$where .= "AND category = " . $_GET['cat'];
};
if (isset($_GET['loc'])) {
$where .= "AND location = " . $_GET['loc'];
};
};
$result = mysql_query("SELECT * FROM " . TABLE . $where . " ORDER BY " . $order);
显然这是行不通的,否则我不会在这里。 :) 基本上,我有 4 个变量有条件地用于在我的查询中进行排序:开始日期、结束日期、类别和位置。我的问题是所有这 4 个可能并不总是被使用.. 所以鉴于上面的例子,可能有人选择一个类别($cat)但不是开始日期($sd)......这意味着我的WHERE 子句将以“AND”开头,这显然是无效的。那么如何根据可能会或可能不会使用的变量构建查询呢?
我真的觉得我想多了,我害怕编写 9000 行 isset 测试来解释 $_GET 变量使用的每种组合。当然有一种简单的方法可以从多个 $_GET 构建 WHERE 子句,每次都可能使用也可能不使用......?我试过谷歌搜索,但只能找到建议使用框架来构建复杂查询的解决方案,而且对于这样一个简单的问题,这似乎过于......笨拙......
【问题讨论】:
-
最简单的方法是在执行过程中将每个条件语句放入一个数组中,而不是直接构建 SQL。然后最后,您可以使用 AND 作为胶水来
implode()您的数组。 -
你不应该像这样将你的 GET 变量直接插入到你的 SQL 中。这不安全。看php.net/manual/en/book.mysqli.php
-
建议:我认为对于复杂的条件语句,您应该使用 switch-statement.stackoverflow.com/questions/2158759/…
-
请,在您编写任何更多的 SQL 接口代码之前,您必须阅读 proper SQL escaping 以避免严重的 SQL injection bugs。此外,
mysql_query不应在新应用程序中使用。这是一个已弃用的接口,已从 PHP 的未来版本中删除。像PDO is not hard to learn 这样的现代替代品,将使您的数据库代码更容易正确。 -
感谢您的提示!我大部分时间都在做前端和 UI 方面的工作,所以我非常感谢所有的指点。