【问题标题】:CI3 Advanced Search Filter with Query Strings带有查询字符串的 CI3 高级搜索过滤器
【发布时间】:2018-05-03 14:22:47
【问题描述】:

我正在尝试在我的 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
  • 开始年份
  • 年底

我是否需要为每个可能的搜索组合创建一个新函数?用户可以搜索一个另一个。一个另一个。只有一个

那会是很多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

也许有更有效的方法来做到这一点?

我不想使用任何额外的库或插件。

感谢任何建议。

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢@Kisaragi 不幸的是,我发布的字段与我的数据库的名称不同,在这个阶段更改它们会涉及太多工作:/ 另外,@987654323 行不行@生产OR WHERE searchTerm = searchTerm?
    【解决方案2】:

    你可以试试这个

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

    【讨论】:

    • 您能简单解释一下代码中发生了什么吗?感谢您的回答,看起来很有希望。
    • @TheOrdinaryGeek 在代码中没有什么特别之处。当任何搜索词不为空时,它只是连接WHERE
    【解决方案3】:

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

    一个真实的例子

    控制器

    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、where)

    如果您采用这种方法,那么在不构建冗余代码片段的情况下构建动态搜索非常简单

    当然,您必须进行一些实地检查 - 但就此而言,您应该使用 Form_Validation 库。

    【讨论】:

      猜你喜欢
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-11
      • 2021-12-09
      相关资源
      最近更新 更多