Apache

mod_rewrite の RewriteBase を環境によって切り替える方法

More than 1 year has passed since last update.

環境変数を使って切り替える方法がある。
(Apache 2.2.15にて動作確認済み)

SetEnvIf (mod_setenvif) を使う

.htaccess
RewriteEngine On

#----------------------------------------------------------
# RewriteBase for develop
#----------------------------------------------------------
SetEnvIf Host ^develop.example.com$ REWRITE_BASE=/path/to/develop

#----------------------------------------------------------
# RewriteBase for staging
#----------------------------------------------------------
SetEnvIf Host ^staging.example.com$ REWRITE_BASE=/path/to/staging

#----------------------------------------------------------
# RewriteBase for production
#----------------------------------------------------------
SetEnvIf Host ^www.example.com$ REWRITE_BASE=/path/to/production

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !\.(ico|gif|jpe?g|png|css|js)$ [NC]
RewriteRule ^(.*)$ %{ENV:REWRITE_BASE}/index.php [QSA,NS,L]

RewriteCond + RewriteRule で頑張る

.htaccess
RewriteEngine On

#----------------------------------------------------------
# RewriteBase for develop
#----------------------------------------------------------
RewriteCond %{HTTP_HOST} ^develop.example.com$
RewriteRule . - [E=REWRITE_BASE:/path/to/develop]

#----------------------------------------------------------
# RewriteBase for staging
#----------------------------------------------------------
RewriteCond %{HTTP_HOST} ^staging.example.com$
RewriteRule . - [E=REWRITE_BASE:/path/to/staging]

#----------------------------------------------------------
# RewriteBase for production
#----------------------------------------------------------
RewriteCond %{HTTP_HOST} ^www.example.com$
RewriteRule . - [E=REWRITE_BASE:/path/to/production]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !\.(ico|gif|jpe?g|png|css|js)$ [NC]
RewriteRule ^(.*)$ %{ENV:REWRITE_BASE}/index.php [QSA,NS,L]

DocumentRootの階層が違うために環境によってアプリケーションフレームワークの起動パスを切り替えたい場合などに使えるはず。
HTML等でリソースのパスが変わる場合も、この環境変数を頭に付けてやると良い。(PHPだと $_SERVER['REWRITE_BASE'] で参照できる。はず。)

RewriteCond の右辺には変数を書けない

RewriteCondのCondPattern(右辺)に変数を記述しても期待通りには解釈してくれない。
メンテナンス時の設定などで、こういう風に書いてリダイレクトループを回避しようとしてもダメ。
↓これはNG!!

.htaccess
#----------------------------------------------------------
# maintenance for all?
#----------------------------------------------------------
RewriteCond %{REMOTE_ADDR} !=127.0.0.1
RewriteCond %{REQUEST_URI} !=%{ENV:REWRITE_BASE}/503.php
RewriteCond %{REQUEST_FILENAME} !\.(gif|jpe?g|png|css|js|ico|map)$ [NC]
RewriteRule ^.*$ %{ENV:REWRITE_BASE}/503.php [R,L]

TestString(左辺)では変数を解釈してくれるので…
↓これならOK

.htaccess
#----------------------------------------------------------
# maintenance for staging
#----------------------------------------------------------
RewriteCond %{ENV:REWRITE_BASE} ^/path/to/staging$
RewriteCond %{REMOTE_ADDR} !=127.0.0.1
RewriteCond %{REQUEST_URI} !=/path/to/staging/503.php
RewriteCond %{REQUEST_FILENAME} !\.(gif|jpe?g|png|css|js|ico|map)$ [NC]
RewriteRule ^.*$ %{ENV:REWRITE_BASE}/503.php [R,L]

#----------------------------------------------------------
# maintenance for production
#----------------------------------------------------------
RewriteCond %{ENV:REWRITE_BASE} ^/path/to/production$
RewriteCond %{REMOTE_ADDR} !=127.0.0.1
RewriteCond %{REQUEST_URI} !=/path/to/production/503.php
RewriteCond %{REQUEST_FILENAME} !\.(gif|jpe?g|png|css|js|ico|map)$ [NC]
RewriteRule ^.*$ %{ENV:REWRITE_BASE}/503.php [R,L]

こんな感じで環境別に定義するしかないかも。他に良い解決策があれば教えてください。