【thinkphp问题栏】tp5.0分页技巧

发布于:2024-06-23 ⋅ 阅读:(111) ⋅ 点赞:(0)

一、调用内置方法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();
    }

 前端代码则不变,这时候就能访问到原有参数的第二页了。


网站公告

今日签到

点亮在社区的每一天
去签到