schedule2020-03-19

以前のURLからもアクセスできるようにRewriteRuleを設定する

サイトのリニューアルに伴ってURIが幾つか変わったためApacheの設定で対応することになった。 ブックマークされていることも考慮して対応したURIにリダイレクトするようにします。

変更点は2つ

  1. スマホ向けのページをレスポンシブにしたため、ULIの/s/を削除する
  2. .htmlまたは.phpといった拡張子を見せないようにする

これらの設定を載せます。

環境

  • httpd 2.4

ULIの/s/を削除する

移行前ではスマホからのアクセスはUser-Agentで判定してスマホ用のページを表示していました。 URLは

  • PC: www.example.com/mypage
  • スマホ: www.example.com/s/mypage のように/s/を挟む仕様でした。

今回レスポンシブに対応したためどちらもPCのURLに統一します。 移行前にブクマした方向けに/s/mypage/mypageと変換します。

RewriteEngine On
# URIの先頭が/s/の場合
RewriteCond %{REQUEST_URI} ^/s/.*$
RewriteRule ^(.*)/s/(.*)$ $1/$2 [L]

RewriteEngine OnはRewrite機能自体のオン・オフを制御します。

RewriteCondはその条件に当たるURLの場合に続くRewriteRuleを適用します。 %{REQUEST_URI} ^/s/.*$はURIが/s/`で始まる場合が条件。 URIはURLのドメイン以降の部分の文字列です。

RewriteRuleはURL変換のルール。 ^(.*)/[sm]/(.*)$ $1/$2https://www.example.com/s/mypagehttps://www.example.com/mypageになります。

末尾の[L]はこれ以降の変換処理を無視するという意味です。

拡張子を見せないようにする

移行前は/login.phpと拡張子が見える状態でした。 これを/login/としつつ/login.phpからもアクセスできるようにします。

DirectoryIndex

拡張子を見せないようにするにはDirectoryIndexを設定します。 これは、リクエストURIがファイル名を指定せずにディレクトリだけ指定された場合にDirectoryIndexで指定したファイルの内容をかえします。

DirectoryIndex index.php index.html index.htm

このように設定するとディレクトリ内のindex.phpが返ります。 /login/と来た場合は/login/index.phpが返る。

index.phpがない場合はindex.htmlindex.htmと順番に探し、ない場合は404を返します。 他の拡張子のファイルも慣例的にindexと命名します。

拡張子付きのURLを処理する

/login.phpと来た場合にはそのPHPファイルを用意していないため404となります。 そこで/login.phpを``/login`にするよう変換します。

RewriteEngine On
RewriteCond %{THE_REQUEST} ^.*\.(html|php)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)\.(html|php)(.*)$ $1/$2$4 [L]

RewriteCondを続けるとANDの条件になる。 この例では「拡張子があり(2行目)該当するファイルとディレクトリがない(3,4行目)場合」となります。 -fでファイルが、-dでディレクトリが存在するかであり!がその逆です。

RewriteRuleで拡張子を除去したURLに変換します。

/user.php?id=1/user?id=1となるようクエリパラメータも考慮してあります。

まとめると

以上の処理をまとめるとこんな感じ求める動きになった。

RewriteEngine On
RewriteCond %{REQUEST_URI} ^/[sm]/.*$
RewriteRule ^(.*)/[sm]/(.*)$ $1/$2 [R=301,L]
RewriteCond %{THE_REQUEST} ^.*/.*\.(html|php)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)\.(html|php)(.*)$ $1/$2$4 [L]

DirectoryIndex index.php index.html

スマホページも拡張子の処理が必要でしたので、一度整形したURLにリダイレクトしてから拡張子を処理するようにしています。 R=301がステータス301でリダイレクトする設定。

mod_rewriteの参考となる記事

公式

日本語の記事

あとは正規表現を自在に使えるようになりたい。

関連する書いたもの