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 相关文章推荐
php4的彩蛋
Oct 09 PHP
如何写php程序?
Dec 08 PHP
关于在php.ini中添加extension=php_mysqli.dll指令的说明
Jun 14 PHP
php 8小时时间差的解决方法小结
Dec 22 PHP
php开启安全模式后禁用的函数集合
Jun 26 PHP
有关于PHP中常见数据类型的汇总分享
Jan 06 PHP
PHP中对于浮点型的数据需要用不同的方法解决
Mar 11 PHP
php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
Jun 19 PHP
Yii2中使用join、joinwith多表关联查询
Jun 30 PHP
php检查函数必传参数是否存在的实例详解
Aug 28 PHP
thinkPHP5框架分页样式类完整示例
Sep 01 PHP
php实现的表单验证类完整示例
Aug 13 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 用sock技术发送邮件的函数
2007/07/21 PHP
php str_pad() 将字符串填充成指定长度的字符串
2010/02/23 PHP
遍历指定目录下的所有目录和文件的php代码
2011/11/27 PHP
大家在抢红包,程序员在研究红包算法
2015/08/31 PHP
详谈PHP程序Laravel 5框架的优化技巧
2016/07/18 PHP
PHP图形计数器程序显示网站用户浏览量
2016/07/20 PHP
javascript中的对象和数组的应用技巧
2007/01/07 Javascript
JavaScript中Object和Function的关系小结
2009/09/26 Javascript
js和jquery使按钮失效为不可用状态的方法
2014/01/26 Javascript
js实现九宫格图片半透明渐显特效的方法
2015/02/16 Javascript
JavaScript将数字转换成大写中文的方法
2015/03/23 Javascript
jQuery插件Skippr实现焦点图幻灯片特效
2015/04/12 Javascript
javascript中call apply 与 bind方法详解
2016/03/10 Javascript
jQuery.Validate表单验证插件的使用示例详解
2017/01/04 Javascript
微信小程序之MaterialDesign--input组件详解
2017/02/15 Javascript
基于Vue生产环境部署详解
2017/09/15 Javascript
webpack-dev-server远程访问配置方法
2018/02/22 Javascript
layer.confirm取消按钮绑定事件的方法
2018/08/17 Javascript
详解如何运行vue项目
2019/04/15 Javascript
layer关闭当前窗口页面以及确认取消按钮的方法
2019/09/09 Javascript
JavaScript中的null和undefined用法解析
2019/09/30 Javascript
vue引用外部JS的两种种方法
2020/01/28 Javascript
小程序实现简单语音聊天的示例代码
2020/07/24 Javascript
Openlayers3实现车辆轨迹回放功能
2020/09/29 Javascript
用python实现简单EXCEL数据统计的实例
2017/01/24 Python
python 二分查找和快速排序实例详解
2017/10/13 Python
对Python中9种生成新对象的方法总结
2018/05/23 Python
Python 给屏幕打印信息加上颜色的实现方法
2019/04/24 Python
python中seaborn包常用图形使用详解
2019/11/25 Python
Python中如何将一个类方法变为多个方法
2019/12/30 Python
亿阳信通股份有限公司笔试题(C#)
2016/03/04 面试题
写给女生的道歉信
2014/01/14 职场文书
优秀干部获奖感言
2014/01/31 职场文书
小学生检讨书大全
2014/02/06 职场文书
公证书标准格式
2014/04/10 职场文书
vue2的 router在使用过程中遇到的一些问题
2022/04/13 Vue.js