TP 3.2 的分页优化

浏览:1065 发布日期:2019/04/04 分类:功能实现
TP 5 分页很方便,但 TP 3.2 分页就很麻烦,为维护老项目,就动手作了优化。
TP 5 分页很方便,但 TP 3.2 分页就很麻烦。虽然现在新项目都是用 TP 5,但很多老项目还是用 TP 3.2,为维护方便,还是动手去优化了 TP 3.2 的分页实现。

TP 3.2 分页,有几个方面要处理:
1)取得当前页号、每页数据条数;
2)取得指定页面数据;
3)渲染分页导航 html 代码。

2019-04-15 bug 修复:修复可能出现页数错误的 bug

直接先看代码:

一、添加分页类:<?php
/**
 * User: Aven
 * Date: 2019-04-03
 * Time: 14:14
 */

namespace Lib;


use Think\Page;

class Paginator implements \ArrayAccess,\Countable,\IteratorAggregate
{
    protected $_items = [];
    protected $rowsList;
    protected $options;
    protected $totalRows;
    protected $prev;
    protected $next;

    function __construct($items, $totalRows, $rowsList = 15, $options = [])
    {
        $this->_items = $items;
        $this->rowsList = $rowsList;
        $this->options = $options;
        $this->totalRows = $totalRows;
    }

    public function render()
    {
        $page = new Page($this->totalRows, $this->rowsList);
        if ($this->prev){
            $page->setConfig('prev', $this->prev);
        }
        if ($this->next){
            $page->setConfig('next', $this->next);
        }
        return $page->show();
    }

    public function items()
    {
        return $this->_items;
    }

    public function each(callable $callback)
    {
        foreach ($this->_items as $key => $item) {
            $result = $callback($item, $key);
            if (false === $result) {
                break;
            } elseif (!is_object($item)) {
                $this->_items[$key] = $result;
            }
        }

        return $this;
    }

    public function setPrev($prev){
        $this->prev = $prev;
        return $this;
    }

    public function setNext($next) {
        $this->next = $next;
        return $this;
    }

    public function slice($offset, $length = null, $preserveKeys = false)
    {
        return array_slice($this->_items, $offset, $length, $preserveKeys);
    }

    public function count()
    {
        return count($this->_items);
    }

    public function offsetExists($offset)
    {
        return isset($this->_items[$offset]);
    }

    public function offsetGet($offset)
    {
        return $this->offsetExists($offset) ? $this->_items[$offset] : null;
    }

    public function offsetSet($offset, $value)
    {
        $this->_items[$offset] = $value;
    }

    public function offsetUnset($offset)
    {
        unset($this->_items[$offset]);
    }

    public function getIterator()
    {
        return new \ArrayIterator($this->_items);
    }
}
二、修改 Model 类,为 model 添加功能。// $rowsList 为每页数据条数
// $data_only 为 true 时,只返回数据,不作渲染、不统计数据总条数,提高性能,主要为接口提供数据用。
// 2019-04-15 bug 修复
public function paginate($rowsList = 15, $data_only = false)
    {
        $currentPage = I(C('VAR_PAGE') ? C('VAR_PAGE') : 'p', 1);

        // 添加一行,备份 options,因为每进行一次查询,都会清了 options。
        $options = $this->options;

        $items = $this->page($currentPage, $rowsList)->select();
        if ($data_only){
            return $items;
        }

        // 添加一行,恢复 options。
        $this->options = $options;

        $totalRows = $this->count();
        return new \Lib\Paginator($items, $totalRows, $rowsList);
    }
三、修改模板渲染文件,让 volist 标签识别分页类数据。修改以下的代码即可。    $parseStr  .=  'if(is_array('.$name.') || ' . $name . ' instanceof \Lib\Paginator): $'.$key.' = 0;';
    if(isset($tag['length']) && '' != $tag['length'] ) {
        $parseStr  .= ' $__LIST__ = ' . $name . ' instanceof \Lib\Paginator ? ' . $name . '->array_slice(' . $name.','.$tag['offset'].','.$tag['length'] . ',true) : array_slice('.$name.','.$tag['offset'].','.$tag['length'].',true);';
    }elseif(isset($tag['offset'])  && '' !=$tag['offset']){
        $parseStr  .= ' $__LIST__ = ' . $name . ' instanceof \Lib\Paginator ? ' . $name . '->array_slice(' . $name.','.$tag['offset'].','.$tag['length'] . ',true) : array_slice('.$name.','.$tag['offset'].',null,true);';
    }else{
         $parseStr .= ' $__LIST__ = ' . $name . ';';
    }
四、现在使用就简单了:$data = M('User')->where(array('rank' => 2))->order('id asc')->paginate(20);

//只要数据就这样
$data = M('User')->paginate(20, true);
其它说明:
1)页号参数,按 TP 3.2 的分页类,默认为 p,可以在配置文件中配置 VAR_PAGE 即可。
2)分页也像 TP 5 的分页一样,带 each 方法。
3)本次优化,是实现主要的、常用的功能,要实现其它功能,看官自行完善。
评论( 相关
后面还有条评论,点击查看>>