Фильтр расширенного поиска CI3 со строками запроса - PullRequest
0 голосов
/ 03 мая 2018

Я пытаюсь реализовать расширенный поиск на моем сайте Codeigniter 3.

Текущая функция поиска работает нормально ( поиск по всем записям ).

У меня есть простая форма HTML с одним входом (searchTerm), это отправляет строку запроса q=. Мой основной синтаксис поиска:

$searchTerm  = $this->input->get('q'); 
if ($searchTerm) { 
    $this->db->from('records');
    $this->db->where('column1', $searchTerm); 
    $this->db->where('column2', $searchTerm);
    $this->db->where('column3', $searchTerm);
    // $this->db->where('etc', $searchTerm);
    $query = $this->db->get();
    return $query->result_array();
}

В моей базе данных приблизительно 20 столбцов.

Я хочу добавить еще три входа в мою HTML-форму, которые будут искать эти столбцы базы данных;

  • collectionId
  • startYear
  • endYear

Нужно ли создавать новую функцию для каждой возможной комбинации поиска? Пользователи могут искать один или другой. Один и другой. Просто один .

Это будет много if/else заявлений? Например;

 - if searchTerm is not empty
 - if searchTerm is not empty and startYear is not empty
 - if startYear is empty and endYear is not empty
 - etc
 - etc

Возможно, есть более эффективный способ сделать это?

Я не хочу использовать дополнительные библиотеки или плагины.

Любой совет приветствуется.

Ответы [ 3 ]

0 голосов
/ 04 мая 2018

Вы можете попробовать это

$searchTerm  = $this->input->get('q');
$searchTerm1  = $this->input->get('x');
$searchTerm2  = $this->input->get('y');
$searchTerm3  = $this->input->get('z');

if(!empty($searchTerm1)){
    $this->db->where('collectionId', $searchTerm1);
}

if(!empty($searchTerm2)){
    $this->db->where('startYear = "'.$searchTerm2.'"', NULL,FALSE);
}

if(!empty($searchTerm3)){
    $this->db->where('endYear BETWEEN "'.$searchTerm3.'" AND NOW()', NULL,FALSE);
}



if ($searchTerm) { 
    $this->db->from('records');
    $this->db->where('column1', $searchTerm); 
    $this->db->where('column2', $searchTerm);
    $this->db->where('column3', $searchTerm);
    // $this->db->where('etc', $searchTerm);
}

 $query = $this->db->get();
 return $query->result_array();
0 голосов
/ 04 мая 2018

если вы хотите автоматизировать вещи здесь, вы должны использовать другой подход, самое важное здесь - это группировать вещи

Пример из реальной жизни

Контроллер

class So extends CI_Controller
{

    public function so50157398()
    {
        if ($this->input->post())
        {
            $this->load->model('so/So50157398_model');
            $this->So50157398_model->buildSearch($this->input->post('search'));
        }
        $this->load->view('so/so50157398'); 
    }
}

View (простой шаблон начальной загрузки)

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">

    <title>Hello, world!</title>
</head>
<body>
<div class="container">
    <h1>Automatic Search Builder</h1>
    <form method="post">
        <div class="form-row">
            <div class="form-group col-md-6">
                <label for="inputEmail4">Email</label>
                <input type="email" name="search[or_where][email]" class="form-control" id="inputEmail4" placeholder="Email">
            </div>
            <div class="form-group col-md-6">
                <label for="inputPassword4">Password</label>
                <input type="password" name="search[or_where][password]" class="form-control" id="inputPassword4" placeholder="Password">
            </div>
        </div>
        <div class="form-group">
            <label for="inputAddress">Address</label>
            <input type="text" class="form-control" name="search[where][address]" id="inputAddress" placeholder="1234 Main St">
        </div>
        <div class="form-group">
            <label for="inputAddress2">Address 2</label>
            <input type="text" class="form-control" name="search[where][address2]" id="inputAddress2" placeholder="Apartment, studio, or floor">
        </div>
        <div class="form-row">
            <div class="form-group col-md-6">
                <label for="inputCity">City</label>
                <input type="text" class="form-control" name="search[where][city]" id="inputCity">
            </div>
            <div class="form-group col-md-4">
                <label for="inputState">State</label>
                <select id="inputState" name="search[where][state]" class="form-control">
                    <option selected>Choose...</option>
                    <option>Option 1</option>
                    <option>Option 2</option>
                    <option>Option 3</option>
                </select>
            </div>
            <div class="form-group col-md-2">
                <label for="inputZip">Zip</label>
                <input type="text" name="search[where][zip]" class="form-control" id="inputZip">
            </div>
        </div>
        <button type="submit" class="btn btn-primary">Sign in</button>
    </form>
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>
</body>
</html>

Модель

class So50157398_model extends CI_Model
{
    private $arrAllowedFields = ['email', 'password', 'address', 'address2', 'city', 'state', 'zip'];

    public function buildSearch($arrSearchFields)
    {
        $this->db
            ->select('*')
            ->from('records');
        foreach($arrSearchFields AS $key => $arrFields)
        {
            $this->buildQuery($key, $arrFields);
        }

        echo $this->db->get_compiled_select();
    }

    private function buildQuery($group, $arrFields)
    {
        $this->db->group_start();
        foreach($arrFields AS $key => $value)
        {
            if (in_array($key, $this->arrAllowedFields))    $this->db->$group($key, $value);
        }
        $this->db->group_end();

    }
}

Как вы можете видеть, я сгруппировал поля ввода по разным категориям (например, в этом случае или где, где)

Если вы следуете такому подходу, то довольно просто создать динамический поиск без создания избыточных кодовых фракций

конечно, вам нужно выполнить некоторые проверки полей, но для этого вам следует использовать библиотеку Form_Validation.

0 голосов
/ 03 мая 2018

Вы можете убедиться, что вы разместили поля с тем же именем, что и поля вашей базы данных, и сделать что-то вроде этого:

$search_query = $this->input->get(); //assuming your query strings are only search terms 

foreach($search_query as $search){
    $this-db->or_where($search, $search);  //or where, you could also you $this-db->where();  which will produce where and foreach element 
}
return $this-db->get('records')->result(); 

Если в строке запроса содержатся другие элементы, кроме поисковых терминов, вы можете сбросить их с $search_query перед продолжением цикла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...