mod_rewriteの例が悪い
URLをリダイレクト・リライトする場合の.htaccessの設定例 がなんか全体的に微妙。
「product.php?12」を「product/ipod-nano/12.html」にリライト
正しくは「product?id=12」だけどこれはご愛嬌。
まず原文もそうだけど見出しの語順が逆だと思う。「product/ipod-nano/12.htmlをproduct.php?id=12にリライト」が処理の流れ的に正しい。
で、問題のコードですが、
RewriteEngine on RewriteRule ^product/([a-zA-Z0-9_-]+)/([0-9]+).html$ product.php?id=$2
元記事のコメント欄で突っ込まれてる とおり、product/awdftgyhjiiko/89818917897871.htmlとか、product/microsoft-zune/12.htmlまで同じ内容になるのはさすがにダメだろう。
RewriteEngine on RewriteRule ^product/ipod-nano/([0-9]+).html$ product.php?id=$1
か
RewriteEngine on RewriteRule ^product/([a-zA-Z0-9_-]+)/([0-9]+).html$ product.php?genre=$1&id=$2
が正しい。
あとこの例だとmod_rewrite使わなくても、
Options +MultiViews
とするとproduct.php/ipod-nano/12.htmlやproduct/ipod-nano/12.htmlがそのまま通るので、PHP側で受け方をちょっと変えればrewriteしなくてもいい。404とかを手動でやらないといけないから面倒だけど、rewrite使えない環境もあるだろうから考慮に入れといて損はないかと。
さらに蛇足だけどproduct/ipod-nano/12.htmlてのはURLの設計がおかしいと思う。これがproduct/ipod-nano/specとか、product/12.htmlとか、product/ipod-nano.htmlならわかる。12って何のパラメータなんだ? あとせっかく()でキャプチャしてるわりにPHPには渡してないので「ipod-nano」は不要なんじゃないのか?
「yoursite.com/user.php?username=xyz」を「yoursite.com/xyz」にリライト
RewriteEngine On RewriteRule ^([a-zA-Z0-9_-]+)$ user.php?username=$1 RewriteRule ^([a-zA-Z0-9_-]+)/$ user.php?username=$1
間違いではないけど冗長。
RewriteEngine On RewriteRule ^([a-zA-Z0-9_-]+)/?$ user.php?username=$1
で充分。
あと元記事でもコリスでもSEOについて触れてるわりに、これだとパーマリンクが/の有無でばらけてしまってSEOが甘い。3行目を削除して、/ありURLをNot Foundにしてしまってもいいけど、ちゃんと書き直すとこう。
RewriteEngine On RewriteRule ^([a-zA-Z0-9_-]+)$ user.php?username=$1 RewriteRule ^([a-zA-Z0-9_-]+)/$ $1 [R=301]
最後に/がついてるURLにアクセスしてきたら/なしのURLに301リダイレクトして一本化する。このブログでもそうしてる。
「サブフォルダのもの」を「ルート直下」にリダイレクト
例:test.com/new
RewriteEngine On RewriteCond %{HTTP_HOST} ^test.com$ [OR] RewriteCond %{HTTP_HOST} ^www.test.com$ RewriteCond %{REQUEST_URI} !^/new/ RewriteRule (.*) /new/$1
それだと最終的にtest.com/new/newを見に行くことになるけどあってる?
たぶん元々の意図は、「http://test.com/old-permalinkへのアクセスを、内部的にhttp://test.com/backup/old-contentにリライトしたい(古いコンテンツを全部backupディレクトリに移してしまいたい)」なんだと思うけどあんまり自信ない。
あ、違うか。逆だ。元記事だとこう書いてるな。
Suppose the you’ve redeveloped your site and all the new development reside inside the “new” folder of inside root folder.Then the new development of the website can be accessed like “test.com/new”.Now moving these files to the root folder can be a hectic process so you can create the following code inside the .htaccess file and place it under the root folder of the website. In result, www.test.com point out to the files inside “new” folder.
↑適当訳:サイトをリニューアルして、新しいファイルをnewディレクトリに置いたとしよう。これで一応新しいサイトにはhttp://test.com/new/でアクセスできる。そこから新しいサイトのファイルを一番上のディレクトリに移していくなんていう死ぬほどめんどくさい作業をしなくても、以下のように.htaccessを書けばほぼ同じことができる。要するに、http://test.com/へのアクセスをhttp://test.com/new/へとリライトするわけだ。
RewriteEngine On
RewriteCond %{HTTP_HOST} ^test\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.test\.com$
RewriteCond %{REQUEST_URI} !^/new/
RewriteRule (.*) /new/$1
か。なるほど。rewriteを使って、/public_html/じゃなくて/public_html/new/をルートにするわけか。それだと古いコンテンツへのリンクがたぶん死ぬけど、まあリニューアルなんだし仕方ないか。http:/test.com/new/へのアクセスがトップページと同じ内容になるけど、秘密にしとけば実用的には問題ないか。
あとRewriteCondのHTTP_HOSTチェックはこの例の場合どうでもいいと思う。
mod_rewriteは黒魔術です
mod_rewriteとか使わないに越したことはない。
膨大な設定例やドキュメントがあるにもかかわらず、mod_rewrite は黒魔術である。かなりイケてるっぽい黒魔術だが、やっぱり所詮は黒魔術である。
プログラム界隈で黒魔術というと、「難解だけどよく動いてるコード」「ダークサイドに堕ちた 」などなど、強力だけど普段使いするな、リスクを理解してから使え、みたいなニュアンスです。カリカリにチューニングされたコードとか、極限まで短くされたワンライナーなんかが該当します。汚さと引き換えに強力なパワーがどうとか。ただのぐちゃぐちゃなコードはスパゲッティとか呼ばれて、黒魔術とは区別されます。
Cool URI の考えに始まり、SEOが云々言い出して、Railsが突貫して以降、rewriteは当たり前のものみたいになってるけど、静的ページがメインのサイトで必要になることはまずないはず。最後の例の/new/みたいに不用意に使えばユーザーと管理者が無駄にメダパニるだけなので、そのへん注意して用法を誤らず用量を適正に保ちつつ清く正しく使わないとそのうち誰かが流れ弾に当たって死にます。
こめんと