web系のサーバーサイドエンジニアを目指す奴のメモ書きです。
環境:Windows10
この連載の
第二回目の記事に沿ってやっていくよ!情報量多かったので分割します。
前回はこれ!
前回、XAMPPのhtdocs配下にLaravelプロジェクトを作成した。そしてhttp://localhost/firstlaravel/public/hello
にアクセスするとHello World!が表示されるようにLaravelプロジェクト配下のroutesフォルダにあるweb.phpというファイルを以下のように変更した。
<?php
use Illuminate\Support\Facades\Route;
//コメント省略
Route::get('/', function () {
return view('welcome');
});
//追加
Route::get("/hello", function () {
print("<h1>Hello World!</h1>");
return null;
});
今回はなぜweb.phpを変更しただけでHello World!が出せたのかをルーティングの観点で学んでみるよ!
全てのリクエストはpublic/index.phpに通ず
前回Laravelプロジェクト配下のpublicフォルダについて少し学んだ。publicフォルダはLaravelプロジェクトで内で唯一外部に公開されている。つまりすべてのリクエストは唯一公開されているpublicフォルダにアクセスせざるを得ないということになる。前回アクセスしたURLを見てもhttp://localhost/firstlaravel/public/
とhttp://localhost/firstlaravel/public/hello
でどちらもちゃんとpublicフォルダにアクセスしていることが分かる。
勘のいい人は気が付いたかもしれないがhttp://localhost/firstlaravel/public/hello
でアクセスしているがhelloなんてファイルはないし、ましてやhttp://localhost/firstlaravel/public/
に関してはファイルの指定すらされていないということに。。。安心してください、
http://localhost/firstlaravel/public/
やhttp://localhost/firstlaravel/public/hello
のようにpublicフォルダに該当するファイルが存在しない場合、いったんindex.php
が実行されるようになっているんです!
ルーティングで困ったらとりあえずindex.php
に振ってしまえっていう作戦ですね。
ちなみにindex.php
に割り振るという作戦は同じくpublicフォルダにある.htaccess
というファイルで設定しています。
次はこの.htaccess
という参謀についてみていきましょう。
※基本的にセキュリティの観点でpublic配下には作成したソースは配置せず、すべてindex.phpに振るのがよいとされているようです。(index.phpしか置いてない=どのリクエストも存在しないファイルだからindex.phpが実行される。)
勘違いしてる初心者は多いのですが、phpを動作させるためには別に必ずブラウザからアクセスできるところに.phpファイルを置かなきゃいけないというルールはありません。
コマンドからも実行できるので、Webサーバー内であればどこでも良いのです。
ブラウザから直接アクセス可能だと意図せず実行されてしまいますよね。
特にフレームワークではコアソース部分はそういった意図しない実行を防ぐためにドキュメントルート配下にはindex.phpしか置かない仕組みになっています。
https://teratail.com/questions/223840
.htaccessという参謀
.htaccess
はフォルダ単位でApacheの設定をできるファイルらしいです。
中身を確認すると以下のようになっています。
<IfModule mod_rewrite.c>
# 省略
RewriteEngine On
# 省略
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
処理の内容をざっくり説明すると、ApacheのURL書き換えモジュールが使えるなら、それを使用。一致するファイル名、フォルダ名がない場合はURLをindex.phpに書き換えるという処理をしています。
では順番に解読していきましょう!
<IfModule mod_rewrite.c>
とは
mod_rewrite.c
とはURLの書き換え・リダイレクト処理を行うApacheのモジュールです。
<IfModule モジュール名>
でモジュールが利用できる状態か確認して、利用できるときのみタグ内の処理を実施します。つまりmod_rewrite.cが利用可能であればタグ内の処理を実施します。
RewriteEngine Onとは
RewriteEngine On
でmod_rewriteの機能を有効化することができます。
これはシンプルにRewriteEngine Off
でmod_rewriteの機能を無効化できます。
RewriteCond %{REQUEST_FILENAME} !-d と RewriteCond %{REQUEST_FILENAME} !-fとは
RewriteCond
はURLの書き換えを行う条件を設定します。
今回の例のように2つの条件ががただ続いている場合はAND条件を表しています。
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
OR条件を表したい場合は[OR]をくっつけてあげる必要があります。
RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteCond %{REQUEST_FILENAME} !-f
今回はAND条件なので%{REQUEST_FILENAME} !-d
と%{REQUEST_FILENAME} !-f
両方を満たす場合にURLが書き換えられます。
%{REQUEST_FILENAME}
はHTTP環境変数のREQUEST_FILENAMEを参照しています。
HTTP環境変数については下記のように説明されています。
リクエストを受け取った側がCGIやPHPなどのプログラムの場合,HTTPリクエストヘッダの情報や、アクセス元のIPアドレス,TCPポート番号などの情報を環境変数に設定します。 環境変数にはクライアント側の情報だけでなく,サーバ側の情報も含まれます。
https://www.blackstone.jp/tech/memo/env.php
つまりリクエストの際にありとあらゆる情報を環境変数に設定して情報として活用できる状態にしているということです!
その中にREQUEST_FILENAMEという環境変数があり、リクエストされたサーバーパス情報を持っています。
残るのは!-d
と!-f
だけです!
-d
はディレクトリであればTRUEです。-f
はファイルであればTRUEです。
そこにそれぞれ否定の意味の!
が付いているので条件が反転します。
!-d
はディレクトリでなければTRUEで、!-f
はファイルでなければTRUEです。
条件については少し長くなってしまいましたがまとめると、リクエストされたサーバのパスがディレクトリでもファイルでもなければTRUEということになります。
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]とは
RewriteRuleは記述した内容でリクエストURLの書き換えをします。
書き換えといっても単に読み込むファイルを変更するだけの場合と別のURLに差し替えて他のページを表示(リダイレクト)する場合の2パターンがあります。
今回見ている箇所は単に読み込むファイルを変更するだけの場合です。リダイレクトにはRewriteRuleの末尾に[R=301]のようなものが付いています。
今回でいうとリクエストURLがhttp://localhost/firstlaravel/public/hello
ですが単に読み込むファイルを変更するだけの場合、ブラウザに表示されるURLはhttp://localhost/firstlaravel/public/hello
のまま、表示ファイルのみD:\XAMPP\XAMPP\htdocs\firstlaravel\public\index.php
に変更します。
最初は.htaccessのRewriteRuleの書き換えの処理内容が調べてもさっぱりわからなかったためteratailで教えていただきました。回答してくださった方ありがとうございました!
RewriteRuleの変換処理についてここに記載すると長くなってしまうため、また記事を作成したらこちらにリンクを掲載いたします。
この場では一旦RewriteRuleではリクエストURLを別のファイルへのアクセスに変換するということをやっているということだけにとどめておきます。
[L]はURL書き換えを終了します。(LastのL)
ただ注意しないといけない点として[L]を点ければそこで処理が終了するわけではないということです。
[L]は確かに最後ですが、[L]に到達したらもう一度先頭に戻って書き換え後のURLで再度条件に一致するか確認します。最終的にどの条件にも一致しなくなって初めて処理を抜けます。
.htaccessの学習課題
・.htaccessは推奨されておらず、できるだけhttpd.confで設定する方がよいらしいのでRewriteRuleの記述をhttpd.confでできるようにする。
参考資料
https://codezine.jp/article/detail/11370
https://html-coding.co.jp/knowhow/tips/wp_modrewrite/
https://pasomaki.com/htaccess-environment-variable/
https://itlog.unknown-r.com/5
https://laraweb.net/environment/9367/
https://ysklog.net/mod-rewrite/rewrite-base.html
https://www.suzu6.net/posts/239-laravel-htaccess/
https://www.javadrive.jp/apache/htaccess/index4.html#section1