MySQL PHPに関する質問です。


MySQLに以下のテーブルがあるとします。
テーブル名  sample_table

フィールド  id
title
text

このテーブルのレコードを、
http://www.hogehoge.com/○○○.html
のようにHTMLファイル(あるいはPHPでも)でパブリッシュするような仕組みが欲しいです。
上記URLの○○○にはidフィールドの値が入るようなイメージで、HTMLファイルの中身はtextフィールドです。

http://www.hogehoge.com/aaa.php?ID=○○○
上記のようなURLではなく、あくまで最初のような形です。

このような仕組みは可能なのでしょうか?

新しくレコードが追加された場合も自動的にパブリッシュされ、レコードが削除された場合はファイルも削除されると完璧です。
パブリッシュ形式はいわゆる静的なURLならばHTMLでもPHPでも構いません。

皆様よろしくお願い致します。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2007/03/15 15:43:48
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:nandedarou No.4

回答回数230ベストアンサー獲得回数34

ポイント100pt

まず、結論からいいます。

tokyosmashさんが、お使いのMovableTypeで使用している.htaccessのRewriteEngine onの直後に、以下3行をコピーして貼り付けて下さい。

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)\.html$ aaa.php?ID=$1 [L]

以下、理由を知りたい場合は、読んでください。


http://www.net-newbie.com/trans/mod_rewrite.html

を参考にしましたが、よくわからないところがありました。

以下は、実験を繰り返して得た結論です。説明が正確でない部分があると思いますが、ご容赦ください。


詳しい書き方は上記リンクに譲るとして、RewriteCondディレクティブとRewriteRuleディレクティブ、そして、RewriteRuleディレクティブの第三引数、[L]フラグの関係について書きます。


RewriteCondや、[L]フラグがないと文法的に誤りというわけではありませんが、以下は、それがあるのを前提に説明します。RewriteCondから、RewriteRuleの[L]までが一つのまとまりと考えると分かりやすいです。今回の説明の中では、このまとまりを「基本セット」と言うことにします。基本セットは、いくつあっても構いません。ファイルの上に書いたものから優先的に適用されます。

次の2行を書くと、実際にあるファイル名やディレクトリ名のときは、RewriteRuleを適用しません。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRuleディレクティブの第三引数に、[L]フラグを書くと、マッチした場合は、それ以降の基本セットを無視します。

以上は、マニュアルをよく読むとわかります。

以下が、マニュアルでは分かりにくい部分です。

RewriteCondの効力は、それが属する基本セット内だけにしか及びません。同じ効力を別の基本セット内でも使いたい場合は、その基本セット内でRewriteCondを書く必要があります。


[L]フラグつきのRewriteRuleを連続して書いても、二つの基本セットとは見なされません。一つ目の[L]は無視されます。つまり、一つ目のRewriteRuleにマッチしても、さらに、重複して次のRewriteRuleが適用されます。


一つ目のRewriteRuleにマッチしたら、次のRewriteRuleを無視したい場合は、この2つのRewriteRuleの間に、RewriteCondを入れて下さい。これで、2つのことなる基本セットとみなされます。
id:tokyosmash

実際に実行してみましたが、hogehoge.com/aaa.php?ID=12 で飛ばされる先のURLは正常に表示されました。

つまり hogehoge.com/12.html

にアクセスすると正常に表示されたという事です。

しかし、従来からある通常のページが表示されません。

つまり hogehoge.com/company.html のようなページです。

表示されないといっても404や500エラーではなく、hogehoge.com/aaa.php?ID=companyにアクセスした状態になります。

真っ白な画面です。


少し考えてみました。


RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

この2行を書くことで「実際にあるページは通常通り表示される」との事ですが、ほぼ全てのページをダイナミックパブリッシングしているので、hogehoge.com/company.htmlのようなページも「実際には存在しない」と見なされているのではないでしょうか。

index.htmlのみは静的HTMLで書き出しているのですが、こちらは正常に表示されます。

そこで一つ思いつきました。

aaa.php?ID=$1で飛ばしたい先のURLを.htmlではなくて.phpにして、

RewriteRule ^(.*)\.php$ aaa.php?ID=$1

にすればいいのではないでしょうか。

RewriteRule ^(.*)\.html$ aaa.php?ID=$1

だと通常のページ(全てhtmlで書き出されています)を拾ってしまうので。


これでうまくいきました。

どうでしょうか?

2007/03/12 05:10:12

その他の回答3件)

id:b-wind No.1

回答回数3344ベストアンサー獲得回数440

ポイント33pt

Apache なら mod_rewrite でそう見せかければよい。

RewriteEngine On
RewriteRule ^/([a-zA-Z0-9]+\.html /aaa.php?ID=$1 [L]

で、実際の処理は aaa.php に記述。

mod_rewrite

id:tokyosmash

なるほどこれは勉強になります!

SEO対策にも使えますね。

ただこのままだと既存のHTMLファイルへのアクセスが全部飛ばされちゃいますよね。ディレクトリを別にすれば解決しますが。

実は試してみたのですが、うまくいきません。

参考URLとb-windさんの書き方が微妙に違うのですが、ちょっと混乱しています。

恐らく参考URLの方に記述ミスがあるとは思うのですが。。


他の方法があれば、よろしくお願いします。回答はまだまだ受け付けています。実際にパブリッシュする方法があれば教えてください。

2007/03/11 02:16:18
id:nandedarou No.2

回答回数230ベストアンサー獲得回数34

ポイント19pt
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\.html$ aaa.php?ID=$1 [L]

これで、既存のHTMLファイルへのアクセスも大丈夫です。

お試しください。

id:tokyosmash

昨日から度々お世話になっています。

うーんうまくいきません。

URLが存在しない、ってなります。

.htaccessをテキストファイルで編集する際に

\ が ¥ に変換されてしまうのですがそれは問題ないのでしょうか?

2007/03/11 02:39:11
id:nandedarou No.3

回答回数230ベストアンサー獲得回数34

ポイント23pt

それでは、私の行った実験と同じようにして頂けますか?

※下記の.htaccessとaaa.phpを同じディレクトリに置いて下さい。

.htaccessの中身(先の回答と同じものです。)

\ が ¥ に変換されてしまうのは、OKです。

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\.html$ aaa.php?ID=$1 [L]

// aaa.phpの中身

<?php
echo "GET:";
print_r($_GET);
?>

実験1

ブラウザのアドレスに次のように入力

もちろん、www.hogehoge.comはご自分の環境にあわせて変更して下さい。

http://www.hogehoge.com/aaa.php?ID=bbb

次のようにブラウザに表示されます。

もし、この段階でダメならば、.htaccessの問題ではないですよね。

GET:Array ( [ID] => bbb )

実験2

ブラウザのアドレスに次のように入力

www.hogehoge.comはご自分の環境にあわせて変更して下さい。

注意1:ここで、最後に「html/」などと「/」をつけてはダメですよ。

注意2:htmlであって、htmはダメ

http://www.hogehoge.com/ddd.html

次のようにブラウザに表示されます。

GET:Array ( [ID] => ddd )

以上どうでしょうか?


※質問終了前でも、この質問・回答へのコメントを書けるようにして頂けると、ありがたいです。今から変えるのは無理でしょうか

id:tokyosmash

ご丁寧にありがとうございます。

早速実験してみました。

1は出来ました。

2で500エラーになってしまいます。

実はサーバーはXREA(有料)なのですが、これが原因でしょうか?

>質問終了前でも、この質問・回答へのコメントを書けるよう

このような設定が出来るのですね。最近はてなを始めたもので知りませんでした。

2007/03/11 03:49:52
id:nandedarou No.4

回答回数230ベストアンサー獲得回数34ここでベストアンサー

ポイント100pt

まず、結論からいいます。

tokyosmashさんが、お使いのMovableTypeで使用している.htaccessのRewriteEngine onの直後に、以下3行をコピーして貼り付けて下さい。

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)\.html$ aaa.php?ID=$1 [L]

以下、理由を知りたい場合は、読んでください。


http://www.net-newbie.com/trans/mod_rewrite.html

を参考にしましたが、よくわからないところがありました。

以下は、実験を繰り返して得た結論です。説明が正確でない部分があると思いますが、ご容赦ください。


詳しい書き方は上記リンクに譲るとして、RewriteCondディレクティブとRewriteRuleディレクティブ、そして、RewriteRuleディレクティブの第三引数、[L]フラグの関係について書きます。


RewriteCondや、[L]フラグがないと文法的に誤りというわけではありませんが、以下は、それがあるのを前提に説明します。RewriteCondから、RewriteRuleの[L]までが一つのまとまりと考えると分かりやすいです。今回の説明の中では、このまとまりを「基本セット」と言うことにします。基本セットは、いくつあっても構いません。ファイルの上に書いたものから優先的に適用されます。

次の2行を書くと、実際にあるファイル名やディレクトリ名のときは、RewriteRuleを適用しません。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRuleディレクティブの第三引数に、[L]フラグを書くと、マッチした場合は、それ以降の基本セットを無視します。

以上は、マニュアルをよく読むとわかります。

以下が、マニュアルでは分かりにくい部分です。

RewriteCondの効力は、それが属する基本セット内だけにしか及びません。同じ効力を別の基本セット内でも使いたい場合は、その基本セット内でRewriteCondを書く必要があります。


[L]フラグつきのRewriteRuleを連続して書いても、二つの基本セットとは見なされません。一つ目の[L]は無視されます。つまり、一つ目のRewriteRuleにマッチしても、さらに、重複して次のRewriteRuleが適用されます。


一つ目のRewriteRuleにマッチしたら、次のRewriteRuleを無視したい場合は、この2つのRewriteRuleの間に、RewriteCondを入れて下さい。これで、2つのことなる基本セットとみなされます。
id:tokyosmash

実際に実行してみましたが、hogehoge.com/aaa.php?ID=12 で飛ばされる先のURLは正常に表示されました。

つまり hogehoge.com/12.html

にアクセスすると正常に表示されたという事です。

しかし、従来からある通常のページが表示されません。

つまり hogehoge.com/company.html のようなページです。

表示されないといっても404や500エラーではなく、hogehoge.com/aaa.php?ID=companyにアクセスした状態になります。

真っ白な画面です。


少し考えてみました。


RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

この2行を書くことで「実際にあるページは通常通り表示される」との事ですが、ほぼ全てのページをダイナミックパブリッシングしているので、hogehoge.com/company.htmlのようなページも「実際には存在しない」と見なされているのではないでしょうか。

index.htmlのみは静的HTMLで書き出しているのですが、こちらは正常に表示されます。

そこで一つ思いつきました。

aaa.php?ID=$1で飛ばしたい先のURLを.htmlではなくて.phpにして、

RewriteRule ^(.*)\.php$ aaa.php?ID=$1

にすればいいのではないでしょうか。

RewriteRule ^(.*)\.html$ aaa.php?ID=$1

だと通常のページ(全てhtmlで書き出されています)を拾ってしまうので。


これでうまくいきました。

どうでしょうか?

2007/03/12 05:10:12
  • id:tokyosmash
    追記です。

    VPSサーバを一つ契約していてそちらで試してみたところうまくいきました。
    これはXREAだからうまくいかないのですね。。
  • id:nandedarou
    私のサーバも、XREAですよ。ちゃんとできます。
  • id:tokyosmash
    原因がわかりました。
    MovableTypeのダイナミックパブリッシングを使っているのですが、それが生成する.htaccess内に以下の記述がありました。

    RewriteRule ^(.*)$ /mt-dynamic.php [L,QSA]

    これを削除したところうまくいきました。

    しかしこれを削除すると他のページが全く表示されなくなってしまいます。

    RewriteRule ^(.*)$ /mt-dynamic.php [L,QSA]
     RewriteRule ^(.*)\.html$ aaa.php?ID=$1 [L]

    この2文を共存させる事はできないのでしょうか??

  • id:nandedarou
    [L]は、条件にマッチした場合そこで判定を終了する(以下に続くRewriteRuleを評価しない) という意味なので、
    RewriteRule ^(.*)\.html$ aaa.php?ID=$1 [L]
    RewriteRule ^(.*)$ /mt-dynamic.php [L,QSA]
    の順番で書けばOKです!

  • id:tokyosmash

    ## %%%%%%% Movable Type generated this part; don't remove this line! %%%%%%%
    # Disable fancy indexes, so mt-dynamic.php gets a chance...
    Options -Indexes +SymLinksIfOwnerMatch
    <IfModule mod_rewrite.c>
    # The mod_rewrite solution is the preferred way to invoke
    # dynamic pages, because of its flexibility.

    # Add mt-dynamic.php to the list of DirectoryIndex options, listing it last,
    # so it is invoked only if the common choices aren't present...
    <IfModule mod_dir.c>
    DirectoryIndex index.php index.html index.htm default.htm default.html default.asp /mt-dynamic.php
    </IfModule>

    RewriteEngine on

    # don't serve mt-dynamic.php if the request is for a real directory
    # (allows the DirectoryIndex lookup to function)
    RewriteCond %{REQUEST_FILENAME} !-d

    # don't serve mt-dynamic.php if the request is for a real file
    # (allows the actual file to be served)
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !\.(cgi|css|gif|jp*g|png)$
    RewriteCond %{REQUEST_FILENAME} !\.(cgi|css|gif|jp*g|png)$
    RewriteCond %{REQUEST_FILENAME} !\.(cgi|css|gif|jp*g|png)$
    RewriteCond %{REQUEST_FILENAME} !\.(cgi|css|gif|jp*g|png)$
    RewriteCond %{REQUEST_FILENAME} !\.(cgi|css|gif|jp*g|png)$
    RewriteCond %{REQUEST_FILENAME} !\.(cgi|css|gif|jp*g|png)$
    RewriteCond %{REQUEST_FILENAME} !\.(cgi|css|gif|jp*g|png)$

    # anything else is handed to mt-dynamic.php for resolution
    RewriteRule ^(.*)\.html$ aaa.php?ID=$1 [L]
    RewriteRule ^(.*)$ /mt-dynamic.php [L,QSA]

    </IfModule>

    <IfModule !mod_rewrite.c>
    # if mod_rewrite is unavailable, we forward any missing page
    # or unresolved directory index requests to mtview
    # if mt-dynamic.php can resolve the request, it returns a 200
    # result code which prevents any 4xx error code from going
    # to the server's access logs. However, an error will be
    # reported in the error log file. If this is your only choice,
    # and you want to suppress these messages, adding a "LogLevel crit"
    # directive within your VirtualHost or root configuration for
    # Apache will turn them off.
    ErrorDocument 404 /mt-dynamic.php
    ErrorDocument 403 /mt-dynamic.php
    </IfModule>
    ## ******* Movable Type generated this part; don't remove this line! *******



    これで500になってしまいます。。
  • id:nandedarou
    ディレクトリやaaa.phpのパーミションを777にして、みるとどうなりますか?変わらなかったら、パーミションをもとに戻してください。
  • id:nandedarou
    aaa.phpの前にスラッシュ「/」をいれれば、いけるかも…。
    /mt-dynamic.php
    ってなってるから、
  • id:nandedarou
    RewriteRule ^(.*)\.html$ /aaa.php?ID=$1 [L]

    RewriteRule ^/(.*)\.html$ /aaa.php?ID=$1 [L]

    試して見てください。
    それでも、だめなら、.htaccessの先頭に書いてみて下さい。
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)\.html$ aaa.php?ID=$1 [L]
    4行目は、上記のように、スラッシュを入れたりしてみて下さい。
    それでは、また。

  • id:tokyosmash
    今はzero3からしか観覧できません

    本日中にまたご報告します。毎度ご丁寧にありがとうございます!
  • id:tokyosmash
    色々と試してみましたが、全て500になってしまいます。
    やはりMovableTypeが吐き出す部分とうまくいかないみたいです。

    mod_rewriteの方法は諦める事とします。
    しかしとても勉強になりました。
    他のところで使ってみようと思います。
  • id:nandedarou
    tokyosmashさんの.htaccessの内容を教えてもらったので、
    それを使って私のサーバで実験できることをいまさらながら、
    思いつきました。
    お手数お掛けしました。ただいま、実験中です。
    ちょっと、解決のきっかけがつかめたところです。
    また、後で結果報告致します。お待ちください。

    (もし、だめでも、phpで解決する方法も大雑把な方針は考えてありますが、.htaccessで解決するのが常套手段だと思います。)
  • id:tokyosmash
    ありがとうございます!
    ここまで付き合ってもらって、ホント感謝感謝です。

    何卒よろしくお願いします。
  • id:nandedarou
    大変時間が掛かってしまいましたが、ようやく理屈が分かりました。
    同じところでつまづいた人が参考にするとき、解答欄に書いた方が分かりやすいと思いますので、解答欄に書きますね!
  • id:tokyosmash
    よろしくお願いします!
  • id:nandedarou
    すみません。頭のなかを整理して書くのに時間が掛かってしまいました。こんな時間まで、起きててくれたんですね、ありがとうございました。
  • id:tokyosmash
    >こんな時間まで

    いえいえ、それはこちらの台詞でございまして。。
    本当にありがとうございます。
    回答への返信で書いていますが、静的URL(.phpですが)に変換できました!
  • id:nandedarou
    company.htmlが確実に存在しているのに、コメントのような状態になったのでしょうか?
  • id:tokyosmash
    すいません「確実に存在」はしていません。
    MovableTypeのダイナミックパブリッシングによって生成された見かけ上のURLです。

    ですから以下の2行でRewriteRuleを防ぐ事ができなかったのですね。
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d

    index.htmlは確実に存在しており、静的なHTMLファイルとしてサーバーに存在しています。こちらは正常に表示されました。

    記事が多すぎてMovableTypeがまともに動かなくなってしまって、そこで大多数の記事をダイナミックパブリッシングしたのです。
    説明不足ですみませんでした。
  • id:nandedarou
    なるほど、それなら、そういうことになりますね。
    私は、一回目のアクセスで静的ページをつくり出し、次回からはその静的ページを出力するのだと思っておりました。勘違いしてました。

    MovableTypeで、.htm のページがないならば、
    RewriteRule ^(.*)\.htm$ aaa.php?ID=$1 [L]
    というように。エルをとるだけでも、大丈夫だと思います。

    もちろん。.phpでも構いません。
    ※ただし、IDがaaaとなるものは、aaa.phpとなり、実際に存在するのでダメですね。

    オリジナルの拡張子でもokです。
  • id:tokyosmash
    どうやら静的ページを吐き出すわけでは無いようです。サーバーにはその形跡が見られません。説明不足で申し訳なかったです。

    ほんの1週間前まで「SEOには静的HTMLだ。PHPなんてありえない」と考えてたのですが、MovableTypeの処理能力に限界が来てしまってやむを得ずダイナミック化したのです。その過程でPHPを勉強しようと思ったのですが面白いですね。MySQL、GoogleMAPと組み合わせれば色々な事ができて、ちょっとしたプログラマー気分です。

    RewriteRuleの記号の羅列は正規表現ですよね。これも数日前に知りまして、勉強リストに入れておりました。IDに入る規則性は6桁未満の数字というくらいでしょうか。MovableTypeで吐き出すファイル名は6桁なので、「それより少ない桁数の数字」という正規表現を勉強がてら作ってみようと思います。

    >htm
    なるほどその手がありましたね。これならphpよりもSEO効果が高そうです。オリジナルの拡張子でもOKだなんて、ホント何でも出来ちゃうんですね。。まさに黒魔術だと思います。
  • id:nandedarou
    MovableTypeは使ったことがなくて、知識不足でした。
    私も非常に勉強になりました。お付き合いいただいありがとうございました。
    解決策が見つかってよかったです。とっても清清しい朝になりました。
    それでは、また!
  • id:tokyosmash
    ここ数日どうもありがとうございました。

    またよろしくお願い致します!
  • id:b-wind
    次回は是非コメント欄でのチャットは控えていただきたい。
    ぜーんぶメールで飛んでくるので。
  • id:nandedarou
    はてなに登録してあるメールをほとんど確認しない為、「この質問・回答へコメント」が他の回答者に送信される仕様だと気づきませんでした。tokyosmashさんは、「最近はてなを始めた」とこことなので、知らなかったと思います。コメントでのやりとりに誘導したのは私ですので、私の責任です。ご迷惑お掛けし、申し訳ありませんでした。
  • id:b-wind
    id:nandedarou さん。
    まぁ仕様なのは知っているので文句を言うべきではないと思うんですが、さすがに今回は数が多かったんで大人気なくなってしまいました。
    あまり気にしないでください。
  • id:nandedarou
    お気遣いありがとうございます。
    今後は、簡潔かつ適切に回答できるように頑張ります!
  • id:tokyosmash
    id:b-windさん

    ご迷惑をおかけしたようですみませんでした。
    以後気をつけます。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません