とある同僚から「Apache 2.4 に FallbackResource というディレクティブがあって mod_rewrite 要らなくなるっぽい」と聞いたので、ちょっと試してみました。
mod_rewrite
とりあえず Silex でサンプルを作ります。なお、CentOS 7 です。
Apache と PHP をインストールして、
yum -y install httpd php
Composer をインストールして、
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
ドキュメントルートで Silex を入れて(普通はこんな位置に入れない方がいい)、
cd /var/www/html
composer require "silex/silex:*"
index.php を作ります。
vim index.php
次のような内容です。
<?php
require __DIR__ . '/vendor/autoload.php';
$app = new Silex\Application();
$app->get('/', function() {
return "this is index page\n";
});
$app->get('/aaa', function() {
return "this is aaa page\n";
});
$app->get('/bbb', function() {
return "this is bbb page\n";
});
$app->run();
.htaccess に rewrite を書いて、存在しないファイルへのリクエストを index.php に向けます。
cat <<EOS> .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
EOS
デフォ設定だと .htaccess が効かなかったので Apache の設定をちょっと弄ります。
cat <<EOS> /etc/httpd/conf.d/zz.conf
<Directory /var/www/html>
AllowOverride All
</Directory>
EOS
Apache を起動します。
systemctl start httpd.service
期待した通りの結果が返ってくるはずです。
curl http://localhost/
curl http://localhost/aaa
curl http://localhost/bbb
FallbackResource
.htaccess に FallbackResource を書いてみます。
cat <<EOS> .htaccess
DirectoryIndex index.php
FallbackResource /index.php
EOS
期待した通りの結果が返ってくるはずです。
curl http://localhost/
curl http://localhost/aaa
curl http://localhost/bbb
DirectoryIndex も書いておかないと http://localhost/ のときに良くわからないことになりました。
cat <<EOS> .htaccess
FallbackResource /index.php
EOS
curl -i http://localhost/
HTTP/1.1 200 OK
Date: Fri, 19 Jun 2015 03:23:16 GMT
Server: Apache/2.4.6 (CentOS) PHP/5.4.16
X-Powered-By: PHP/5.4.16
Cache-Control: no-cache
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
this is index page
curl: (18) transfer closed with outstanding read data remaining
原因は不明です。
ErrorDocument
FallbackResource って要するに、リクエストされたファイルが存在しなかったときに指定されたパスに内部リダイレクトする、ってことだと思うんですが、ん? よく考えたらそれって ErrorDocument 404
でもおんなじじゃない? と思ったので試してみました。
cat <<EOS> .htaccess
DirectoryIndex index.php
ErrorDocument 404 /index.php
EOS
期待した通りの結果が返ってきました。
curl http://localhost/
curl http://localhost/aaa
curl http://localhost/bbb
この方法だとレスポンスのステータスコードが 404 になってしまうので、PHP 側で明示的に http_response_code(200);
などとしてやる必要があります(Silex は Symfony の Response がそれに相当することを勝手にやっている)。