【问题标题】:Codeigniter search engine BUG: results pagination items display ALL the postsCodeigniter 搜索引擎BUG:结果分页项显示所有帖子
【发布时间】:2018-10-01 15:09:02
【问题描述】:

我正在使用 Codeigniter 3.1.8 开发一个基本的博客应用程序。和 Bootstrap 4. 该应用程序具有搜索帖子功能。

标题视图中的表单:

<form method="get" action="<?php echo base_url('posts/search') ?>" id="search_form" class="w-100 py-1 px-2 px-md-3 px-lg-5" accept-charset="utf-8">
    <div class="input-group <?php if(form_error('search')) echo 'has-error';?>">
      <input class="form-control form-control-dark" type="text" name="search" placeholder="Search posts..." aria-label="Search">
      <?php if(form_error('search')) echo form_error('search'); ?> 
      <div class="input-group-append">
        <button class="btn btn-success" type="submit"><i class="fa fa-search"></i></button>
      </div>
    </div>
</form>

由于帖子是分页的,因此搜索结果也应该分页。 index()search() 方法都是同一个 Posts 控制器的一部分,所以我尽量不重复分页的代码:

private function _initPagination($path, $totalRows, $query_string_segment = 'page') {
    //load and configure pagination 
    $this->load->library('pagination');
    $config['base_url'] = base_url($path);
    $config['query_string_segment'] = $query_string_segment; 
    $config['total_rows'] = $totalRows;
    $config['per_page'] = 12;
    if (!isset($_GET[$config['query_string_segment']]) || $_GET[$config['query_string_segment']] < 1) {
      $_GET[$config['query_string_segment']] = 1;
    }
    $this->pagination->initialize($config);

    $limit = $config['per_page'];
    $offset = ($this->input->get($config['query_string_segment']) - 1) * $limit;

    return ['limit' => $limit, 'offset' => $offset];
  }

  public function index() {
    //call initialization method
    $config = $this->_initPagination("/posts", $this->Posts_model->get_num_rows());

    $data = $this->Static_model->get_static_data();
    $data['categories'] = $this->Categories_model->get_categories();

    //use limit and offset returned by _initPaginator method
    $data['posts'] = $this->Posts_model->get_posts($config['limit'], $config['offset']);
    $this->load->view('partials/header', $data);
    $this->load->view('posts');
    $this->load->view('partials/footer');
  }

  public function search() {
   // Force validation since the form's method is GET
   $this->form_validation->set_data($this->input->get());
   $this->form_validation->set_rules('search', 'Search term', 'required|trim|min_length[3]');
   $this->form_validation->set_error_delimiters('<p class = "error search-error"> ', ' </p>
       ');
    // If search fails
   if ($this->form_validation->run() === FALSE) {
       return $this->index();
   } else {
       $expression = $this->input->get('search');
       $posts_count = $this->Posts_model->search_count($expression);
       $query_string_segment = 'search=' . $expression . '&page';
       $config = $this->_initPagination("/posts/search", $posts_count, $query_string_segment);
       $data = $this->Static_model->get_static_data();
       $data['categories'] = $this->Categories_model->get_categories();
       //use limit and offset returned by _initPaginator method
       $data['posts'] = $this->Posts_model->search($expression, $config['limit'], $config['offset']);
       $data['expression'] = $expression;
       $data['posts_count'] = $posts_count;
       $this->load->view('partials/header', $data);
       $this->load->view('search');
       $this->load->view('partials/footer');
   }
} 

型号:

public function search_count($expression) {
    $query = $this->db->like('title', $expression)
                      ->or_like('description', $expression)
                      ->or_like('content', $expression);
    $query = $this->db->get('posts');
    return $query->num_rows();  
}

public function search($expression, $limit, $offset) {
    $query = $this->db->like('title', $expression)
                        ->or_like('description', $expression)
                        ->or_like('content', $expression);
    $this->db->order_by('posts.id', 'DESC');
    $query = $this->db->get('posts', $limit, $offset);
    return $query->result();
}

问题

搜索结果的第一页显示包含搜索表达式的 12 个项目,如预期,但所有其他页面,再次显示所有帖子

由于$config['query_string_segment'] 被分页使用,$query_string_segment = 'search=' . $expression . '&amp;page'; 行应该有助于通过$_GET[]搜索表达式传递到页面1、2 等等。

但是页面项目链接不保留=&amp;

<a href="http://localhost/ciblog/posts/search?search%3Dharum%26page=2" data-ci-pagination-page="2">2</a>

为什么会这样?我的错在哪里?

【问题讨论】:

  • 代替$config = $this-&gt;_initPagination("/posts/search", $posts_count);试试$config = array_merge($this-&gt;_initPagination("/posts/search", $posts_count), $config);
  • CI 中的搜索始终存在问题 我很久以前就使用过本教程,因为 CI 搜索引擎参数在 url 中不可见,但分页效果很好。 code.tutsplus.com/tutorials/…
  • @umefarooq 很棒的教程,但我宁愿没有存储搜索的表格。我用什么get(),而不是post()
  • 正如您在 search%3Dharum%26page=2 中看到的那样,= 并没有被单独编码为 %3D,因为此链接中还有另一个 =。您在代码中的什么位置创建此链接?
  • @vivek_23 我该如何解决这个问题?

标签: php codeigniter codeigniter-3


【解决方案1】:

_initPagination 方法中添加这两行解决了这个问题:

$config['enable_query_strings'] =TRUE;
$config['reuse_query_string'] =TRUE;

整个代码:

private function _initPagination($path, $totalRows, $query_string_segment = 'page') {
//load and configure pagination 
    $this->load->library('pagination');
    $config['base_url'] = base_url($path);
    $config['query_string_segment'] = $query_string_segment; 
    $config['enable_query_strings'] =TRUE;
    $config['reuse_query_string'] =TRUE;
    $config['total_rows'] = $totalRows;
    $config['per_page'] = 12;
    if (!isset($_GET[$config['query_string_segment']]) || $_GET[$config['query_string_segment']] < 1) {
        $_GET[$config['query_string_segment']] = 1;
    }
    $this->pagination->initialize($config);

    $limit = $config['per_page'];
    $offset = ($this->input->get($config['query_string_segment']) - 1) * $limit;

    return ['limit' => $limit, 'offset' => $offset];
}

public function search() {
   // Force validation since the form's method is GET
    $this->form_validation->set_data($this->input->get());
    $this->form_validation->set_rules('search', 'Search term', 'required|trim|min_length[3]');
    $this->form_validation->set_error_delimiters('<p class = "error search-error"> ', ' </p>
        ');
    // If search fails
    if ($this->form_validation->run() === FALSE) {
        return $this->index();
    } else {
        $expression = $this->input->get('search');
        $posts_count = $this->Posts_model->search_count($expression);
        $query_string_segment = 'page';
        $config = $this->_initPagination("/posts/search", $posts_count, $query_string_segment);
        $data = $this->Static_model->get_static_data();
        $data['categories'] = $this->Categories_model->get_categories();
   //use limit and offset returned by _initPaginator method
        $data['posts'] = $this->Posts_model->search($expression, $config['limit'], $config['offset']);
        $data['expression'] = $expression;
        $data['posts_count'] = $posts_count;
        $this->load->view('partials/header', $data);
        $this->load->view('search');
        $this->load->view('partials/footer');
    }
} 

【讨论】:

    【解决方案2】:

    这是一个解决方案:

    public function get_posts_search($keyword,$limit,$start){
       $this->db->where("(title LIKE '%$keyword%' || description LIKE '%$keyword%' || content LIKE '%$keyword%')");
       $this->db->limit($limit, $start);
       $query = $this->db->get('posts');
       return $query; //don't return result when your query haven't check if having a records
    }
    public function get_posts_search_total($keyword){
       $this->db->where("(title LIKE '%$keyword%' || description LIKE '%$keyword%' || content LIKE '%$keyword%')");
       $query = $this->db->get('posts');
       return $query->num_rows(); //don't return result when your query haven't check if having a records
    }
    

    【讨论】:

      猜你喜欢
      • 2017-05-03
      • 2018-06-16
      • 2014-03-26
      • 1970-01-01
      • 1970-01-01
      • 2016-01-28
      • 1970-01-01
      • 2014-02-14
      • 1970-01-01
      相关资源
      最近更新 更多