分页


使用分页的方法

获取分页数据

获取表的分页数据, 只需要调用find()方法即可, find方法的定义如下

/**
 * 带分页的数据查询
 *
 * @param string $table
 * @param string $fields 字段名
 * @param string|array $where
 * @param int $order
 * @param array $page
 * @param int $group_by
 * @return mixed
 */
public function find($table, $fields, $where, $order = 1, & $page = array('p' => 1, 'limit' => 50), $group_by = 1)
{
    if (!isset($page['result_count'])) {
        $total = $this->get($table, 'COUNT(*) as total', $where);
        $page['result_count'] = (int)$total['total'];
    }

    $page['limit'] = max(1, (int)$page['limit']);
    $page['total_page'] = ceil($page['result_count'] / $page['limit']);

    if ($page['p'] <= $page['total_page']) {
        $page['p'] = max(1, $page['p']);
        $this->SQLAssembler->find($table, $fields, $where, $order, $page, $group_by);
        return $this->getPrepareResult(true);
    }

    return array();
}

第五个参数为一个引用值, 在外部传入这个参数时, 会返回当前条件下表的总记录条数和总页数.

在控制器中获取指定页数的数据

在控制器中,我们可以根据当前的URI参数获取要读取的哪一页的数据, 一般使用方法如下:

namespace app\web\controllers;

use modules\publish\IndexModule;

class Search extends Controller
{

    /**
     * @var IndexModule
     */
    protected $INDEX;

    function __construct()
    {
        parent::__construct();
        $this->INDEX = new IndexModule();
    }

    function index()
    {
        $page = array(
            'p' =>  isset($this->params['p']) ? (int) $this->params['p'] : 1,
            'limit' =>  15,
            'link'  =>  array('search', array()),
			'half'  =>  5,
        );

        $this->data['list'] = $this->INDEX->listIndex($page);
        $this->data['page'] = $page;
        $this->display($this->data);
    }
}

当前页数, 和每页条数, 一起放入$page变量中, 传给modules\publish\IndexModule中的listIndex方法:

/**
 * 索引列表
 *
 * @param array $page
 * @return mixed
 */
function listIndex(& $page = array('p' => 1, 'limit' => 50))
{
    return $this->link->find($this->t_index, '*', array(), 1, $page);
}

然后我们在控制器中通过$this->data['page']将分页数据传给视图控制器

扩展模板

在视图控制器中增加一个用于处理分页的方法

function page(array $data, $tpl = 'default')
{
    if (!isset($data['link'])) {
        $params = array();
        $current_controller = lcfirst($this->controller);
        $controller = "{$current_controller}:{$this->action}";
    } elseif (is_array($data['link']) && $data['link'][1]) {
        list($controller, $params) = $data['link'];
    } elseif (is_array($data['link'])) {
        $params = array();
        $controller = $data['link'][0];
    } else {
        $params = array();
        $controller = $data['link'];
    }

    if (!isset($data['anchor'])) {
        $data['anchor'] = '';
    }

    $data['controller'] = $controller;
    $data['params'] = $params;

    if (!isset($data['half'])) {
        $data['half'] = 5;
    }

    include $this->tpl("page/{$tpl}");
}

分页处理方法一共接收2个参数

$data 数据
$tpl 分页模板文件

模板的分页模板路径是page/default.tpl.php文件

$page_content = '';
if ($data['p'] > $data['half'] + 1) {
    $data['params']['p'] = 1;
    $page_content .= $this->wrap('li')->a(1, $this->url($data['controller'], $data['params']) . $data['anchor']) .
        $this->wrap('li')->a(' ... ', 'javascript:void(0)');
}
for ($i = max(1, $data['p'] - $data['half']), $j = min($data['p'] + $data['half'], $data['total_page']); $i <= $j; $i++) {
    if ($i == $data['p']) {
        $href = 'javascript:void(0)';
        $attr = array('class' => 'active');
    } else {
        $data['params']['p'] = $i;
        $attr = array();
        $href = $this->url($data['controller'], $data['params']) . $data['anchor'];
    }
    $page_content .= $this->wrap('li', $attr)->a($i, $href);
}
if ($data['p'] + $data ['half'] < $data['total_page']) {
    $data['params']['p'] = $data['total_page'];
    $page_content .= $this->wrap('li')->a(' ... ', 'javascript:void(0)') . $this->wrap('li')->a($data['total_page'], $this->url($data['controller'], $data['params']) . $data['anchor']);
}

echo $this->wrap('ul', array('class' => 'pagination'))->html($page_content);

扩展好分页方法后, 我们就可以在模板中直接调用了

<?php $this->page($data['page']) ?>

通过page()方法的第二个参数, 我们可以调用指定的分页显示模板来灵活处理各种条件下的分页显示