質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

クロージャ

クロージャは、プログラミング言語における関数オブジェクトの一種です。 引数以外の変数を実行時の環境ではなく、 自身が定義された環境において解決することを特徴とします。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Q&A

解決済

1回答

1396閲覧

laravel6 ソースコード - dispatchToRouter()の返すクロージャの引数にどこからどうやって値が渡るのか分かりません

hasukawa

総合スコア2

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

クロージャ

クロージャは、プログラミング言語における関数オブジェクトの一種です。 引数以外の変数を実行時の環境ではなく、 自身が定義された環境において解決することを特徴とします。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

0グッド

0クリップ

投稿2020/08/18 18:47

laravel6のソースコードについて質問させていただきます。
RequestインスタンスのrequestUriにどのタイミングでURLが格納されるのかを特定しようとしており、関連するソースコードを読んでおります。

Xdebug等を駆使し、createFromBaseメソッドによって作られた空のRequestインスタンスをIlluminate\Foundation\Http\KernelクラスのsendRequestThroughRouterメソッドに渡すと、渡されたRequestインスタンスのrequestUriに値が格納されるというところまで突き止めました。

問題はそこから先で、sendRequestThroughRouterメソッドがどのようにしてrequestUriを取得しているのかがわかりません。SendRequestThroughRouterメソッドの一番最後の行で呼んでいるthen($this->dispatchToRouter())がどのような挙動になっているのか、どうしても理解できないからです。

特に、dispatchToRouter()については、ソースコードを見ると、単にクロージャを返しているだけのようなのですが、そのクロージャは引数として$requestを受け取ることとなっています。この$requestは呼び出し元であるsendRequestThroughRouterメソッドに渡された$requestのことかなと思ったのですが、自分の雑なPHPの理解では、クロージャに外部から引数を渡すときはuseを使う必要があるのではと思い、この$requestにどこからどうやって値が渡るのかがわからず、これ以上コードを読み進めることができずにいます。

有識者の方、ご指導のほど、どうぞよろしくお願いいたします。

Laravel

1 2namespace Illuminate\Foundation\Http; 3 4class Kernel implements KernelContract 5{ 6 7// 一部抜粋 8 9 protected function sendRequestThroughRouter($request) 10 { 11 $this->app->instance('request', $request); 12 13 Facade::clearResolvedInstance('request'); 14 15 $this->bootstrap(); 16 17 return (new Pipeline($this->app)) 18 ->send($request) 19 ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware) 20 ->then($this->dispatchToRouter()); 21 } 22 23 protected function dispatchToRouter() 24 { 25 return function ($request) { //この$requestにはどこからどうやって値が渡るのか 26 $this->app->instance('request', $request); 27 28 return $this->router->dispatch($request); 29 }; 30 } 31

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/08/18 23:13

ドキュメント確認します  というコメントを見た気がしたのですが、 この質問内容だと何も確認してないように見受けられます。
hasukawa

2020/08/19 05:16

ドキュメントは確認しましたが、私の質問に対する解説は載っていなかったと理解しています。(少なくともドキュメントの検索窓でdispatchToRouterで検索しても何もヒットしませんでした。) ドキュメントに書いてあるのは主にlaravelの使い方かと思いますが、目的は、laravelの使い方を知ることではなく、laravelの挙動を「ソースコードから」理解することですので。 もし私の探し方が甘かったということであれば、恐れ入りますが、下の方のご回答のような解説が載っているドキュメントのページをご教示いただけませんでしょうか。 宜しくお願い致します。
guest

回答1

0

ベストアンサー

どうやらvendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php
public function then(Closure $destination) public function send($passable)を見たら分かるようです。
public function send($passable)の**$passableが質問文で抜粋してあるコードの$request**です。

前のコメントで反応無かったんであえて本回答に書きますが、コードを読むのは面倒くさいだけで特にコツはありません、ただソースを愚直に追うだけです。
実際に自分もこの質問を見てからの数分程度、vimで追ってみただけです。grepすら使ってません。

dispatchToRouterについて調べた手順

vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.phpを見ると、

Pipeline->send->through->then(dispatchToRouter())

という呼び出しと共に使われている事が分かるので、Pipelineがどこにあるかをファイル内を検索するとuse Illuminate\Routing\Pipeline;している事が分かる

vendor/laravel/framework/src/Illuminate/Routing/Pipeline.phpでthenを検索してみるがヒットしないので、extendsしているBasePipelineに目星をつけて、BasePipelineを検索するとuse Illuminate\Pipeline\Pipeline as BasePipeline;している事が分かる

vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.phpでthenを検索すると

php

1 97 public function then(Closure $destination) 2 98 { 3 99 $pipeline = array_reduce( 4100 array_reverse($this->pipes()), $this->carry(), $this->prepareDestination($destination) 5101 ); 6102 7103 return $pipeline($this->passable); 8104 } 9105 10

が見つかり、$this->prepareDestination($destination)という呼び出しをしている事が分かる

同ファイル内でprepareDestinationを調べてみると、

php

126 return function ($passable) use ($destination) { 2127 try { 3128 return $destination($passable); 4129 } catch (Throwable $e) { 5130 return $this->handleException($passable, $e); 6131 } 7132 }; 8

と使われている事が分かる。
では$passableが何かという事で同ファイル内をpassable検索すると

58 public function send($passable) 59 { 60 $this->passable = $passable; 61 62 return $this; 63 }

が見つかり、sendで渡しているパラメーターだという事が分かる
そしてsendで渡しているものが何かというと、最初のファイルに戻って$requestだという事が分かる

そしてこれが分かったところでLaravel使う上では全く何の役にも立たないのです。

投稿2020/08/18 20:15

編集2020/08/19 00:19
hentaiman

総合スコア6421

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hasukawa

2020/08/19 05:21

詳細なご回答ありがとうございました。 まさにこのような解説が欲しかったところです。大変勉強になりました。 laravelを「使う」うえでは役にたたないことは確かですが、著名なフレームワークから、将来にわたって使えるデザインパターンを学ぶという意味では、ソースコードリーディングは有意義だと信じています。(10年後までlaravelが現役な保証はどこにもないので。。。)
hentaiman

2020/08/19 05:51

そうですね、プログラム書く事に的を絞ればフレームワークを読むことで書き方の発見はあるしそれらは実務でも役に立ちますね。 コーディングオンリーじゃないのならフレームワークで使われている周辺知識の学習の方が有益な感じはしますが(sqs・redis・workerなど)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問