title: Codeigniter search engine BUG: results pagination items display ALL the posts
body: <p>I am working on a basic blog application with Codeigniter 3.1.8. and Bootstrap 4. The application has a search posts functionality. </p>
  
  <p>The form in the header view:</p>
  
  <pre><code>&lt;form method="get" action="&lt;?php echo base_url('posts/search') ?&gt;" id="search_form" class="w-100 py-1 px-2 px-md-3 px-lg-5" accept-charset="utf-8"&gt;
      &lt;div class="input-group &lt;?php if(form_error('search')) echo 'has-error';?&gt;"&gt;
        &lt;input class="form-control form-control-dark" type="text" name="search" placeholder="Search posts..." aria-label="Search"&gt;
        &lt;?php if(form_error('search')) echo form_error('search'); ?&gt; 
        &lt;div class="input-group-append"&gt;
          &lt;button class="btn btn-success" type="submit"&gt;&lt;i class="fa fa-search"&gt;&lt;/i&gt;&lt;/button&gt;
        &lt;/div&gt;
      &lt;/div&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>Since the posts are paginated, so should the search results. The <code>index()</code> and <code>search()</code> methods are both part of the same Posts controller, so I have tried to NOT repeat the pagination's code:</p>
  
  <pre><code>private function _initPagination($path, $totalRows, $query_string_segment = 'page') {
      //load and configure pagination 
      $this-&gt;load-&gt;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']] &lt; 1) {
        $_GET[$config['query_string_segment']] = 1;
      }
      $this-&gt;pagination-&gt;initialize($config);
  
      $limit = $config['per_page'];
      $offset = ($this-&gt;input-&gt;get($config['query_string_segment']) - 1) * $limit;
  
      return ['limit' =&gt; $limit, 'offset' =&gt; $offset];
    }
  
    public function index() {
      //call initialization method
      $config = $this-&gt;_initPagination("/posts", $this-&gt;Posts_model-&gt;get_num_rows());
  
      $data = $this-&gt;Static_model-&gt;get_static_data();
      $data['categories'] = $this-&gt;Categories_model-&gt;get_categories();
  
      //use limit and offset returned by _initPaginator method
      $data['posts'] = $this-&gt;Posts_model-&gt;get_posts($config['limit'], $config['offset']);
      $this-&gt;load-&gt;view('partials/header', $data);
      $this-&gt;load-&gt;view('posts');
      $this-&gt;load-&gt;view('partials/footer');
    }
  
    public function search() {
     // Force validation since the form's method is GET
     $this-&gt;form_validation-&gt;set_data($this-&gt;input-&gt;get());
     $this-&gt;form_validation-&gt;set_rules('search', 'Search term', 'required|trim|min_length[3]');
     $this-&gt;form_validation-&gt;set_error_delimiters('&lt;p class = "error search-error"&gt; ', ' &lt;/p&gt;
         ');
      // If search fails
     if ($this-&gt;form_validation-&gt;run() === FALSE) {
         return $this-&gt;index();
     } else {
         $expression = $this-&gt;input-&gt;get('search');
         $posts_count = $this-&gt;Posts_model-&gt;search_count($expression);
         $query_string_segment = 'search=' . $expression . '&amp;page';
         $config = $this-&gt;_initPagination("/posts/search", $posts_count, $query_string_segment);
         $data = $this-&gt;Static_model-&gt;get_static_data();
         $data['categories'] = $this-&gt;Categories_model-&gt;get_categories();
         //use limit and offset returned by _initPaginator method
         $data['posts'] = $this-&gt;Posts_model-&gt;search($expression, $config['limit'], $config['offset']);
         $data['expression'] = $expression;
         $data['posts_count'] = $posts_count;
         $this-&gt;load-&gt;view('partials/header', $data);
         $this-&gt;load-&gt;view('search');
         $this-&gt;load-&gt;view('partials/footer');
     }
  } 
  </code></pre>
  
  <p>The model:</p>
  
  <pre><code>public function search_count($expression) {
      $query = $this-&gt;db-&gt;like('title', $expression)
                        -&gt;or_like('description', $expression)
                        -&gt;or_like('content', $expression);
      $query = $this-&gt;db-&gt;get('posts');
      return $query-&gt;num_rows();  
  }
  
  public function search($expression, $limit, $offset) {
      $query = $this-&gt;db-&gt;like('title', $expression)
                          -&gt;or_like('description', $expression)
                          -&gt;or_like('content', $expression);
      $this-&gt;db-&gt;order_by('posts.id', 'DESC');
      $query = $this-&gt;db-&gt;get('posts', $limit, $offset);
      return $query-&gt;result();
  }
  </code></pre>
  
  <p>The <strong>PROBLEM</strong>:</p>
  
  <p>The first page of search results displays 12 items containing the search expression, <em>as expected</em>, but  all the other pages, display <em>all the posts again</em>. </p>
  
  <p>Since <code>$config['query_string_segment']</code> is used by the pagination, the line <code>$query_string_segment = 'search=' . $expression . '&amp;page';</code> should help pass the <em>search expression</em>, via <code>$_GET[]</code>, to the pages 1, 2 and so on. </p>
  
  <p>But the page items link does not keep <code>=</code> and <code>&amp;</code>:</p>
  
  <pre><code>&lt;a href="http://localhost/ciblog/posts/search?search%3Dharum%26page=2" data-ci-pagination-page="2"&gt;2&lt;/a&gt;
  </code></pre>
  
  <p>Why does that happen? Where is my mistake?</p>