在做資料搜尋的時候,我們可能會加上許多的判斷條件,比如說像產品的話我們會依據分類、名稱、價錢... 等條件去做搜尋。

像是要依名稱搜尋在 PDO 會這樣寫:

$name="something";
$sql = "SELECT * FROM products WHERE name= ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$name]);

 

加入時間的判斷的話會是這樣:

$date1="2021-09-01";
$date2="2021-11-30";
$sql = "SELECT * FROM products WHERE created_at BETWEEN ? AND ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$date1, $date2]);

 

但搜尋的時候不一定每次都會用到所有的搜尋條件,若我們在寫的時候都像這樣判斷是否存在變數:

if(isset($_GET["name"])){
  //依名稱搜尋寫這邊
}else if(isset($_GET["date1"]){
  //依日期搜尋寫這邊
}

條件一多會變成很麻煩,而且我們也不能說有了 A 就不能有 B 這樣,那要做比較多條件的篩選的話,就可以利用陣列來幫我們儲存 query 的條件,之後再把陣列轉換為字串,舉例來說:

$conditions = [];
$parameters = [];

// conditional statements
if (!empty($_GET['name']))
{
    // here we are using LIKE with wildcard search
    // use it ONLY if really need it
    $conditions[] = 'name LIKE ?';
    $parameters[] = '%'.$_GET['name']."%";
}

if (!empty($_GET['category']))
{
    $conditions[] = 'category = ?';
    $parameters[] = $_GET['category'];
}


if (!empty($_GET['date_start']) && $_GET['date_end'])
{

    // BETWEEN
    $conditions[] = 'created_at BETWEEN ? AND ?';
    $parameters[] = $_GET['date_start'];
    $parameters[] = $_GET['date_end'];
}

// the main query
$sql = "SELECT * FROM products";

// 把條件組合成 query 語法
if ($conditions)
{
    $sql .= " WHERE ".implode(" AND ", $conditions);
}

// the usual prepare/execute/fetch routine
$stmt = $pdo->prepare($sql);
//丟入參數
$stmt->execute($parameters);
$data = $stmt->fetchAll();

這樣就能應付比較複雜的條件,而且是比較有彈性的寫法了。