URLを弄った時のパス対策

動的URLはSEO的によろしくない場合があるらしいので、可能ならば、静的アドレスに見せかけると見た目上も格好が付くと思います。これらを実現する手法は、開発者の間でかなり浸透していると言えますね。この前、私がPATH_INFOでそのような仕組みを実装した時に、パスがずれるという不具合にどう対処したかということについてメモをしておきます。

動的アドレスを静的アドレスに変換する

大きく分けて、2つの方法があると思います。それについて紹介しておきましょう。

動的アドレスを静的アドレスに変換?

http://jikkenjo.net/index.php?p=471

よりは、

http://jikkenjo.net/471.html

の方が格好が付きますよね。検索結果のインデックスを作るロボットも、後者の方が重要度を大きく評価することもあるらしいです。

mod_rewriteを用いる

RewriteEngine on
RewriteRule ^([0-9A-Za-z_/]+)\.html$ index.php?p=$1 [L]

このように.htaccessに記述してindex.phpと同ディレクトリに置けば、〜.htmlを、index.php?p=〜と置き換えられます。これは、結局、内部的には変換後のアドレスを呼び出しているに過ぎないようです。

PATH_INFOを用いる

phpではpath_infoというものが使えます。これは、ファイル名以降を全てクエリとして解釈できる機構です。

http://localhost/path_info/index.php/abcde/fg.html
<?php
// path_info/index.phpに記述
echo $_SERVER['PATH_INFO'];
?>

となると、このように文字列が取得できています。

/abcde/fg.html

mod_rewriteでは、apache側でアプリケーション側にあわせてやりましたが、path_infoでは吐き出されたクエリを自分で加工してやらなければなりません。この点で、面倒そうだなということは、その通りだと思います。なので、今回のような目的の場合、環境的にmod_rewriteが使えないなどといった時のみに使うべきだと、私は考えています。

<FilesMatch "^index$">
    ForceType application/x-httpd-php
</FilesMatch>

更に、.htaccessにこのように記述すると、[index]という名前のファイルを、phpとして解釈するようになります。これがどのような利益をもたらすかと言うと。

http://localhost/path_info/index.php/abcde/fg.html

これが、以下のように、よりディレクトリっぽく自然に見えます。それだけですが、案外有効な気はしますね。

http://localhost/path_info/index/abcde/fg.html

発生する問題

すいません、少し前置きが長すぎました。

上記のような設計をした人なら分かると思いますが、あらゆるもののパスがずれます。どういうことかというと、クエリを用いた従来の実装では、index.php?m=dir&p=sampleなどとなっていた為、見た目のカレントディレクトリはあくまでも、index.phpが存在するディレクトリでした。ところが、URLを書き換えた場合は/dir/sample.htmlなどとなっているため、見た目のカレントディレクトリは/dir/です。画像などを、相対パスで貼り付けていた場合、ブラウザが誤解してしまいます。これらの不具合を改善するためには、以下の方法が有効だと思われます。

解決法

結論から言えば、baseタグを使う手法が一番楽です。

クエリが実際のディレクトリと同じ場合

クエリとして渡すパスが、実際のディレクトリ構造と同じ場合は、張りたい画像ファイルなどをクエリで渡したパスに置けばよいのです。具体例を出して説明します。

htdoc/index.php
htdoc/.htaccess
htdoc/test/test.php
htdoc/test/test.png
//htdoc/.htaccess
RewriteEngine on
RewriteRule ^([0-9A-Za-z_/]+)\.html$ index.php?p=$1 [L]
<!-- htdoc/test/test.php -->
<img src="test.png">

このようなディレクトリ構造だった時に、

http://localhost/test/test.html

と、このようにアクセスするときのカレントディレクトリはlocalhost/test/となりますから、相対パスで見たtest.pngは、正当なパスとなります。この例は、かなり限定された場面の話なので、あまり当てはまらないかもしれません。更に、画像ファイルがそれぞれのディレクトリに散らばるため、管理性の問題もあります。

CSSなどを読み込む場合は、どっちにしろ、CSSは絶対パスで書く必要があるので、使い勝手は悪そうです(なぜなら、この結論であれば、それぞれのディレクトリ全てにCSSを置かないといけなくなってしまう)。

全て絶対パス

単純明快で分かりやすいですね。全てのあらゆるパスを、ルートからの絶対パスで書けば良いのです。非常に単純ですが、良く考えてみてください。ルートからの絶対パスで指定してしまった場合、ウェブサイト自体を移転する場合などでURLが変わった時などで、index.phpがサブディレクトリに移動した時……わかりますね、全てのパスを書き換えるという手間です。

<img src="/image/title/title.png">

と、なっていた時に、/test/に移転したとします。

<img src="/test/image/title/title.png">

と、全てのページにおいて書き換える必要が出てきます。

baseタグ

救世主です。お恥ずかしいことに、私は今までこのタグの存在を知りませんでした。そのため、上記の小手先テクニックで乗り越えていました。このタグは、やたら便利なのです。

基準となる URL を指定します。引用

つまり、このタグは、カレントディレクトリを指定できてしまうんです。注意点としましては、http://〜から記述しないと、OperaやChromeでしか期待通りに解釈してくれません。http://〜から記述するようにする点だけ注意してくださいね。

これで、もういくらでも相対パスで画像などをはっつけたり出来そうです。革命的だ。

コメントを残す

メールアドレスが公開されることはありません。