Laravel5.5 手动分页和自定义分页样式的简单实现


Posted in PHP onOctober 15, 2019

基于Laravel5.5 在项目实施过程中,需要对从接口中获取的数据(或者通过搜索工具查询出来的数据)进行分页

一、创建手动分页

在laravel自带的分页中,一般是通过数据库查询访问paginate()方法来达到分页的效果 ,like this:

class IndexControllerextends Controller

{  
  publicfunctionindex()
  {
    $person = DB::table('person')->paginate(15);
 
    return view('index.pagTest',['person'=> $person]);
  }
}

查看框架的分页源代码

#vender/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php

/**
   * Paginate the given query.
   *
   * @param int $perPage
   * @param array $columns
   * @param string $pageName
   * @param int|null $page
   * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
   *
   * @throws \InvalidArgumentException
   */
  public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
  {
    $page = $page ?: Paginator::resolveCurrentPage($pageName);
 
    $perPage = $perPage ?: $this->model->getPerPage();
 
    $results = ($total = $this->toBase()->getCountForPagination())
                  ? $this->forPage($page, $perPage)->get($columns)
                  : $this->model->newCollection();
 
    return $this->paginator($results, $total, $perPage, $page, [
      'path' => Paginator::resolveCurrentPath(),
      'pageName' => $pageName,
    ]);
  }

发现,分页用了 \Illuminate\Contracts\Pagination\LengthAwarePaginator 构造方法,查看这个构造方法

<?php
 
namespace Illuminate\Pagination;
 
use Countable;
use ArrayAccess;
use JsonSerializable;
use IteratorAggregate;
use Illuminate\Support\Collection;
use Illuminate\Support\HtmlString;
use Illuminate\Contracts\Support\Jsonable;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\Pagination\LengthAwarePaginator as LengthAwarePaginatorContract;
 
class LengthAwarePaginator extends AbstractPaginator implements Arrayable, ArrayAccess, Countable, IteratorAggregate, JsonSerializable, Jsonable, LengthAwarePaginatorContract
{
  /**
   * The total number of items before slicing.
   *
   * @var int
   */
  protected $total;
 
  /**
   * The last available page.
   *
   * @var int
   */
  protected $lastPage;
 
  /**
   * Create a new paginator instance.
   *
   * @param mixed $items
   * @param int $total
   * @param int $perPage
   * @param int|null $currentPage
   * @param array $options (path, query, fragment, pageName)
   * @return void
   */
  public function __construct($items, $total, $perPage, $currentPage = null, array $options = [])
  {
    foreach ($options as $key => $value) {
      $this->{$key} = $value;
    }
 
    $this->total = $total;
    $this->perPage = $perPage;
    $this->lastPage = max((int) ceil($total / $perPage), 1);
    $this->path = $this->path !== '/' ? rtrim($this->path, '/') : $this->path;
    $this->currentPage = $this->setCurrentPage($currentPage, $this->pageName);
    $this->items = $items instanceof Collection ? $items : Collection::make($items);
  }

如果要实现手动分页,只需要使用这个构造方法,给定参数,就能达到分页的效果

贴代码:

public function setPage2(Request $request,$data,$prepage,$total){

#每页显示记录
    $prePage = $prepage;
    //$total =count($data);
    $allitem = $prepage *100;
    $total > $allitem ? $total = $allitem : $total;
    if(isset($request->page)){
      $current_page =intval($request->page);
      $current_page =$current_page<=0?1:$current_page;
    }else{
      $current_page = 1;
    }
    #url操作
    $url = $url='http://'.$_SERVER['SERVER_NAME'].$_SERVER["REQUEST_URI"];
    if(strpos($url,'&page')) $url=str_replace('&page='.$request->page, '',$url);
 
    # $data must be array
    $item =array_slice($data,($current_page-1)*$prePage,$prePage);
    $paginator = new LengthAwarePaginator($item,$total,$prePage,$current_page,[
      'path'=>$url,
      'pageName'=>'page'
    ]);
 
    return $paginator;
  }

($data 为需要进行分页的数据)

说明:

1、在考虑到代码的复用性,我将分页代码封装到app/Controllers/Controller.php中的一个方法里面,这样在其他控制器里只需要$this->setPage(Request $request,$data,$prepage,$total) 就能使用了,(前提:其他控制器继承了Controller.php)

2、分页的URL,因为我的项目的url一定会携带一个kw参数,所以我直接用str_replace替换"&page",如果是存在不携参分页的话,需要判断,到底是"?page"还是"&page"。(url的逻辑可以自己写)

#分页 php

$paginator = $this->setPage2($request,$data,25,$sum);
      $data =$paginator->toArray()['data'];

在模板中:{{$paginator->render()}}即能输出分页HTML,样式如下:

Laravel5.5 手动分页和自定义分页样式的简单实现

二、自定义分页样式

在实际开发中,不希望用户在浏览时直接浏览最后几页,只想用户从前往后依次的浏览,如百度搜索分页,这时候,就想修改分页的样式,经过一个下午的奋战,贴出解决过程

在上一环节中,手动创建了分页,了解HTML的模板生成是render()方法,

#\Illuminate\Contracts\Pagination\LengthAwarePaginator

/**
   * Render the paginator using the given view.
   *
   * @param string|null $view
   * @param array $data
   * @return \Illuminate\Support\HtmlString
   */
  public function render($view = null, $data = [])
  {
    return new HtmlString(static::viewFactory()->make($view ?: static::$defaultView, array_merge($data, [
      'paginator' => $this,
      'elements' => $this->elements(),
    ]))->render());
  }

经过思考,我们不去改laravel框架的源代码,可以通过重构render方法或者重新定义一个生成HTML模板的方法来实现自定义HTML模板

因为我们只需要自定义HTML模板,所以,可以创建一个文件,继承\Illuminate\Contracts\Pagination\LengthAwarePaginator 类

看代码:

<?php
 
namespace App\Helpers;
 
use Illuminate\Pagination\LengthAwarePaginator;
/**
 * Created by PhpStorm.
 * User: 1
 * Date: 2018/4/9
 * Time: 9:08
 */
class Newpage extends LengthAwarePaginator {
 
  public $de_page = 10; //默认显示分页数
  public $pageHtml;
 
  public function newrender(){
    if($this->hasPages())
    {
 
      return sprintf("<ul class='pagination'>%s %s %s</ul>",
        $this->pre_page(),
        $this->pages_num(),
        $this->next_page()
      );
    }
  }
 
  #上一页
  public function pre_page(){
    if($this->currentPage == 1){
      //dd($this->currentPage);
      return "<li class='disabled'><span>《</span></li>";
    }else{
 
      $url = $this->path."&page=".($this->currentPage-1);
      //dd($url);
      return "<li><a href=".$url." rel="external nofollow" rel='prev'>《</a></li>";
    }
  }
 
  #页码
  public function pages_num(){
    $pages = '';
    if($this->currentPage <= 6){
      for($i = 1; $i <= $this->de_page; $i++){
        if($this->currentPage == $i){
          $pages .= "<li class='active'><a href=".$this->path." rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" &page=".$i.">".$i."</a></li>";
        }else{
          $pages .="<li><a href=".$this->path." rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" &page=".$i.">".$i."</a></li>";
        }
      }
    }else{
      #当前页前边部分
      for($i = 5; $i >=1 ; $i--){
        $url =$this->currentPage-$i;
        $pages .= "<li><a href=".$this->path." rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" &page=".$url.">".$url."</a></li>";
      }
      #当前页
      $pages .= "<li class='active'><span>".$this->currentPage."</span></li>";
      #当前页后边部分
      for($i = 1;$i < 5; $i++ ){
        $nowpage =$this->currentPage+$i;
        $pages .= "<li><a href=".$this->path." rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" &page=".$nowpage.">".$nowpage."</a></li>";
      }
    }
    return $pages;
 
  }
  #下一页
  public function next_page(){
    if($this->currentPage < $this->total){
      $page =$this->currentPage+1;
      return "<li><a href=".$this->path." rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" &page=".$page." rel='next'><span>》</span></a></li>";
    }else{
      return "<li class='disabled'><span>》</span></li>";
    }
 
  }
 
}

我选择的方法是自定义新的方法生成HTML模板,模板中通过:{{$paginator->newrender()}}输出HTML

如果选择重构render()方法,只需要将上面的newrender()方法做一些小变动

public function render($view=null,$data=[]){
 
    if($this->hasPages())
    {
      return sprintf("<ul class='pagination'>%s %s %s</ul>",
        $this->pre_page(),
        $this->pages_num(),
        $this->next_page()
      );
    }
  }

模板中通过:{{$paginator->render()}}输出HTML

最终效果如图:

Laravel5.5 手动分页和自定义分页样式的简单实现

注意:自定义HTML后因为新建了一个类继承了LengthAwarePaginator类,需要将第一步手动分页的方法中new LengthAwarePaginator 修改为 new Newpage 参数不变。

以上这篇Laravel5.5 手动分页和自定义分页样式的简单实现就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
腾讯QQ php程序员面试题目整理
Jun 08 PHP
并发下常见的加锁及锁的PHP具体实现代码
Oct 12 PHP
PHP表单提交表单名称含有点号(.)则会被转化为下划线(_)
Dec 14 PHP
解析用PHP实现var_export的详细介绍
Jun 20 PHP
解析Win7 XAMPP apache无法启动的问题
Jun 26 PHP
ThinkPHP跳转页success及error模板实例教程
Jul 17 PHP
Ubuntu server 11.04安装memcache及php使用memcache来存储session的方法
May 31 PHP
Laravel 5.4向IoC容器中添加自定义类的方法示例
Aug 15 PHP
php自定义排序uasort函数示例【二维数组按指定键值排序】
Jun 19 PHP
微信公众号之主动给用户发送消息功能
Jun 22 PHP
Laravel 对某一列进行筛选然后求和sum()的例子
Oct 10 PHP
yii框架数据库关联查询操作示例
Oct 14 PHP
Laravel实现搜索的时候分页并携带参数
Oct 15 #PHP
在Laravel中实现使用AJAX动态刷新部分页面
Oct 15 #PHP
Yii框架的redis命令使用方法简单示例
Oct 15 #PHP
解决在laravel中leftjoin带条件查询没有返回右表为NULL的问题
Oct 15 #PHP
解决Laravel5.5下的toArray问题
Oct 15 #PHP
laravel通过a标签从视图向控制器实现传值
Oct 15 #PHP
laravel在中间件内生成参数并且传递到控制器中的2种姿势
Oct 15 #PHP
You might like
PHP静态类
2006/11/25 PHP
微信网页授权(OAuth2.0) PHP 源码简单实现
2016/08/29 PHP
javascript  Error 对象 错误处理
2008/05/18 Javascript
用户注册常用javascript代码
2009/08/29 Javascript
JavaScript中this关键词的使用技巧、工作原理以及注意事项
2014/05/20 Javascript
js实现鼠标感应向下滑动隐藏菜单的方法
2015/02/20 Javascript
超详细的JS弹出窗口代码大全
2020/04/18 Javascript
微信小程序 保留小数(toFixed)详细介绍
2016/11/16 Javascript
浅析js的模块化编写 require.js
2016/12/07 Javascript
js中document.referrer实现移动端返回上一页
2017/02/22 Javascript
JS验证码实现代码
2017/09/14 Javascript
nodejs判断文件、文件夹是否存在及删除的方法
2017/11/10 NodeJs
JS实现获取进今年第几天是周几的方法分析
2018/06/27 Javascript
在vue项目中,将juery设置为全局变量的方法
2018/09/25 Javascript
JavaScript 获取滚动条位置并将页面滑动到锚点
2021/02/08 Javascript
[51:34]Ti4主赛事胜者组 DK vs EG 2
2014/07/19 DOTA
Python实现的检测web服务器健康状况的小程序
2014/09/17 Python
Python3 正在毁灭 Python的原因分析
2014/11/28 Python
python中map、any、all函数用法分析
2015/04/21 Python
Python3读取文件常用方法实例分析
2015/05/22 Python
Python创建xml文件示例
2017/03/22 Python
Python Web程序部署到Ubuntu服务器上的方法
2018/02/22 Python
python实现树形打印目录结构
2018/03/29 Python
想学python 这5本书籍你必看!
2018/12/11 Python
Python基于network模块制作电影人物关系图
2020/06/19 Python
英国钻石公司:British Diamond Company
2020/02/16 全球购物
乡镇网格化管理实施方案
2014/03/23 职场文书
数学系毕业生求职信
2014/05/29 职场文书
党的群众路线查摆剖析材料
2014/10/10 职场文书
讲文明倡议书
2015/04/29 职场文书
幼儿园开学家长寄语(2015秋季)
2015/05/27 职场文书
大学毕业晚会开场白
2015/05/29 职场文书
校园音乐节目广播稿
2015/08/19 职场文书
有趣的二维码:使用MyQR和qrcode来制作二维码
2021/05/10 Python
JavaScript的Set数据结构详解
2022/02/18 Javascript
详解Spring Bean的配置方式与实例化
2022/06/10 Java/Android