当前位置:编程学习 > > 正文

laravel接口规范(Laravel5.5 手动分页和自定义分页样式的简单实现)

时间:2021-10-01 01:41:04类别:编程学习

laravel接口规范

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

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

一、创建手动分页

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

class IndexControllerextends Controller

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  •   publicfunctionindex()
  •   {
  •     $person = DB::table('person')->paginate(15);
  •  
  •     return view('index.pagTest',['person'=> $person]);
  •   }
  • }
  • 查看框架的分页源代码

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

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • /**
  •    * 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 构造方法,查看这个构造方法

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • <?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){

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  •   #每页显示记录
  •   $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

  • ?
  • 1
  • 2
  • $paginator = $this->setPage2($request,$data,25,$sum);
  •  $data =$paginator->toArray()['data'];
  • 在模板中:{{$paginator->render()}}即能输出分页HTML,样式如下:

    laravel接口规范(Laravel5.5 手动分页和自定义分页样式的简单实现)

    二、自定义分页样式

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

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

    #\Illuminate\Contracts\Pagination\LengthAwarePaginator

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • /**
  •    * 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 类

    看代码:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • <?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>".标签:

    猜您喜欢