1

以下代码需要使用用户提供的 3 个变量。默认情况下,所有这些变量都等于 0。

  1. 时间(文本框)
  2. 城市(下拉列表)
  3. 类型(下拉列表)

例如,如果用户给出时间和城市,但让类型为零,则不会返回任何结果。我的问题是什么是修改我现有代码的有效且高效的方法,以便如果用户选择不选择时间、城市或类型或这些的任何组合,将返回结果?

例如,如果时间21:00 添加城市编号 3,它将显示所有满足 2 条件的类型应列出。

$question= 'SELECT * FROM events WHERE ABS(TIMESTAMPDIFF( HOUR , `time`, :time )) < 2 AND city=:city AND type=:type';
$query = $db->prepare($question);
$query->bindValue(":time", $time, PDO::PARAM_INT);
$query->bindValue(":city", $city, PDO::PARAM_INT);
$query->bindValue(":type", $type, PDO::PARAM_INT);
$query->execute();
4

4 回答 4

1
<?php
$question= 'SELECT * FROM events WHERE ';

$hasTime = false;
if(!empty($time)) { // @note better validation here
    $hasTime = true;
    $question .= 'ABS(TIMESTAMPDIFF( HOUR , `time`, :time )) < 2 ';
}

$hasCity = false;
if(!empty($city)) { // @note better validation here
    $hasCity = true;
    $question .= 'AND city=:city ';
}

$hasType = false;
if(!empty($type)) { // @note better validation here
    $hasType = true;
    $question .= 'AND type=:type';
}

$query = $db->prepare($question);

if($hasTime)
    $query->bindValue(":time", $time, PDO::PARAM_INT);
if($hasCity)
    $query->bindValue(":city", $city, PDO::PARAM_INT);
if($hasType)
    $query->bindValue(":type", $type, PDO::PARAM_INT);

$query->execute();
$results = $query->fetchAll();

if(empty($results))
    echo 'no results';
else
    // $results is an array of arrays
于 2012-07-20T16:23:59.953 回答
1

我更喜欢使用条件数组,并检查条件是否存在,以构建 SQL 查询的各个部分:

$conditions = array(); // Creating an array of conditions.
if ($time) // Checks to see if value exists.
{
    $timeCondition = "ABS(TIMESTAMPDIFF( HOUR , `time`, :time )) < 2";
    $conditions[] = $timeCondition; // Adds this condition string to the array.
}
if ($city)
{
    $cityCondition = "city=:city";
    $conditions[] = $cityCondition;
}
if ($type)
{
    $typeCondition = "type=:type";
    $conditions[] = $typeCondition;
}

$conditionString = implode(" AND ", $conditions); // Gluing the values of the array with " AND " in between the string conditions.

if (count($conditions) > 0) // If conditions exist, add "WHERE " to the condition string.
{
    $conditionString = "WHERE ".$conditionString;
}
else // Otherwise, the condition string is blank by default.
{
    $conditionString = '';
}

$question= 'SELECT * FROM events '.$conditionString; // If no conditions, will return all from events. Otherwise, conditions will be slotted in through $conditionString.

$query = $db->prepare($question);

if($time)
    $query->bindValue(":time", $time, PDO::PARAM_INT);
if($city)
    $query->bindValue(":city", $city, PDO::PARAM_INT);
if($type)
    $query->bindValue(":type", $type, PDO::PARAM_INT);

$query->execute();
于 2012-07-20T16:22:25.610 回答
0

You can use a series of IF() statements in your SQL statement, and return true if the value isn't set. So something like this:

...WHERE IF(:time, ABS(TIMESTAMPDIFF(HOUR, `time`, :time)) < 2, 1)
AND IF(:city, city=:city, 1) AND IF(:type, type=:type, 1)
于 2012-07-20T16:24:56.557 回答
0

动态构建查询,以便如果该字段为其默认值,则不要将其包含在 where 子句中。

$conditions = array();
if ($_POST['time']) {
    $conditions[] = "ABS(TIMESTAMPDIFF( HOUR , `time`, :time )) < 2";
}
if ($_POST['city']) {
    $conditions[] = "city=:city";
}
if ($_POST['type']) {
    $conditions[] = "type=:type";
}

$conditionString = implode(" AND ", $conditions);
if (count($conditions) > 0) {
    $conditionString = "WHERE " . $conditionString;
}
else {
    $conditionString = '';
}
$question = 'SELECT * FROM events ' . $conditionString;
于 2012-07-20T16:22:24.920 回答