一、调用内置方法paginate
thinkphp内置了一个paginate方法支持分页功能
该方法位于library\think\db\Query.php内
/**
* 分页查询
* @param int|array $listRows 每页数量 数组表示配置参数
* @param int|bool $simple 是否简洁模式或者总记录数
* @param array $config 配置参数
* page:当前页,
* path:url路径,
* query:url额外参数,
* fragment:url锚点,
* var_page:分页变量,
* list_rows:每页数量
* type:分页类名
* @return \think\Paginator
* @throws DbException
*/
public function paginate($listRows = null, $simple = false, $config = [])
{
// 如果$simple是整数,表示这是总记录数,并不是简洁模式
if (is_int($simple)) {
$total = $simple;
$simple = false;
}
// 如果 $listRows 是数组,表示这是配置参数,需要合并默认配置。
if (is_array($listRows)) {
$config = array_merge(Config::get('paginate'), $listRows);
$listRows = $config['list_rows'];
} else {// 其他情况使用传入的 $config 合并默认配置,确定每页记录数量。
$config = array_merge(Config::get('paginate'), $config);
$listRows = $listRows ?: $config['list_rows'];
}
/** @var Paginator $class */
// 根据配置中的 type 确定使用的分页类。
$class = false !== strpos($config['type'], '\\') ? $config['type'] : '\\think\\paginator\\driver\\' . ucwords($config['type']);
// 确定当前页码,如果配置中有 page 直接使用,否则通过分页类的 getCurrentPage 方法获取。
$page = isset($config['page']) ? (int) $config['page'] : call_user_func([
$class,
'getCurrentPage',
], $config['var_page']);
$page = $page < 1 ? 1 : $page;
$config['path'] = isset($config['path']) ? $config['path'] : call_user_func([$class, 'getCurrentPath']);
// 如果没有指定总记录数且不使用简洁模式,查询总记录数并获取当前页数据。
if (!isset($total) && !$simple) {
$options = $this->getOptions();
unset($this->options['order'], $this->options['limit'], $this->options['page'], $this->options['field']);
$bind = $this->bind;
$total = $this->count();
$results = $this->options($options)->bind($bind)->page($page, $listRows)->select();
} elseif ($simple) {//如果使用简洁模式,只查询当前页数据。
$results = $this->limit(($page - 1) * $listRows, $listRows + 1)->select();
$total = null;
} else {//否则直接查询当前页数据。
$results = $this->page($page, $listRows)->select();
}
//调用分页类的 make 方法,生成并返回分页器对象。
return $class::make($results, $listRows, $page, $total, $simple, $config);
}
这个方法有三个参数
参数 | 类型 | 解释 |
$listRows | int|array | 每页数量 数组表示配置参数 |
$simple | int|bool | 是否简洁模式或者总记录数 |
$config | array | 配置参数 |
1、第一种情况
当我们需要分条件查询时,举个例子
后端代码为:
public function page(){ $model=new UserModel(); // 设置分页条数为20 $users=$model->where("status",1)->paginate(20); $this->assign("users",$users); return $this->fetch(); }
前端代码为:
<html> <head> <title>测试</title> </head> <body> <ul> {volist name="users" id="user"} <li>{$user.name}_{$user.age}</li> {/volist} </ul> {$users->render()} </body> </html>
拓展:
(1)获取数据总条数,当前页和总页数
// 总条数 $total=$user->total(); // 当前页,从路径获取 $page= input("page") ?: 1; // 总页数,计算获得 $pageCount = ceil($count / $20);
(2)分页方法写在后端
后端代码为:
public function page(){ $model=new UserModel(); // 设置分页条数为20 $users=$model->where("status",1)->paginate(20); $userPage=$users->render(); $this->assign("users",$users); $this->assign("userPage",$userPage); return $this->fetch(); }
前端代码为:
<html> <head> <title>测试</title> </head> <body> <ul> {volist name="users" id="user"} <li>{$user.name}_{$user.age}</li> {/volist} </ul> {$userPage} </body> </html>
2、第二种情况
如果我们所访问的路径为get请求所获得的数据,当点击第二页时,路径就会刷新,从而获取不到原来所存储的路径变量值。
举个例子
后端代码为:
public function page(){ $archivesModel=new \addons\cms\model\Archives(); //请求路径中带有参数 if (input('category_id')){ $channel_id=input("category_id"); $archivesModel->where("channel_id",$channel_id); } if (input('keyword')){ $title=input("keyword"); $archivesModel->where("title",'like','%' . $title . '%'); } // 分页数 $listRow=20; // 总数据 $archives=$archivesModel->order('id', 'desc')->paginate($listRow); $this->assign("archives",$archives); return $this->fetch(); }
前端代码为:
{volist name="archives" id="item"} <tr> <td>{$item.id}</td> <td class="listNewsTitleContent"> <a target="_blank" href="{$item.url}" title="{$item.title}">{$item.title}</a> </td> <td>{$item.industry|htmlentities}</td> <td>{$item.area|htmlentities}</td> <td>{:date("Y-m-d", $item['publishtime'])}</td> </tr> {/volist} {$archives->render()}
此时当我们点击第二页的时候,页面会跳转到第二页,但是原来第一页request上的url参数却缺失了,所以我们需要保留原有的路径参数
后端代码为:
public function page(){ $archivesModel=new \addons\cms\model\Archives(); //请求路径中带有参数 if (input('category_id')){ $channel_id=input("category_id"); $archivesModel->where("channel_id",$channel_id); } if (input('keyword')){ $title=input("keyword"); $archivesModel->where("title",'like','%' . $title . '%'); } // 分页数 $listRow=20; // 总数据 $archives=$archivesModel->order('id', 'desc')->paginate($listRow,false,['query'=>$this->request->param() ]); $this->assign("archives",$archives); return $this->fetch(); }
前端代码则不变,这时候就能访问到原有参数的第二页了。