-1

The problem is that I can't reach the 3rd "else if statement" where the scenario is like this:
I have 3 textboxes in HTML -> minimum value, maximum value and search keyword. if the 2 textbox has values I want to reach the 3rd if I put values in 2 textboxes, but what's happening is it's only returning to the 1st if statement.

 <?php
    $price_min = $_POST['price_min'];
    $price_max = $_POST['price_max'];
    $keyword = $_POST['keyword'];
    $sql = 'SELECT * FROM products ';
    
    if (!empty($price_min)) {
      $sql .='WHERE price >='.$price_min;
    } else if (!empty($price_max)) {
      $sql .='WHERE price <='.$price_max;
    } else if (!empty($price_min) && !empty($price_max)) {
      $sql .='WHERE price BETWEEN '.$price_min.' AND '.$price_max;
    } else if (!empty($keyword) && !empty($price_min)) {
      $sql .='WHERE (tags LIKE "%'.$keyword.'%") AND (price >='.$price_min.')';
    } else if (!empty($keyword) && !empty($price_max)) {
      $sql .='WHERE (tags LIKE "%'.$keyword.'%") AND (price <='.$price_max.')';
    } else if (!empty($keyword) && (!empty($price_min) AND !empty($price_max)) {
      $sql .='WHERE (tags LIKE "%'.$keyword.'%") AND (price BETWEEN '.$price_min.' AND '.$price_max.')';
    } else {
      echo "all are empty// ";
    }
  ?>

1 Answers1

3

else if is only executed if the previous if condition was false. A series of if/else if will stop at the first true condition. So this should only be used when the conditions are mutually exclusive. If both $price_min and $price_max are filled in, the first if will succeed, so it won't perform any of the else if tests. You should test for both being set before checking for either of them by themselves.

iif (!empty($price_min) && !empty($price_max)) {
    $sql .='WHERE price BETWEEN '.$price_min.' AND '.$price_max;
} else if (!empty($price_min)) {
  $sql .='WHERE price >='.$price_min;
} else if (!empty($price_max)) {
  $sql .='WHERE price <='.$price_max;
}

However, a much better way to do this is to just check for one variable at a time, and then collect all the WHERE conditions at the end.

$conditions = [];

if (!empty($price_min)) {
    $conditions[] = 'price >='.$conn->real_escape_string($price_min);
}
if (!empty($price_max)) {
    $conditions[] = 'price <='.$conn->real_escape_string($price_min);
}
if (!empty($keyword)) {
    $conditions[] = 'tags LIKE "%'.$conn->real_escape_string($keyword).'%"';
}

if (!empty($conditions)) {
    $sql .= 'WHERE ' . implode(' AND ', $conditions);
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • thank you for this! I think your code is way much better than mine! but how 'bout if "price_min and price_max" has values? does "price >= $price_min AND price <= $price_max" will have the same output query as "BETWEEN min AND max"? – dabin_tsikin Sep 20 '20 at 05:48
  • Yes, `a BETWEEN x AND y` is equivalent to `a >= x AND a <= y` – Barmar Sep 20 '20 at 05:52
  • oh my gosh I've been stuck on this problems for days, thank you so much! can I ask one more thing if it's okay with you? I forgot to include this in my question, I have this checkbox for category filtering and the problem is if the checkbox will only have 1 checked, the query will be "category_id = $category" but if it's 2 or more the query will be " `category_id LIKE \'%'.$category_checked.'%\' OR category_id LIKE \'%'.$category_checked.'%\' and so on.. depends on how many category will be checked ` – dabin_tsikin Sep 20 '20 at 06:19
  • The checkboxes should be in an array. Then you can loop over all of them, and collect them into an array of `category_id LIKE "%' . $category_checked[$i] . '%"`, which you then combine using `'(' . implode(' OR ', $categories) . ')'`. Add that to your `$conditions` array. – Barmar Sep 20 '20 at 06:22
  • Don't put long code in comments, it's totally unreadable. If you have other problems, post another question so you can format it properlyl – Barmar Sep 20 '20 at 06:24
  • BTW, if you're putting lists in your `tags` column, see https://stackoverflow.com/questions/3653462/is-storing-a-delimited-list-in-a-database-column-really-that-bad – Barmar Sep 20 '20 at 06:24
  • I've moved it here [link](https://stackoverflow.com/a/63976175/10888948) – dabin_tsikin Sep 20 '20 at 06:54
  • Answers should not be used to ask additional questions. – Barmar Sep 20 '20 at 06:55
  • i'm so sorry, it's just my first time here. forgive me – dabin_tsikin Sep 20 '20 at 07:10