我认为这是一个非常简单的问题。这是我最好的选择,还是有“正确”的方式来做这件事?
<?php
$correctOrder = array("name", "address", "phone", "starttime", "endtime",
"status", "details");
$sql->sql1 = "SELECT * FROM `pickups` WHERE";
if (isset($_GET["name"])){
$sql->sql2 = "`name` LIKE '%" . $_GET['name'] . "%'";
}
if (isset($_GET["address"])){
if (!isset($_GET['name'])){
$q = "`address` LIKE '%" . $_GET['address'] . "%'";
} else {
$q = "AND `address` LIKE '%" . $_GET['address'] . "%'";
}
$sql->sql3 = $q;
}
...
...
echo implode(" ", (array) $sql);
?>
所以,现在:
?name=Jari%20Martikainen&address=some%20random%20street
和
?name=Jari%20Martikainen&address=some%20random%20street&blah=har
和
?address=some%20random%20street&blah=har&name=Jari%20Martikainen
都会返回所需的相同结果,但它似乎不是一种非常有效的处理方式。
答案 0 :(得分:1)
此代码使用数组来计算出它感兴趣的参数,并构建where子句数组。
我在此数组("name" => "name"
)中使用$correctOrder
的原因是它允许参数名称和列名称不同。您应该在此处添加所需的任何参数。
此代码也使用绑定变量,不确定您使用的数据库访问的风格,但您可以将$data
数组传递给execute
以绑定它们。
$correctOrder = array("name" => "name", "address" => "address");
$_GET = [ 'name' => 'name1', 'address' => 'add'];
$where = [];
$data = [];
foreach ( $_GET as $paramName => $param ) {
if ( isset($correctOrder[$paramName]) ) {
$where[] = "`{$correctOrder[$paramName]}` like ? ";
$data[] = '%'.$param.'%';
}
}
$sql = "SELECT * FROM `pickups`";
if ( count($where) > 0 ){
$sql .= " WHERE ".implode( " and ", $where);
}
echo $sql.PHP_EOL;
print_r($data);
如果有要添加的内容,count($where) > 0
部分将只添加where
子句,并且内部添加适当的and
位作为粘合剂。
哪个测试数据给出了......
SELECT * FROM `pickups` WHERE `name` like ? and `address` like ?
Array
(
[0] => %name1%
[1] => %add%
)
这只适用于字符串,但您可以为其他数据字段添加特定代码,并在到达构建语句的最终部分之前将该子句添加到$where
数组中。
答案 1 :(得分:1)
构建一个AND子句的数组($ands
),但没有&#34; AND&#34;。
$ands = array();
if (...)
$ands[] = "name LIKE ...";
if (...)
$ands[] = "address LIKE ...";
...
然后构建查询:
$query = "SELECT ... WHERE " . implode(' AND ', $ands);
我发现这种模式简单,干净,避免像1=1
这样的kludges或删除额外的AND
。
答案 2 :(得分:0)
这比你要求的更多一次大修。
首先,使用1 = 1启动WHERE子句,然后遍历搜索项数组,并扩展where子句(如果$ _GET数组中包含任何子句)。
其次,我使用PDO对象连接到您的数据库,然后BIND $ _GET值。这将有助于保护您免受SQL注入/黑客攻击。
下面,我循环搜索条件,如果$ _GET数组中存在某些内容,则将它们保存到名为$ sqlParams的数组中。然后我循环遍历$ sqlParams并绑定值。
// connect to database via PDO
try {
$db = new PDO($dsn, $username, $password, $options);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
$correctOrder = array("name", "address", "phone", "starttime", "endtime",
"status", "details");
$sql = "SELECT * FROM `pickups` WHERE 1=1 ";
// check the $_GET array, build SQL, remember values in $sqlParams
$sqlParams = [];
foreach ($correctOrder as $key) {
if (isset($_GET[$key])) {
$sql .= "and `$key` LIKE :$key ";
$sqlParams[":$key"] = "%{$_GET[$key]}%";
}
}
// bind values from $sqlParams into SQL statement
$stmt = $db->prepare($sql);
foreach ($sqlParams as $key => &$value) {
$stmt->bindParam($key, $value);
}
// execute SQL statement, catching exception
try {
$stmt->execute();
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
// cycle through results and do stuff
while ($row = $stmt->fetch()) {
print_r($row);
}