PHP MySQL поиск по нескольким критериям

У меня есть форма поиска на веб-сайте, и я хотел бы иметь несколько условий поиска, которые вводятся пользователем для выполнения поиска в базе данных, условия, указанные ниже:

  • Ключевые слова
  • Недвижимость на продажу (продажа, аренда ...)
  • Тип недвижимости (Квартира, Дом с террасой ...)
  • Состояние
  • Минимальная цена
  • Макс Цена

Вот сценарий для выполнения поиска с вводом вышеуказанного термина

public function get_property_list_by_search($start, $per_page, $keyword, $prop_for, $min, $state, $ptype, $max, $mysqli)
{
    if(empty($start) && empty($per_page))
    {
        return 0;
    }

    $start = preg_replace('/[^0-9]/', '', $mysqli->real_escape_string($start));
    $per_page = preg_replace('/[^0-9]/', '', $mysqli->real_escape_string($per_page));
    $keyword = $mysqli->real_escape_string(stripslashes($keyword));
    $prop_for = $mysqli->real_escape_string(stripslashes($prop_for));
    $state = $mysqli->real_escape_string(stripslashes($state));
    $ptype = $mysqli->real_escape_string(stripslashes($ptype));
    $min_price = self::num_clean($mysqli->real_escape_string($min));
    $max_price = self::num_clean($mysqli->real_escape_string($max));

    $t1 = '';
    $t2 = '';
    $t3 = '';
    $t4 = '';
    $t5 = '';

    if(isset($keyword) && !empty($keyword)){
        $t1 = " AND `proj_title` LIKE '%".$keyword."%' OR `proj_addr` LIKE '%".$keyword."%' OR `proj_area` LIKE '%".$keyword."%'";
    }
    if(isset($prop_for) && !empty($prop_for)){
        $t2 = " AND `proj_for`='".$prop_for."'";
    }
    if(isset($state) && !empty($state)){
        $t3 = " AND `state`='".$state."'";
    }
    if(isset($ptype) && !empty($ptype)){
        $t4 = " AND `proj_cat`='".$ptype."'";
    }
    //min & max
    if((isset($min_price) && !empty($min_price)) && (isset($max_price) && !empty($max_price))){
        $t5 = " AND `price` BETWEEN '".$min_price."' AND '".$max_price."'";
    }
    //min only
    if(!empty($min_price) && empty($max_price)){
        $t5 = " AND `price` >= '".$min_price."'";
    }
    //max only
    if(empty($min_price) && !empty($max_price)){
        $t5 = " AND `price` <= '".$max_price."'";
    }

    $sql = $mysqli->query("SELECT * FROM `project` WHERE `status`='1' ".
    $t1." ".$t2." ".$t3." ".$t4." ".$t5." ".
    "ORDER BY `posted_date` DESC LIMIT ".$start.", ".$per_page);

    if($sql->num_rows > 0){
        return $sql;
    }else{
        return false;
    }
} 

Результат запроса будет примерно таким:

SELECT * FROM `project` 
WHERE `proj_title` LIKE '%keywords%' 
OR `proj_addr` LIKE '%keywords%' 
OR `proj_area` LIKE '%keywords%' 
AND `proj_for`='Sale' AND `state`='Somewhere' AND `proj_cat`='8' AND `price` BETWEEN '250000' AND '600000'

(Тип данных для price - DECIMAL(10,2), в нем хранится значение типа 250000.00)

Однако возвращенные результаты не соответствуют ожидаемым (не точны), также будет получен результат с ценой более 600000 и категорией проекта, которая находится из 8, что не нравится конечному пользователю для поиска на веб-сайте.

есть ли способ уточнить запрос, чтобы выполнить более конкретный запрос?


person conmen    schedule 09.10.2014    source источник


Ответы (3)


Вместо использования этих переменных следует использовать оператор «. =».

/*      $t1 = '';
        $t2 = '';
        $t3 = '';
        $t4 = '';
        $t5 = '';
*/
        $q = "SELECT * FROM `property` WHERE `status`='1' ";

// You need to enclose all **OR** logical tests in parenthesis.
// Moreover most of the usages of isset function are useless,
// as your are initializing many variables

        if($keyword && !empty($keyword)){
            $q .= " AND (`p_title` LIKE '%".$keyword."%' OR `address` LIKE '%".$keyword."%' OR `area` LIKE '%".$keyword."%')";
        }
        if($prop_for && !empty($prop_for)){
// If you are using double quotes you really don't need  handle to concatenation.
        $q .= " AND `p_for`='$prop_for'";
        }
        if($state && !empty($state)){
            $q .= " AND `state`='$state'";
        }
        if($ptype && !empty($ptype)){
            $q .= " AND `p_category`='$ptype'";
        }
        //min only
        if($min_price && !empty($min_price)){
            $q .= " AND `price` >= '".$min_price."'";
        }
        //max only
        if($max_price && !empty($max_price)){
            $q .= " AND `price` <= '$max_price'";
        }

// When you are not using OFFSET keyword,
//the first number after LIMIT keyword should be the number of records
                $q .= " ORDER BY `posted_date` DESC LIMIT $per_page , $start;";
                $sql = $mysqli->query($q);
person gahse    schedule 09.10.2014
comment
Спасибо чувак. Могу я поучиться у тебя? как я могу вывести запрос для проверки цели из класса? Я до сих пор не знаю, что не так с запросом, вызвавшим сбой. - person conmen; 09.10.2014
comment
Конечно, @conmen, :) вы можете добавить меня на FB (fb.com/gahse). Я просто прошу вас добавить echo $ q; перед этой строкой $ sql = $ mysqli- ›query ($ q); Это вернет строку запроса, затем вы можете скопировать эту строку и вставить ее в любой клиент MySql, например phpmyadmin или sqlyog. Это поможет вам удалить все синтаксические ошибки. - person gahse; 09.10.2014

Вам понадобятся скобки.

SELECT * FROM `project` WHERE (`proj_title` LIKE '%keywords%' OR `proj_addr` LIKE '%keywords%' OR `proj_area` LIKE '%keywords%') AND `proj_for`='Sale' AND `state`='Somewhere' AND `proj_cat`='8' AND `price` BETWEEN '250000' AND '600000'

Без скобок он просто должен соответствовать одному из критериев перед последним ИЛИ.

person cjc    schedule 09.10.2014

person    schedule
comment
Я хочу выполнить поиск в этом поле с выбором или без выбора пользователем. если не выбирайте, чем все, что нужно, по условию поиска, что я делаю - person Rahul Kashyap; 14.05.2015