Study & Practice

北海道札幌市のプログラマによる技術とか雑記のブログ

Laravle+ApacheでDocument Root以外にアクセスすると404エラーになる際の対処法

こちらの記事にて解決しました

teratail.com

以下のコマンドでmod_rewriteを有効化するだけでDocument Root以外も表示されるようになった

cat /etc/apache2/mods-available/rewrite.load
sudo a2enmod rewrite

しかし、さっぱり何をしているのかわからなかったので少し深堀してみる

ちなみに公式ドキュメントにmod_rewiteを有効にしろと書いてあった
https://readouble.com/laravel/6.x/ja/installation.html?header=Apache

mod_rewriteとは

まず、mod_rewriteはサーバーへのリクエストに応じてURLを書き換え、リダイレクトを行ってくれる

といってもよくわからなかったのでmod_rewriteの設定ファイルである.htaccessを確認する
mod_rewriteはlaravelのプロジェクトであればpublicディレクトリの直下にある

僕の場合は以下のような設定になっていた

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Send Requests To Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>


正直よくわかっていないのだが今回重要なのが

# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]

この部分

RewriteRuleは文字通りRewriteのルールを定義していて
RewriteCondはそのルールを適用する条件を設定している

RewriteCondの行の-dと-fはそれぞれディレクトリとファイルを表しており
RewriteCondが複数並んだ際はAnd条件となる

REQUEST_FILENAMEはファイルシステムにおけるフルパスのことなので

今回の場合、リクエストが指すパスの先がディレクトリでもなくファイルでもないときRerwiteを行うという条件になる

そしてRewriteRule

RewriteRuleはでは^という記号が使われている

^は正規表現において行頭を指す。
今回のRewriteRuleでいうと行頭をすべてindex.phpに置き換えるということになる

今回の設定値だと「/test」へのアクセスは「index.php/test」に変換しているということになる
この感じだと最初の/がなくなってしまっているがそこは内部的に変換しているのだと思う

ためしにmod_rewriteを無効にして「/index.php/test」にアクセスしてみるとちゃんとページが表示された
mod_rewriteを無効にするコマンドは以下

sudo a2dismod rewrite

a2enmonはenableで有効化
a2dismodはdisableで無効化ということらしい

ネット上によく見るものでは「RewriteRule ^ /index.php [L]」や「RewriteRule . /index.php [L]」ばかりなので
記載としては「RewriteRule ^ /index.php [L]」が正しいんじゃないかなと思っている

こうして振り返ってみると大した内容ではなかったが答えにたどり着くまでにも、何をしているのかを理解するのにも時間がかかってしまったが
こうして1歩ずつ成長していきたい

参考記事
html-coding.co.jphttps://murashun.jp/blog/20190215-01.html
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html
基本的な正規表現一覧 | murashun.jp