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 相关文章推荐
PHP 和 XML: 使用expat函数(二)
Oct 09 PHP
ADODB的数据库封包程序库
Dec 31 PHP
PHP 命令行工具 shell_exec, exec, passthru, system详细使用介绍
Sep 11 PHP
PHP提示Notice: Undefined variable的解决办法
Nov 24 PHP
PHP连接MySQL的2种方法小结以及防止乱码
Mar 11 PHP
ThinkPHP学习笔记(一)ThinkPHP部署
Jun 22 PHP
PHP读取文件的常见几种方法
Nov 03 PHP
php中strtotime函数性能分析
Nov 20 PHP
yii2.0整合阿里云oss上传单个文件的示例
Sep 19 PHP
php表单处理操作
Nov 16 PHP
PHP连续签到功能实现方法详解
Dec 04 PHP
WordPress免插件实现面包屑导航的示例代码
Aug 20 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 文章采集正则代码
2009/12/28 PHP
使用PHP获取汉字的拼音(全部与首字母)
2013/06/27 PHP
PHP中使用循环实现的金字塔图形
2014/11/08 PHP
php数组实现根据某个键值将相同键值合并生成新二维数组的方法
2017/04/26 PHP
php生成微信红包数组的方法
2019/09/05 PHP
js wmp操作代码小结(音乐连播功能)
2008/11/08 Javascript
JS setCapture 区域外事件捕捉
2010/03/18 Javascript
用js小类库获取浏览器的高度和宽度信息
2012/01/15 Javascript
JS打开新窗口的2种方式
2013/04/18 Javascript
JS基于Ajax实现的网页Loading效果代码
2015/10/27 Javascript
JavaScript通过代码调用Flash显示的方法
2016/02/02 Javascript
jQuery文字横向滚动效果的实现代码
2016/05/31 Javascript
Javascript之String对象详解
2016/06/08 Javascript
JS简单获取及显示当前时间的方法
2016/08/03 Javascript
关于Iframe父页面与子页面之间的相互调用
2016/11/22 Javascript
vue打包使用Nginx代理解决跨域问题
2018/08/27 Javascript
解决vuecli3.0热更新失效的问题
2018/09/19 Javascript
微信小程序云开发之使用云存储
2019/05/17 Javascript
jQuery实现提交表单时不提交隐藏div中input的方法
2019/10/08 jQuery
Vue实现仿iPhone悬浮球的示例代码
2020/03/13 Javascript
完美解决python遍历删除字典里值为空的元素报错问题
2016/09/11 Python
Python爬虫信息输入及页面的切换方法
2018/05/11 Python
python实现输入数字的连续加减方法
2018/06/22 Python
Django Rest framework之认证的实现代码
2018/12/17 Python
Python3.5迭代器与生成器用法实例分析
2019/04/30 Python
Python+Tensorflow+CNN实现车牌识别的示例代码
2019/10/11 Python
基于python纯函数实现井字棋游戏
2020/05/27 Python
pycharm 添加解释器的方法步骤
2020/08/31 Python
瑞士领先的网上超市:LeShop.ch
2018/11/14 全球购物
世界上最全面的草药补充剂和顶级品牌维生素网站:HerbsPro
2019/01/20 全球购物
Myholidays美国:在线旅游网站
2019/08/16 全球购物
附答案的Java面试题
2012/11/19 面试题
十佳少年事迹材料
2014/12/25 职场文书
2015年基层党建工作汇报材料
2015/06/25 职场文书
旷工检讨书大全
2015/08/15 职场文书
详解Oracle块修改跟踪功能
2021/11/07 Oracle