Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Laravel の paginate は一体何をやっているのか
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Shohei Okada
June 27, 2018
Programming
69
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Laravel の paginate は一体何をやっているのか
2018-06-27 開催の「第127回 PHP勉強会@東京」におけるLT資料です
https://phpstudy.doorkeeper.jp/events/76011
Shohei Okada
June 27, 2018
More Decks by Shohei Okada
See All by Shohei Okada
Symfony + NelmioApiDocBundle を使った スキーマ駆動開発 / Schema Driven Development with NelmioApiDocBundle
okashoi
0
310
たった 1 枚の PHP ファイルで実装する MCP サーバ / MCP Server with Vanilla PHP
okashoi
1
950
どうして手を動かすよりもチーム内のコードレビューを優先するべきなのか
okashoi
3
2.3k
パスワードのハッシュ、ソルトってなに? - What is hash and salt for password?
okashoi
3
400
設計の考え方 - インターフェースと腐敗防止層編 #phpconfuk / Interface and Anti Corruption Layer
okashoi
11
6.1k
"config" ってなんだ? / What is "config"?
okashoi
0
1.8k
ファイル先頭の use の意味、説明できますか? 〜PHP の namespace と autoloading の関係を正しく理解しよう〜 / namespace and autoloading in php
okashoi
4
2.2k
MySQL のインデックスの種類をおさらいしよう! / overviewing indexes in MySQL
okashoi
0
1.4k
PHP における静的解析(あるいはそもそも静的解析とは) / #phpcondo_yasai static analysis for PHP
okashoi
1
1.5k
Other Decks in Programming
See All in Programming
Java × distroless で 軽量なコンテナイメージを / Java on Distroless
contour_gara
0
540
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.6k
A2UI という光を覗いてみる
satohjohn
1
130
コンテキストの使い捨てをやめる — ビジネスルール駆動開発と miko —
ioki
0
200
Language Server 使ってる? 〜VSCode と Zed の場合〜 / Are you using a Language Server? ~For VS Code and Zed~
handlename
0
780
ADKを使って簡単にAIエージェントを作ってみよう
k1mu21
0
260
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5.1k
不変条件と整合性境界—ビジネスが決める設計判断と実現パターン / Invariants and Consistency Boundaries
nrslib
13
4.5k
The NotImplementedError Problem in Ruby
koic
1
790
フロントエンドとバックエンドで「1文字」を揃えよう
youkidearitai
PRO
0
690
「エンジニアインターン、どうやって取った?」準備のリアルを語るLT会 Progate BAR
akiomatic
0
130
RTSPクライアントを自作してみた話
simotin13
0
610
Featured
See All Featured
The Invisible Side of Design
smashingmag
302
52k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
270
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
840
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
400
How to build a perfect <img>
jonoalderson
1
5.6k
Unsuck your backbone
ammeep
672
58k
What's in a price? How to price your products and services
michaelherold
247
13k
Designing for Performance
lara
611
70k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
330
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.2k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.3k
Transcript
Laravel の paginate は 一体何をやっているのか 第127回 PHP勉強会@東京
岡田 正平(おかだ しょうへい)@okashoi • 株式会社ウィルゲート 2015年新卒入社 • 開発室 ソリューションユニット 所属
• PHP, Laravel, Vue.js 2 自己紹介 Slides:
① Laravel の paginate は何をやっているのか • タイトル通り ② フレームワークのソースコードの追うときの思考プロセス 3
このスライドでつたえたい
https://laravel.com/docs/5.6/pagination
// Controller にて $users = App¥User::paginate(15); {{-- blade template にて
--}} <div class="container"> @foreach ($users as $user) {{ $user->name }} @endforeach </div> {{ $users->links() }}
// Controller にて $users = App¥User::paginate(15); {{-- blade template にて
--}} <div class="container"> @foreach ($users as $user) {{ $user->name }} @endforeach </div> {{ $users->links() }}
None
routing を触らずに ページネーション用の URL (?page=x) が生まれる • 勝手に routing が生成される?
だけでいい感じにページネーションのリンクが生まれる 8 なんか気持ち悪い…… $users->links()
……
// Controller にて $users = App¥User::paginate(15); {{-- blade template にて
--}} <div class="container"> @foreach ($users as $user) {{ $user->name }} @endforeach </div> {{ $users->links() }}
// Controller にて $users = App¥User::paginate(15); {{-- blade template にて
--}} <div class="container"> @foreach ($users as $user) {{ $user->name }} @endforeach </div> {{ $users->links() }}
• の戻り値 • ページネーションに必要な情報を持っている • もこのクラスに生えている 12 ¥Illuminate¥Pagination¥LengthAwarePaginator // Controller
にて $users = App¥User::paginate(15); ¥Illuminate¥Database¥Query¥Builder::paginate() links()
• の戻り値 • ページネーションに必要な情報を持っている • もこのクラスに生えている 13 ¥Illuminate¥Pagination¥LengthAwarePaginator // Controller
にて $users = App¥User::paginate(15); ¥Illuminate¥Database¥Query¥Builder::paginate() links()
14 ¥Illuminate¥Pagination¥LengthAwarePaginator // Controller にて $users = App¥User::paginate(15);
これらの情報から、ページネーション部分の HTML を生成することはできる(わかる)
16 ¥Illuminate¥Pagination¥LengthAwarePaginator // Controller にて $users = App¥User::paginate(15);
17 ¥Illuminate¥Pagination¥LengthAwarePaginator // Controller にて $users = App¥User::paginate(15); DBから取得できる (わかる)
18 ¥Illuminate¥Pagination¥LengthAwarePaginator // Controller にて $users = App¥User::paginate(15); DBから取得できる (わかる)
引数でもらう (わかる)
19 ¥Illuminate¥Pagination¥LengthAwarePaginator // Controller にて $users = App¥User::paginate(15); DBから取得できる (わかる)
引数でもらう (わかる) 算出できる (わかる)
20 ¥Illuminate¥Pagination¥LengthAwarePaginator // Controller にて $users = App¥User::paginate(15); DBから取得できる (わかる)
引数でもらう (わかる) 算出できる (わかる) ??(わからない)
ここからは勘と執念の戦い (なのでちょっと駆け足)
• の戻り値 • ページネーションに必要な情報を持っている • もこのクラスに生えている 22 ¥Illuminate¥Pagination¥LengthAwarePaginator // Controller
にて $users = App¥User::paginate(15); ¥Illuminate¥Database¥Query¥Builder::paginate() links()
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, ]); }
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 を解決してそう
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; }
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 は……?
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; } ここでセットされてる!
順当にクラス定義をさかのぼって行くと、ここで行き止まる = の呼び出し箇所が見つからない → Laravel には ServiceProvider という仕組みがある • アプリケーションの各所初期処理が行われる場所
28 行き止まり? Paginator::currentPageResolver()
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; }); }
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} を取得
31 ¥Illuminate¥Pagination¥LengthAwarePaginator // Controller にて $users = App¥User::paginate(15); DBから取得できる (わかる)
引数でもらう (わかる) 算出できる (わかる) ??(わからない)
32 ¥Illuminate¥Pagination¥LengthAwarePaginator // Controller にて $users = App¥User::paginate(15); DBから取得できる (わかる)
引数でもらう (わかる) 算出できる (わかる) わかった!
None
• Laravel の paginate は一見アクロバティックだが 意外と副作用が無い形になっていた • Laravel のコードを追って行って abstract
class や interface で行き止まったら それっぽい ServiceProvider を探すと良い • こういうの調査するのに PhpStorm が便利!(Go To Declaration) • 要 larvae-ide-helper https://github.com/barryvdh/laravel-ide-helper 34 まとめ