带有查询字符串的CI3高级搜索过滤器

时间:2018-05-03 14:22:48

标签: php codeigniter if-statement search codeigniter-3

我正在尝试对我的Codeigniter 3网站实施高级搜索。

当前搜索功能正常(搜索所有记录)。

我有一个带有一个输入(searchTerm)的简单HTML表单,它会发送一个查询字符串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 :(得分:0)

您可以确保发布的字段与数据库字段的名称相同,并执行以下操作:

$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取消设置。

答案 1 :(得分:0)

你可以试试这个

$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();

答案 2 :(得分:0)

如果你想在这里自动化你应该使用另一种方法,这里最重要的是分组事物

一个真实世界的例子

控制器

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'); 
    }
}

查看(一个简单的样板文件引导程序模板)

<!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();

    }
}

如您所见,我将输入字段分组为不同的类别(例如,在这种情况下为or_where,其中)

如果您遵循这种方法,那么构建动态搜索非常简单,而无需构建冗余的代码片段

当然,您需要进行一些现场检查 - 但就此而言,您应该使用Form_Validation库。