Laravelでドキュメントルートに静的ファイルを混在させる方法

作ったシステムに後から静的ページを追加したい、みたいな要望にどう対応すればいいだろうか。「有料です」で済ませたいところだが、なかなかそうも行かない場合も多い。

古のCGI/PHP環境でやってきたクライアントにとっては、既存のファイルと無関係なところにファイル/ディレクトリを追加することができないのはなぜ、となってしまうのもまあ仕方ないのかもしれない。

そういうときどうするか。

LaravelのデフォルトのApache/Nginxの設定では、ファイルが存在する場合はそちらを読み込むようになっているので、単純にpublicディレクトリにファイルを置けばそちらを優先してくれるが、publicディレクトリは普通Git管理下にあるので、勝手にいじられたくない。1

解決法は、publicディレクトリをドキュメントルートのサブディレクトリなどに置いて触らないよう伝えた上で、ほかは勝手にしてください、とすることだろうか。

ということで、ドキュメントルートにpublic/.htaccessベースの.htaccessを置いて、URL上ではルートで動かしながら、じっさいのファイルはドキュメントルートのサブディレクトリに置くようにしてみる。

以下ではサブディレクトリ名は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]

    # ここから追加 {
    RewriteCond %{REQUEST_URI} ^/$
    RewriteRule ^ public/index.php [L]

    RewriteCond %{REQUEST_FILENAME} !-f # これがあれば、ドキュメントルート直下の同名ファイルを優先できるがなくてもいい。
    RewriteCond %{DOCUMENT_ROOT}/public%{REQUEST_URI} -f
    RewriteRule (.*) public/$1
    # } ここまで追加

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ public/index.php [L] # ここも変更
</IfModule>

なおこれだけでは、https://example.com/public/への直アクセスが防げない。いい方法が思い付かなかった。思い付いた人いたら教えてください。


  1. デプロイ方法にもよる。リンクでなく一方向のコピーであれば、上書きさえしなければ問題ない。