<?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);其它说明:ThinkPHP 是一个免费开源的,快速、简单的面向对象的 轻量级PHP开发框架 ,创立于2006年初,遵循Apache2开源协议发布,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。并且拥有众多的原创功能和特性,在社区团队的积极参与下,在易用性、扩展性和性能方面不断优化和改进,已经成长为国内最领先和最具影响力的WEB应用开发框架,众多的典型案例确保可以稳定用于商业以及门户级的开发。