これも前回と同様に、開発したプログラムに今まであったバグがLaravelの更新により表面化したという話です。

余分なスラッシュ

例えば、このブログで以下のようなURLあります。

https://www.larajapan.com/2021/02/16/laravel-7-xのインストール

このURLに含まれるスラッシュに余分にスラッシュをつけます。以下では.comの直後にです。

https://www.larajapan.com//2021/02/16/laravel-7-xのインストール

上のリンクをクリックしたらわかりますが、余分なスラッシュを削除して最初のようなURLにして希望したページを表示してくれます。これは、ブラウザが修正してくれるのではなくサーバーで使用しているワードプレスのプログラムが修正してくれます。

Laravel 7.x更新で余分なスラッシュが禁止となる

これに気づいたのは、お客さんのサイトでLaravelを6から7に更新した後です。お客さんが発行したメルマガに入っていた販売商品のページのリンクに余分なスラッシュが含まれていたのです。そのためにリンク先のページにアクセスしても、404の「ページが見つかりません」のエラーページです。さあ大変ということで原因わからずに、即座にLaravel6にダウングレードと、冷や汗ものでした。

お客さんの話では以前は余計なスラッシュが入っていてもアクセスできたということです。さて、いったいどういことでしょう、ということで調査すると、ありました。

https://github.com/laravel/framework/pull/32260

これによると、今までURLにおける余分なスラッシュの扱いにおいて問題がありました。routeをキャッシュしたときとしないときでの統一性にも問題があったそうです。しかしこのPRは、Laravel 7.xのバージョンにマージされています。

ということで、今後は余分なスラッシュがURLに入らないように注意する必要あります。

これからその点をしっかり注意するとして、問題は過去のメルマガに含まれるリンクです。過去だからアクセスをする人は少ないと思いますが昨日のメルマガとかからはアクセスしますよね。ということで、Laravel 7.xが対応しないURLを対応しなければなりません。そうでなければいつまでもLaravelの更新ができないです。

ということで、急いで解決方法を見つけました。

解決方法

解決方法は意外にも、phpのプログラムの変更ではなく、public/.htaccessapacheのウェブサーバーの設定ファイルの修正でした。

以下は、URLのドメイン名の直後の余分なスラッシュを削除してくれます。

<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 %{THE_REQUEST} \s//+
    RewriteRule (.*) /$1 [R=301,L]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !/assets
    RewriteCond %{REQUEST_FILENAME} !/server-status
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

</IfModule>

{THE_REQUEST}は、例えば GET /////2021/02/16/laravel-7-xのインストール HTTP/1.1のような値が含まれます。GETの後の空白文字が\s//+が複数のスラッシュをマッチの条件とします。$1の変数には、余計なスラッシュを含まない2021/02/16/laravel-7-xのインストールの値となるので、/$1で1つのスラッシュに置き換えてリダイレクトします。

これで晴れてLaravel 7.xへの更新ができます!

By khino