CakePHPやWordPressで何で.htaccessが必要なのかやっと理解した件

この記事はだいぶ前に書かれたものなので情報が古いかもしれません

まったくもって、目からウロコと言いますか、鼻から牛乳と言いますか、口からヨダレと言いますか、『ピー』から『ピー』と言いますか……。
(『ピー』には卑猥な言葉が入ります)



普段、CakePHPやWordpressを使うとき、パッケージをダウンロードすると、最初から必ず.htaccessが入っていますよね。

んでまあ、サーバーにアップロードする際には、index.phpなんかと同じところにこの.htaccessも置くことになります。

今まで、その作業をあまりにも当たり前のように行なっていたので、特に気にしたことなかったんですけど、この前たまたま、あの.htaccessにはそんな意味があったのね〜という出来事がありました。



まずは見てみよう

例えばCakePHPの場合。

デフォルトの状態だと、.htaccessの中にはこんなようなことが書いてあると思います。

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>

僕、この意味を考えたことってなかったんですよ。「RewriteCondとかRewirteRuleって何よ?」ってなったことはありましたが、CakePHPを使う際、必ずこの記述があることの意味までは考えたことがありませんでした。

一体これは、どういう意図があるのでしょーか。



必ずindex.phpを経由させる

上記の記述の中にある二行の「RewriteCond」。

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f

これは簡単に言うと「アクセスされたURLにディレクトリもファイル存在しない場合」を意味しています。

例えばあかつきのお宿には「プロット作成をお助け」や「IE8でもbackground-sizeを使えるようにしてみた」みたいな、CakePHPやWordpress以外で作ったページがいくつかあります。

これは、URLでアクセスできる場所にPHPファイルやらHTMLファイルやらが置いてあります。それぞれURLとサーバー上のファイル置き場はこんな感じ。

http://norm-nois.com/makeplot/index.php
http://norm-nois.com/reference/backgroundsize/index.html

ドキュメントルート
  ├ index.php
  ├ .htaccess
  |
  ├ /makeplot
  |  ├ index.php
  |  └ その他のファイル
  |
  └ /reference
     ├ /backgroundsize 
        ├ index.html
        └ その他のファイル

ドキュメントルートの下にあるファイルは、基本的にURLを入力してアクセスすることができます。だからこの場合は「アクセスされたURLはファイルである」となるわけですね。

しかしここで、例えば「http://norm-nois.com/makeplot/test.php」というURLにアクセスしようとした場合。「/makeplot」の下にはtest.phpというファイルが存在しません。つまり「アクセスされたURLはファイルじゃない」となるわけです。もちろんディレクトリでもない。



こっから先はCakePHPの仕事

アクセスされたURLがファイルでもディレクトリでもない場合、.htaccessに書いてある以下の一行が作動します。

RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]

これは「GETパラメータにアクセスされたURLをつけてindex.phpにリダイレクトする」みたいな感じです。

上記の例だと、こんなURLにリダイレクトすることになります。

http://norm-nois.com/index.php?url=makeplot/test.php

このindex.phpはCakePHPのwebrootの中にあるindex.phpです。つまりここから先は、Cakeさんの出番ってことですね。

CakePHPで作るような動的なページは、基本的にそれに該当するファイルがありませんよね。だからどんなURLでアクセスされても、こうして必ずindex.phpにリダイレクトさせるようにしているってことなんですな。

あとはGETパラメータの中身を上手いこと使って、必要なコントローラーやビューファイルを読み込むっていうすんぽーです。

例えば、あかつきのお宿には小説の間ってのがありますけど、これはURLだと「http://norm-nois.com/novels/index」なので、「http://norm-nois.com/index.php?url=novels/index」にリダイレクトして、NovelsController.phpのindexアクションを呼び出すと、そういうことですね。



セキュリティを考慮するなら、これは必要なこと

プロット作成ページやbackgroundsizeのページの場合「/makeplot」「/backgroundsize」というディレクトリの下に必要なファイルが全て置かれているので、「http://norm-nois.com/makeplot/**」「http://norm-nois.com/reference/backgroundsize/**」で直接アクセスすることができます。

でも、こういうのはセキュリティ上よろしくない場合もある。CakePHPの場合でも、本体がドキュメントルートより下にあるのは、基本的にはよくない。だからのっぴきならない事情でもない限り、CakePHPの本体はドキュメントルートより上に置くのが普通だと思います。

同じ要領で、プロット作成やbackgroundsizeのページを読み込む際に使用しているファイルのうち、index.phpやcss、jsファイル以外のものを、ドキュメントルートより上に置いて、直接そのファイルにアクセスできないようにすることもできる。.htaccessと使って。




ちょっと実際にやってみますか。

今、ファイル構成にこんな風にしたとしましょう。

/root
  ├ /ドキュメントルート
  |  ├ index.php
  |  ├ .htaccess
  |  └ cssやjs
  |
  ├ /makeplot
  |  └ index.php
  |
  └ /backgroundsize 
     └ index.html

「/makeplot」「/backgroundsize」をドキュメントルートより上に持って来ました。これで「http://norm-nois.com/makeplot/index.php」や「http://norm-nois.com/backgroundsize/index.html」とURLを入力しても、直接ファイルにアクセスすることはできない。セキュリティレベルがちょっと上がった。テレレレーテッテッテー♪(←レベルアップの音)

「/root」は、サーバーのルートってことね。



次に、ドキュメントルートの下にあるindex.phpを編集。

必要なのは下の一行。

require_once('/root/'.GET['url']);

.htaccessの中身は、CakePHPのときと同じで大丈夫。

これで、「http://norm-nois.com/makeplot/index.php」にアクセスすると「/root/makeplot/index.php」が読み込まれるようになるし、「http://norm-nois.com/backgroundsize/index.html」にアクセスすれば「/root/backgroundsize/index.html」が読み込まれるようになる。

やったね。

ま、GETで変な値が来たりしたときのために、index.phpの中でもうちょいごちゃごちゃといろんなことをやった方が良いかもだけど、今回はそこはパス。






先日、CakePHPを使うほどでもないページをいくつか作ることになりまして……全部PHPベタ書きで実装したんですけど、直接そのファイルにアクセスされるの、できれば避けたいなーって思って、そういやCakePHPは何で必要なファイルをドキュメントルートより上に置けるんだって疑問がふと沸いたときに、何やかんやとあった末に、.htaccessが果たしている役目を知ることになったっつー話です。

あんまりないかもしれないけど、PHPをベタ書くようなことがあって、必要最小限のファイル以外はドキュメントルートの上に置きたいってときには、ここで書いたようなことをやればできます。

機会があればお試しあれ。

そしてあなたの作るシステムに幸あれ。

まるやま 2015年12月10日 19:30:52
最近CakePHPを始めた初心者です(Web自体あんまり知らない...)。
レンタルサーバーにあげる時に上手くいかなくてその時に「.htaccessってなんなん!?」って思ってる時に見つけました!

命名規則で動くってどうなってんねん...っと思ってたりもしてたんですけど、こういうカラクリがあったんですね!
すごく噛み砕いて書いてるんで初心者の僕でもわかりやすかったです!
まっち~(管理人) 2015年12月11日 11:09:36
お役に立てたみたいで何よりです。
僕なんかCakePHP触り始めて五年くらい経って、ようやくこの事実に気づきましたからね。どんだけhtaccessとか気にしてなかったんだって感じですw
もしかしたら何か関連しているかも?