Codeigniter 3分页错误:第二页显示记录3到13而不是11到20

I am making a Codeigniter 3 application, consisting of a table (with approximately 100 rows) that I have paginated, 10 rows per page.

In the home controller I have:

public function index() {
    $this->load->model('Customer');
    $this->load->library('pagination');
    $config = [
        'base_url' => base_url("index.php"),
        'per_page' => 10,
        'total_rows' => $this->Customer->get_num_rows(),
        'uri_segment' => 3,
        'first_tag_open' =>  '<li>',
        'first_tag_close' => '</li>',
        'last_tag_open' =>  '<li>',
        'last_tag_close' => '</li>',
        'full_tag_open' =>  '<ul class="pagination">',
        'full_tag_close' => '</ul>',
        'next_tag_open' =>  '<li>',
        'next_tag_close' => '</li>',
        'prev_tag_open' =>  '<li>',
        'prev_tag_close' => '</li>',
        'num_tag_open' =>   '<li>',
        'num_tag_close' =>  '</li>',
        'cur_tag_open' =>   '<li class="active"><a>',
        'cur_tag_close' =>  '</a></li>',
    ];
    $this->pagination->initialize($config);
        $customers = $this->Customer->getCustomers($config['per_page'], $this->input->get('page'));
    $this->load->view('home', ['records'=>$customers]);
}

In the Model file I have:

class Customer extends CI_Model {
 public function __construct() {
    $this->load->database();
 }

 public function getCustomers($limit, $offset) {
    $this->db->limit($limit, $offset);
    $query = $this->db->get('customers');
    return $query->result();
 }
}

The view:

<div class="pagination-container text-center">
    <?php echo $this->pagination->create_links(); ?>
</div> 

The first page looks good (I have recieved help from the comunuty with that. Thank you!): First page

The problem is that the second page shows records 3 to 13 instead of 11 to 20: Shows records 3 to 13 instead of 11 to 21

Inside the Home controller, after the changes that made the pagination work, I now have:

public function index() {
    $this->load->model('Customer');
    $this->load->library('pagination');
    $config = [
        'base_url' => base_url("index.php"),
        'page_query_string' => TRUE,
        'query_string_segment' => 'page',
        'display_pages' => TRUE,
        'use_page_numbers' => TRUE,
        'per_page' => 10,
        'total_rows' => $this->Customer->get_num_rows(),
        'uri_segment' => 3,
        'first_link' => '&laquo;',
        'first_tag_open' =>  '<li>',
        'first_tag_close' => '</li>',
        'last_link' => '&raquo;',
        'last_tag_open' =>  '<li>',
        'last_tag_close' => '</li>',
        'full_tag_open' =>  '<ul class="pagination">',
        'full_tag_close' => '</ul>',
        'next_link' =>  '&rsaquo;',
        'next_tag_open' =>  '<li>',
        'next_tag_close' => '</li>',
        'prev_link' => '&lsaquo;',
        'prev_tag_open' =>  '<li>',
        'prev_tag_close' => '</li>',
        'num_tag_open' =>   '<li>',
        'num_tag_close' =>  '</li>',
        'cur_tag_open' =>   '<li class="active"><a>',
        'cur_tag_close' =>  '</a></li>'
    ];
    if (!isset($_GET[$config['query_string_segment']])) {
        $_GET[$config['query_string_segment']] = 1;
    }
    $limit = $config['per_page'];
    $offset = ($this->input->get($config['query_string_segment']) - 1) * $limit;
    $this->pagination->initialize($config);
    $customers = $this->Customer->getCustomers($limit, $offset);
    $this->load->view('home', ['records'=>$customers]);
}

It works fine, I hope it will help many. But I wonder if I could be simplified, written with less code...

The offset is a preview limit ( bad explain ). Example:

SELECT * FROM customers LIMIT 0, 10;

Offset is a 0 and limit 10, second page:

SELECT * FROM customers LIMIT 10, 10;

The Offset is a 10 and limit 10, third page:

SELECT * FROM customers LIMIT 20, 10;

The Offset is a 20 and limit 10, etc. Using QueryBuilder of codeigniter:

$this->db->limit( $limit, $offset );

The URL param is a offset.

Then for the instance of pagination library you have use site_url() function. base_url is to statics or assets location and site_url() to navigation page.

Check variable on config.php file $config['index_page'], if you use rewrite url to remove "index.php" then this variable have been empty else your value is a "index.php".

if you use segment param instead variable, you need add route entry. For example:

$route['customers/(:num)'] = 'Customers/index/$1';

Or with regex limiters:

$route['^customers/(:num)$'] = 'Customers/index/$1';

Remember, the url param (:num) is a offset.

Try this.

Codeigniter uses array like array() not using []

Also use a separate function to count all results from table like below

public function index() {

    $this->load->model('customer_model');
    $this->load->library('pagination');


    $config['base_url'] = base_url("controllername");
    $config['total_rows'] = $this->customer_model->count_total();
    $config['per_page'] = 10;
    $config['uri_segment'] = 2;
    $config['num_links'] = 10;

    // Bootstrap
    $config['full_tag_open'] = '<div class="pagination"><ul>';
    $config['full_tag_close'] = '</ul></div><!--pagination-->';
    $config['first_link'] = '&laquo; First';
    $config['first_tag_open'] = '<li class="prev page">';
    $config['first_tag_close'] = '</li>';
    $config['last_link'] = 'Last &raquo;';
    $config['last_tag_open'] = '<li class="next page">';
    $config['last_tag_close'] = '</li>';
    $config['next_link'] = 'Next &rarr;';
    $config['next_tag_open'] = '<li class="next page">';
    $config['next_tag_close'] = '</li>';
    $config['prev_link'] = '&larr; Previous';
    $config['prev_tag_open'] = '<li class="prev page">';
    $config['prev_tag_close'] = '</li>';
    $config['cur_tag_open'] = '<li class="active"><a href="">';
    $config['cur_tag_close'] = '</a></li>';
    $config['num_tag_open'] = '<li class="page">';
    $config['num_tag_close'] = '</li>';
    /*

      Change your uri segment number to what you want make sure though you change it in the array above also uri_segment.

    */
    $page = ($this->uri->segment(2)) ? $this->uri->segment(2) : 0;

    $this->pagination->initialize($config);

    $data['paglinks'] = $this->pagination->create_links();

    $data['records'] = $this->customer_model->getCustomers($config['per_page'], $page);

    $this->load->view('home', $data);


}

http://www.codeigniter.com/user_guide/general/views.html#creating-loops

http://www.codeigniter.com/user_guide/libraries/uri.html

http://www.codeigniter.com/user_guide/general/routing.html#examples

You may need to set your routes

$route['controllername/(:any)'] = 'controllername/index/$1';

I would rename the model to something like customer_model that way if have another file with same name does not cause error

class Customer extends CI_Model {

    public function __construct() {
       parent::__construct();  
    }

    public function getCustomers($limit, $offset) {
        $this->db->limit($limit, $offset);
        $query = $this->db->get('customers');
        return $query->result();
    }

    public function count_total()
    {
        return $this->db->count_all_results('customers');
    }

}

Autoload the database much better

$autoload['libraries'] = array('database');

With your current model method

public function getCustomers($limit, $offset) {
    $this->db->limit($limit, $offset);
    $query = $this->db->get('customers');
    return $query->result();
}

You are passing in $limit, which you are passing in as 10. Your $offset seems to be the page number as is shown by the results you are seeing.

For instance, if your uri segment value is 2 ( for page 2 ) you are effectively setting the limit in your method to be

$this->db->limit(10, 2);

which will show records 3 to 13.

You can verify this by using the following var_dump statement as debug code to inspect the values.

public function getCustomers($limit, $offset) {
    $this->db->limit($limit, $offset);
    var_dump($limit, $offset);
    $query = $this->db->get('customers');
    return $query->result();
}

If you can't see those on the page directly, you will find the output for those when you perform a view-source on your HTML in your web browser.

So what you need to do is to set the $offset to reflect the number of entries * the page number.

So Page 1 will be records with $offset = $limit * ($page - 1) = 10 * 0 = 0, with a limit of 10 will get records 1 to 10.

Page 2 should be records with $offset = $limit * ($page - 1) = 10 * 1 = 10 will give records 11-20

So this leads to the thinking that you need to rename $offset in your method parameters to $page and calculate the required $offset

public function getCustomers($limit, $page) {
    $offset = 0;
    if($page > 0) {
      $offset = $limit * ($page - 1); 
    }
    $this->db->limit($limit, $offset);
    $query = $this->db->get('customers');
    return $query->result();
}

So hopefully that helps.