Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Laravel の paginate は一体何をやっているのか

Laravel の paginate は一体何をやっているのか

2018-06-27 開催の「第127回 PHP勉強会@東京」におけるLT資料です

https://phpstudy.doorkeeper.jp/events/76011

Shohei Okada

June 27, 2018
Tweet

More Decks by Shohei Okada

Other Decks in Programming

Transcript

  1. // Controller にて $users = App¥User::paginate(15); {{-- blade template にて

    --}} <div class="container"> @foreach ($users as $user) {{ $user->name }} @endforeach </div> {{ $users->links() }}
  2. // Controller にて $users = App¥User::paginate(15); {{-- blade template にて

    --}} <div class="container"> @foreach ($users as $user) {{ $user->name }} @endforeach </div> {{ $users->links() }}
  3. routing を触らずに ページネーション用の URL (?page=x) が生まれる • 勝手に routing が生成される?

    だけでいい感じにページネーションのリンクが生まれる 8 なんか気持ち悪い…… $users->links()
  4. // Controller にて $users = App¥User::paginate(15); {{-- blade template にて

    --}} <div class="container"> @foreach ($users as $user) {{ $user->name }} @endforeach </div> {{ $users->links() }}
  5. // Controller にて $users = App¥User::paginate(15); {{-- blade template にて

    --}} <div class="container"> @foreach ($users as $user) {{ $user->name }} @endforeach </div> {{ $users->links() }}
  6. 20 ¥Illuminate¥Pagination¥LengthAwarePaginator // Controller にて $users = App¥User::paginate(15); DBから取得できる (わかる)

    引数でもらう (わかる) 算出できる (わかる) ??(わからない)
  7. 23 ¥Illuminate¥Database¥Query¥Builder::paginate() public function paginate($perPage = 15, $columns = ['*'],

    $pageName = 'page', $page = null) { $page = $page ?: Paginator::resolveCurrentPage($pageName); $total = $this->getCountForPagination($columns); $results = $total ? $this->forPage($page, $perPage)->get($columns) : collect(); return $this->paginator($results, $total, $perPage, $page, [ 'path' => Paginator::resolveCurrentPath(), 'pageName' => $pageName, ]); }
  8. 24 ¥Illuminate¥Database¥Query¥Builder::paginate() public function paginate($perPage = 15, $columns = ['*'],

    $pageName = 'page', $page = null) { $page = $page ?: Paginator::resolveCurrentPage($pageName); $total = $this->getCountForPagination($columns); $results = $total ? $this->forPage($page, $perPage)->get($columns) : collect(); return $this->paginator($results, $total, $perPage, $page, [ 'path' => Paginator::resolveCurrentPath(), 'pageName' => $pageName, ]); } currentPage を解決してそう
  9. 25 ¥Illuminate¥Pagination¥AbstractPaginator public static function resolveCurrentPage($pageName = 'page', $default =

    1) { if (isset(static::$currentPageResolver)) { return call_user_func(static::$currentPageResolver, $pageName); } return $default; } /** * Set the current page resolver callback. * * @param ¥Closure $resolver * @return void */ public static function currentPageResolver(Closure $resolver) { static::$currentPageResolver = $resolver; }
  10. 26 ¥Illuminate¥Pagination¥AbstractPaginator public static function resolveCurrentPage($pageName = 'page', $default =

    1) { if (isset(static::$currentPageResolver)) { return call_user_func(static::$currentPageResolver, $pageName); } return $default; } /** * Set the current page resolver callback. * * @param ¥Closure $resolver * @return void */ public static function currentPageResolver(Closure $resolver) { static::$currentPageResolver = $resolver; } $currentPageResolver を呼び出している $currentPageResolver は……?
  11. 27 ¥Illuminate¥Pagination¥AbstractPaginator public static function resolveCurrentPage($pageName = 'page', $default =

    1) { if (isset(static::$currentPageResolver)) { return call_user_func(static::$currentPageResolver, $pageName); } return $default; } /** * Set the current page resolver callback. * * @param ¥Closure $resolver * @return void */ public static function currentPageResolver(Closure $resolver) { static::$currentPageResolver = $resolver; } ここでセットされてる!
  12. 29 ¥Illuminate¥Pagination¥PaginationServiceProvider public function register() { Paginator::viewFactoryResolver(function () { return

    $this->app['view']; }); Paginator::currentPathResolver(function () { return $this->app['request']->url(); }); Paginator::currentPageResolver(function ($pageName = 'page') { $page = $this->app['request']->input($pageName); if (filter_var($page, FILTER_VALIDATE_INT) !== false && (int) $page >= 1) { return (int) $page; } return 1; }); }
  13. 30 ¥Illuminate¥Pagination¥PaginationServiceProvider public function register() { Paginator::viewFactoryResolver(function () { return

    $this->app['view']; }); Paginator::currentPathResolver(function () { return $this->app['request']->url(); }); Paginator::currentPageResolver(function ($pageName = 'page') { $page = $this->app['request']->input($pageName); if (filter_var($page, FILTER_VALIDATE_INT) !== false && (int) $page >= 1) { return (int) $page; } return 1; }); } リクエストパラメータ ${pageName} を取得
  14. 31 ¥Illuminate¥Pagination¥LengthAwarePaginator // Controller にて $users = App¥User::paginate(15); DBから取得できる (わかる)

    引数でもらう (わかる) 算出できる (わかる) ??(わからない)
  15. • Laravel の paginate は一見アクロバティックだが 意外と副作用が無い形になっていた • Laravel のコードを追って行って abstract

    class や interface で行き止まったら それっぽい ServiceProvider を探すと良い • こういうの調査するのに PhpStorm が便利!(Go To Declaration) • 要 larvae-ide-helper https://github.com/barryvdh/laravel-ide-helper 34 まとめ