laravel接口规范(Laravel5.5 手动分页和自定义分页样式的简单实现)
laravel接口规范
Laravel5.5 手动分页和自定义分页样式的简单实现基于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,样式如下:
二、自定义分页样式
在实际开发中,不希望用户在浏览时直接浏览最后几页,只想用户从前往后依次的浏览,如百度搜索分页,这时候,就想修改分页的样式,经过一个下午的奋战,贴出解决过程
在上一环节中,手动创建了分页,了解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>" .
|