CI分頁類文件Pagination.php

轉載自:https://blog.csdn.net/Zhihua_W/article/details/53083423

CodeIgniter 的分頁類非常容易使用,而且它 100% 可定製,可以通過動態的參數,也可以通過保存在配置文件中的參數。如果你還不熟悉 “分頁” 這個詞,它指的是用於你在頁面之間進行導航的鏈接。像下面這樣:

« First < 1 2 3 4 5 > Last »
舉個例子說明如何在你的控制器方法中創建分頁:

Ⅰ 在構造函數中引入分頁類:

	public function __construct(){
		parent::__construct();
		$this->load->library('form_validation');
		$this->load->model('goodstype_model');
		$this->load->library('pagination');//引入分頁類
	}

Ⅱ 設置配置參數,然後初始化調用輸出:

	public function index($offset = '')
	{
		//配置分頁信息
		$config['base_url'] = site_url('admin/goodstype/index');
		//獲取數據庫總條數
		$config['total_rows'] = $this->goodstype_model->count_goodstype();
		//每頁顯示條數
		$config['per_page'] = 2;
		//頁碼參數位置
		$config['uri_segment'] = 4;
 
		//自定義分頁連接
		$config['first_link'] = '首頁';
		$config['last_link'] = '尾頁';
		$config['prev_link'] = '上一頁';
		$config['next_link'] = '下一頁';
 
		//初始化分類頁
		$this->pagination->initialize($config);
		//生成分頁信息
		//可以輸出查看結果是一串html字符串
		$data['pageinfo'] = $this->pagination->create_links();
		$limit = $config['per_page'];
		$data['goodstypes'] = $this->goodstype_model->list_goodstype($limit,$offset);
		$this->load->view('goods_type_list.html',$data);
	}
`

CI框架的分頁類非常的好用,可以讓我們隨心所欲的去修改定製。但是在這裏要說的是,CI框架的分頁功能僅僅只是提供一個顯示功能,不存在任何和數據庫進行交互的作用,它所顯示的僅僅只是一個連接,其具體的數據查詢功能,數據顯示功能還是要我們自己在模型中進行編寫,這是CI框架的分頁類和其他框架所不同的地方。大家要注意。好了,本篇就說這麼多,其實分頁類的代碼功能還是非常簡單明瞭的,只要稍微的看一篇就能明白其具體的實現過程。

最後貼一下CI框架整個分頁類Pagination.php文件的源代碼(註釋版):
    <?php
    
    /**
     * =======================================
     * Created by Pocket Knife Technology.
     * User: ZhiHua_W
     * Date: 2016/11/08 0041
     * Time: 下午 4:14
     * Project: CodeIgniter框架—源碼分析
     * Power: Analysis for Pagination.php
     * =======================================
     */
    
    defined('BASEPATH') OR exit('No direct script access allowed');
    
    /**
     * 用於生成分頁連接
     */
    class CI_Pagination
    {
        //每次訪問的url地址
        protected $base_url = '';
        //給路徑添加一個自定義前綴,前綴位於偏移段的前面
        protected $prefix = '';
        //給路徑添加一個自定義後綴,後綴位於偏移段的後面。
        protected $suffix = '';
        //這個數字表示你需要做分頁的數據的總行數。通常這個數值是你查詢數據庫得到的數據總量。
        protected $total_rows = 0;
        //放在你當前頁碼的前面和後面的“數字”鏈接的數量。
        //比方說值爲 2 就會在每一邊放置兩個數字鏈接,就像此頁頂端的示例鏈接那樣。
        protected $num_links = 2;
        //這個數字表示每個頁面中希望展示的數量,在上面的那個例子中,每頁顯示 10 個項目。
        public $per_page = 10;
        //當前頁
        public $cur_page = 0;
        //默認分頁的 URL 中顯示的是你當前正在從哪條記錄開始分頁,
        //如果你希望顯示實際的頁數,將該參數設置爲 TRUE 。
        protected $use_page_numbers = FALSE;
        //首頁,左邊第一個鏈接顯示的文本,如果你不想顯示該鏈接,將其設置爲 FALSE 。
        protected $first_link = '‹ First';
        //下一頁,下一頁鏈接顯示的文本,如果你不想顯示該鏈接,將其設置爲 FALSE 。
        protected $next_link = FALSE;
        //下一頁,下一頁鏈接顯示的文本,如果你不想顯示該鏈接,將其設置爲 FALSE
        protected $prev_link = FALSE;
        //尾頁,右邊第一個鏈接顯示的文本,如果你不想顯示該鏈接,將其設置爲 FALSE 。
        protected $last_link = 'Last ›';
        //分頁方法自動檢測你 URI 的哪一段包含頁數,如果你的情況不一樣,你可以明確指定它
        protected $uri_segment = 4;
        //起始標籤放在所有結果的左側。
        //你可以在標籤裏面寫任意的樣式等等
        //不過樣式最好的還是採取分離的方式寫最好,僅在這邊添加不同的class就可以了
        protected $full_tag_open = '<ul class="pagination pagination-sm">';
        //結束標籤放在所有結果的右側。
        protected $full_tag_close = '</ul>';
        //第一個鏈接的起始標籤。
        protected $first_tag_open = '<li>';
        //第一個鏈接的結束標籤。
        protected $first_tag_close = '</li>';
        //最後一個鏈接的起始標籤。
        protected $last_tag_open = '<li>';
        //最後一個鏈接的結束標籤。
        protected $last_tag_close = '</li>';
        //首頁url
        protected $first_url = '';
        //當前頁鏈接的起始標籤。
        protected $cur_tag_open = '<li class="active"><a href="javascript:;">';
        //當前頁鏈接的結束標籤。
        protected $cur_tag_close = '</a></li>';
        //下一頁鏈接的起始標籤。
        protected $next_tag_open = '<li>';
        //下一頁鏈接的結束標籤。
        protected $next_tag_close = '</li>';
        //上一頁鏈接的起始標籤。
        protected $prev_tag_open = '<li>';
        //上一頁鏈接的結束標籤。
        protected $prev_tag_close = '</li>';
        //數字鏈接的起始標籤。
        protected $num_tag_open = '<li>';
        //數字鏈接的結束標籤。
        protected $num_tag_close = '</li>';
        //默認情況下,分頁類假設你使用 URI 段 ,並像這樣構造你的鏈接:
        //http://example.com/index.php/test/page/20
        protected $page_query_string = FALSE;
        protected $query_string_segment = 'per_page';
        //如果你不想顯示數字鏈接(例如你只想顯示上一頁和下一頁鏈接),你可以通過下面的代碼來阻止它顯示
        protected $display_pages = TRUE;
        //如果你想爲分頁類生成的每個鏈接添加額外的屬性
        protected $_attributes = '';
        //連接類型
        protected $_link_types = array();
        //默認情況下你的查詢字符串參數會被忽略,將這個參數設置爲 TRUE ,
        //將會將查詢字符串參數添加到 URI 分段的後面以及 URL 後綴的前面
        protected $reuse_query_string = FALSE;
        //當該參數設置爲 TRUE 時,會使用 application/config/config.php
        //配置文件中定義的 $config['url_suffix'] 參數 重寫 $config['suffix'] 的值
        protected $use_global_url_suffix = FALSE;
        //給數字增加屬性
        protected $data_page_attr = 'data-ci-pagination-page';
        //CI Singleton
        protected $CI;
    
        /**
         * 構造函數->處理數據
         * 在使用加載此類之後,設置一些數據例如:
         * //配置分頁信息
         * $config['base_url'] = site_url('admin/goodstype/index');
         * $config['total_rows'] = $this->goodstype_model->count_goodstype();
         * $config['per_page'] = 2;
         * $config['uri_segment'] = 4;
         *
         * //自定義分頁連接
         * $config['first_link'] = '首頁';
         * $config['last_link'] = '尾頁';
         * $config['prev_link'] = '上一頁';
         * $config['next_link'] = '下一頁';
         */
        public function __construct($params = array())
        {
            $this->CI = &get_instance();
            $this->CI->load->language('pagination');
            foreach (array('first_link', 'next_link', 'prev_link', 'last_link') as $key) {
                if (($val = $this->CI->lang->line('pagination_' . $key)) !== FALSE) {
                    $this->$key = $val;
                }
            }
            $this->initialize($params);
            log_message('info', 'Pagination Class Initialized');
        }
    
        /**
         * 初始化
         * 功能同樣是處理參數
         */
        public function initialize(array $params = array())
        {
            isset($params['attributes']) OR $params['attributes'] = array();
            if (is_array($params['attributes'])) {
                $this->_parse_attributes($params['attributes']);
                unset($params['attributes']);
            }
    
            if (isset($params['anchor_class'])) {
                empty($params['anchor_class']) OR $attributes['class'] = $params['anchor_class'];
                unset($params['anchor_class']);
            }
    
            foreach ($params as $key => $val) {
                if (property_exists($this, $key)) {
                    $this->$key = $val;
                }
            }
    
            if ($this->CI->config->item('enable_query_strings') === TRUE) {
                $this->page_query_string = TRUE;
            }
    
            if ($this->use_global_url_suffix === TRUE) {
                $this->suffix = $this->CI->config->item('url_suffix');
            }
    
            return $this;
        }
    
        /**
         * 創建分頁連接
         * 這個就是我們需要條用到的了,這個函數最後會返回一串html代碼,
         * 而我們僅將這段html代碼在前臺顯示即可。
         * CI框架的分頁類和TP框架的分頁類有這明顯的差別。
         * CI僅是提供分頁顯示,並不提供其和數據庫交互的功能。
         * 這也就讓我們可以對其進行100%的定製。
         * 非常的小巧方便。
         */
        public function create_links()
        {
            //我們在初始化的時候必須要有數據總條數和每頁顯示條數
            if ($this->total_rows == 0 OR $this->per_page == 0) {
                return '';
            }
            //計算頁面總數
            $num_pages = (int)ceil($this->total_rows / $this->per_page);
            //如果只有一頁,則直接然會空字符串
            if ($num_pages === 1) {
                return '';
            }
            //檢查用戶定義的鏈接數
            $this->num_links = (int)$this->num_links;
            if ($this->num_links < 0) {
                show_error('Your number of links must be a non-negative number.');
            }
    
            //保留任何現有的查詢字符串項目。
            //注:與任何其他查詢字符串選項無關。
            if ($this->reuse_query_string === TRUE) {
                $get = $this->CI->input->get();
                unset($get['c'], $get['m'], $get[$this->query_string_segment]);
            } else {
                $get = array();
            }
    
            //處理我們的基礎網址和第一個網址
            $base_url = trim($this->base_url);
            $first_url = $this->first_url;
            $query_string = '';
            $query_string_sep = (strpos($base_url, '?') === FALSE) ? '?' : '&';
            if ($this->page_query_string === TRUE) {
                //如果自定義first_url還沒有被確定,我們會從base_url創建一個網頁,但沒有項目。
                if ($first_url === '') {
                    $first_url = $base_url;
                    if (!empty($get)) {
                        $first_url .= $query_string_sep . http_build_query($get);
                    }
                }
                $base_url .= $query_string_sep . http_build_query(array_merge($get, array($this->query_string_segment => '')));
            } else {
                //生成我們保存的查詢字符串,以在頁面號以後追加。
                if (!empty($get)) {
                    $query_string = $query_string_sep . http_build_query($get);
                    $this->suffix .= $query_string;
                }
                if ($this->reuse_query_string === TRUE && ($base_query_pos = strpos($base_url, '?')) !== FALSE) {
                    $base_url = substr($base_url, 0, $base_query_pos);
                }
                if ($first_url === '') {
                    $first_url = $base_url . $query_string;
                }
    
                $base_url = rtrim($base_url, '/') . '/';
            }
    
            //確定當前頁號。
            $base_page = ($this->use_page_numbers) ? 1 : 0;
            //判斷我們是否使用查詢字符串
            if ($this->page_query_string === TRUE) {
                $this->cur_page = $this->CI->input->get($this->query_string_segment);
            } elseif (empty($this->cur_page)) {
                //如果uri_segment一個沒有被定義,默認的最後一個段的數字。
                if ($this->uri_segment === 0) {
                    $this->uri_segment = count($this->CI->uri->segment_array());
                }
                $this->cur_page = $this->CI->uri->segment($this->uri_segment);
                //從該段中刪除任何指定的前綴/後綴。
                if ($this->prefix !== '' OR $this->suffix !== '') {
                    $this->cur_page = str_replace(array($this->prefix, $this->suffix), '', $this->cur_page);
                }
            } else {
                $this->cur_page = (string)$this->cur_page;
            }
            if (!ctype_digit($this->cur_page) OR ($this->use_page_numbers && (int)$this->cur_page === 0)) {
                $this->cur_page = $base_page;
            } else {
                //確保我們使用的是比較後的整數。
                $this->cur_page = (int)$this->cur_page;
            }
            if ($this->use_page_numbers) {
                if ($this->cur_page > $num_pages) {
                    $this->cur_page = $num_pages;
                }
            } elseif ($this->cur_page > $this->total_rows) {
                $this->cur_page = ($num_pages - 1) * $this->per_page;
            }
    
            $uri_page_number = $this->cur_page;
            //如果我們使用的是偏移量而不是頁面號,將它轉換爲一個頁面號,
            //這樣我們就可以生成周圍的數字鏈接了。
            if (!$this->use_page_numbers) {
                $this->cur_page = (int)floor(($this->cur_page / $this->per_page) + 1);
            }
    
            //計算開始和結束的數字。這些決定開始和結束數字鏈接的數量。
            $start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1;
            $end = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages;
    
            //這個變量就是最後返回的字符串
            $output = '';
    
            //生成首頁鏈接
            if ($this->first_link !== FALSE && $this->cur_page > ($this->num_links + 1 + !$this->num_links)) {
                //爲html代碼添加設置的js屬性
                $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, 1);
                $output .= $this->first_tag_open . '<a href="' . $first_url . '"' . $attributes . $this->_attr_rel('start') . '>' . $this->first_link . '</a>' . $this->first_tag_close;
            }
    
            // 生成上一頁鏈接
            //我個人感覺生成上一頁的這個連接沒用,我們本身已經有了和相鄰的頁面連接
            //故而上一頁和下一頁在我看來沒有用處,我一般都是將此段和下一頁都注視掉
            if ($this->prev_link !== FALSE && $this->cur_page !== 1) {
                $i = ($this->use_page_numbers) ? $uri_page_number - 1 : $uri_page_number - $this->per_page;
                $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, ($this->cur_page - 1));
                if ($i === $base_page) {
                    $output .= $this->prev_tag_open . '<a href="' . $first_url . '"' . $attributes . $this->_attr_rel('prev') . '>' . $this->prev_link . '</a>' . $this->prev_tag_close;
                } else {
                    $append = $this->prefix . $i . $this->suffix;
                    $output .= $this->prev_tag_open . '<a href="' . $base_url . $append . '"' . $attributes . $this->_attr_rel('prev') . '>' . $this->prev_link . '</a>' . $this->prev_tag_close;
                }
            }
            //渲染頁面
            //也就是將你設置的所需要添加的html標籤代碼,屬性,都給加上
            if ($this->display_pages !== FALSE) {
                for ($loop = $start - 1; $loop <= $end; $loop++) {
                    $i = ($this->use_page_numbers) ? $loop : ($loop * $this->per_page) - $this->per_page;
                    $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, $loop);
                    if ($i >= $base_page) {
                        if ($this->cur_page === $loop) {
                            $output .= $this->cur_tag_open . $loop . $this->cur_tag_close;
                        } elseif ($i === $base_page) {
                            $output .= $this->num_tag_open . '<a href="' . $first_url . '"' . $attributes . $this->_attr_rel('start') . '>' . $loop . '</a>' . $this->num_tag_close;
                        } else {
                            $append = $this->prefix . $i . $this->suffix;
                            $output .= $this->num_tag_open . '<a href="' . $base_url . $append . '"' . $attributes . '>' . $loop . '</a>' . $this->num_tag_close;
                        }
                    }
                }
            }
            //生成下一頁連接
            //不多說
            if ($this->next_link !== FALSE && $this->cur_page < $num_pages) {
                $i = ($this->use_page_numbers) ? $this->cur_page + 1 : $this->cur_page * $this->per_page;
                $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, $this->cur_page + 1);
                $output .= $this->next_tag_open . '<a href="' . $base_url . $this->prefix . $i . $this->suffix . '"' . $attributes . $this->_attr_rel('next') . '>' . $this->next_link . '</a>' . $this->next_tag_close;
            }
            //生成最後一頁(尾頁)連接
            if ($this->last_link !== FALSE && ($this->cur_page + $this->num_links + !$this->num_links) < $num_pages) {
                $i = ($this->use_page_numbers) ? $num_pages : ($num_pages * $this->per_page) - $this->per_page;
                $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, $num_pages);
                $output .= $this->last_tag_open . '<a href="' . $base_url . $this->prefix . $i . $this->suffix . '"' . $attributes . '>' . $this->last_link . '</a>' . $this->last_tag_close;
            }
            //將生成的結果html代碼字符串進行處理
            $output = preg_replace('#([^:"])//+#', '\\1/', $output);
            //如果存在添加封裝HTML
            return $this->full_tag_open . $output . $this->full_tag_close;
        }
    
        /**
         * 解析屬性
         */
        protected function _parse_attributes($attributes)
        {
            isset($attributes['rel']) OR $attributes['rel'] = TRUE;
            $this->_link_types = ($attributes['rel']) ? array('start' => 'start', 'prev' => 'prev', 'next' => 'next') : array();
            unset($attributes['rel']);
            $this->_attributes = '';
            foreach ($attributes as $key => $value) {
                $this->_attributes .= ' ' . $key . '="' . $value . '"';
            }
        }
    
        /**
         * 添加“關係”屬性
         */
        protected function _attr_rel($type)
        {
            if (isset($this->_link_types[$type])) {
                unset($this->_link_types[$type]);
                return ' rel="' . $type . '"';
            }
            return '';
        }
    
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章