元記事はこちら。
By rynop
1) 大規模アプリケーションを作っている開発者
2) Apacheを使用していて、Apacheの設定の調整権限を持っている開発者Apacheの .htaccess ファイルはパフォーマンスに打撃を与えるので、ぜひとも使用を控えたいものです。以下に示すチュートリアルでは、CakePHPの機能である「pretty url」を.htaccessを使わずに利用する方法を示します。記事の前半では.htaccessを使用しない方法について説明し、記事の後半ではより複雑な例として一つのApacheで複数のサブドメインを運用する方法について示します。
背景
一般的に、サーバの主設定ファイルにアクセスできない場合を除いて、 .htaccess ファイルの使用は極力避けてください。–apache.org
最初に背景を少し。.htaccessファイルはリソースを食います。有効にすると、毎回のリクエストにおいてドキュメントルート以下の全てのディレクトリでこのファイルを探索します。さらに、探索時に発見された.htaccessファイル内のディレクティブはApacheの設定ディレクティブとメモリ上でマージされます。Apacheのサイトで幾つかの例とさらなる説明があります。
http://httpd.apache.org/docs/2.2/howto/htaccess.html#when
パート1:.htaccessにお別れを
さて、これで問題はお分かりいただけたと思うので、解決しましょう。.htaccessファイルで設定できるものはDirectoryセクションでも設定できます。まず解決法を示し、それから説明します。
Apacheの設定ファイル:
<VirtualHost *:80>
ServerName www.leaguelogix.com
ServerAlias www.leaguelogix.com leaguelogix.com
DocumentRoot /var/www/leaguelogix/app/webroot
Options -Indexes FollowSymLinks
#disable htaccess starting at /
<Directory />
AllowOverride none
</Directory>
<Directory /var/www/leaguelogix/app/webroot/>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
<Files sitemap.xml>
RewriteEngine Off
</Files>
</Directory>
</VirtualHost>
まず、.htaccessファイルの探索と精査を停止します。以下のようにします。
<Directory />
AllowOverride none
</Directory>
これにより、リクエストのたびにApacheが探索するのを停止することができます。Cakeのプロジェクトから.htaccessファイルを削除しても問題ありませんが、そうしなければならないわけではありません。
DocumentRootを、Cakeアプリケーションのwebrootを指すようにセットアップします。
rewriteルールをセットアップします。
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
この記事ではmod_rewriteのパワーや複雑さについて説明しません。概要を示します。これらのルールはファイルまたはディレクトリではないリクエストを、Cakeのwebrootディレクトリのindex.phpに内部的にリダイレクトします。これは、CakeフレームワークのプリティURLマッピングの「マジック」を容易にします。
ここでApacheを再起動します。(sudo /etc/init.d/apache2 restart)
パート2:実装例
簡単ですね?さて、もう少し複雑な(けどタメになる)実際の例を見てみましょう。
好奇心があるなら、leaguelogix.comにアクセスしてみてください。Cakeアプリケーションではないことに気づくでしょう。これは私が30分程度でセットアップしたWordpressのブログです。私のCakeアプリケーションはWebアプリケーションプラットフォームでいくつものサイトで動作しています。一人でたくさんのスポーツ・リーグのサイトを運営管理し、各顧客は自分のWebサイトとドメインを持てるようにしています。
潜在顧客が無料で手早くサイトを作成し、私の製品を試してもらいたいと思いました。それで、Webサイトを持つ代わりに、mysite.leaguelogix.comとサブドメインを持たせることにしたのです。サブドメインごとに別のバーチャルホスト(設定)を作成せずに.htaccessの使用を避けたかったのです。CakePHPプラットフォームは全てのサイトで共通で、サイト固有の設定の調整とルック&フィールがある程度です。
ApacheのVirtualDocumentRootです。パート1で検討した話題が成果を上げます。ここでも、まずコードを示し、それから説明します。
<VirtualHost *:80>
#this handles sitename.leaguelogix.com
ServerName leaguelogix.com
ServerAlias *.leaguelogix.com
Options -Indexes FollowSymLinks
UseCanonicalName Off
VirtualDocumentRoot /opt/leagues/sites/%1/app/webroot
<Directory />
AllowOverride none
</Directory>
<Directory "/opt/leagues/sites/*/app/webroot/">
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/opt/leagues/sites/(.*)/app/webroot/(.*)$ index.php?url=$2 [QSA,L]
<Files sitemap.xml>
RewriteEngine Off
</Files>
</Directory>
</VirtualHost>
パート1で検討した話題を取り上げましょう。
UseCanonicalName Off
VirtualDocumentRoot /opt/leagues/sites/%1/app/webroot
一つのApache設定を、アクセスされたドメインの複数のドキュメントルートに供給することができます。例:http://mysite.leaguelogix.comにアクセスがあった場合、ドキュメントルートは/opt/leagues/sites/mysite/app/webrootになります。クールでしょ?新しいApacheのバーチャルホストを作成する必要はないし、「お試し」の顧客が来るたびに設定をリロードする必要もないのです。
ここで、トリッキーな部分です。mod_vhost_aliasをロードし、VirtualDocumentRootがパート1で出たシンプルなmod_rewriteディレクティブを無効にします。このままでは条件に合う全てのパスをRewriteRuleに渡します。Cakeのindex.php?urlはこれではうまく動作しません。以下の行でそれが実現できます。
RewriteRule ^/opt/leagues/sites/(.*)/app/webroot/(.*)$ index.php?url=$2 [QSA,L]
これでwebrootを「はぎ取り」、cakeが必要とするurl($2)を渡します。
A gotcha
ApacheのVirtualDocumentRootはDOCUMENT_ROOTを正しく設定しない(Apacheでずっとオープンになっているバグです)ので、DOCUMENT_ROOTを使用するにはPHPで以下のコードを記述してください。
$_SERVER['DOCUMENT_ROOT'] = str_replace($_SERVER['SCRIPT_NAME'],"",$_SERVER['SCRIPT_FILENAME']);
以上です。お役に立つことを願っています。
注意:これをテストした際に、実際の製品に使用していないことを明記すべきだと感じました。潜在的な誤りがあればご自由にコメントをお寄せ下さい。できるだけお答えします。
Cakeのパフォーマンスを引き出すことに関心がありますか?ではpseudocoderのこちらの記事(英語)も参考にしてください。
「.htaccessの削除とVirtualDocumentRootのマルチサイト設定でパフォーマンスを向上させる方法」への1件のフィードバック