PHPを研究しながら、OKWaveやはてな人力検索のような

Q&Aに似たWebサービスを個人で開発しているのですが、
ユーザーからの投稿をどのように実装するかで悩んでいます。

現在は、ユーザの投稿があった時点で投稿ごとのページの
PHPファイルをfopen関数で作成して、
サーバに1週間程度保存するという仕様を考えています。
つまり、投稿があるたびにファイルを作成して、
専用のディレクトリにどんどん貯まっていく形になります。
(ちなみに、写真もページに掲載できるようにする予定ですが、
写真はデータベース(MySQL)に入れることを考えています。)

この「投稿時にPHPファイルを作成し、どんどん貯めていく」
というのは適切な実装の方法でしょうか?
はてな人力検索やOKWaveなどのサイトのURLを見ても、
どういうやり方で実装しているのか想像できませんでした。
(人力検索の各ファイル名はタイムスタンプでしょうか?)

もし「普通はそんなやり方はしないよ」などありましたら、
是非アドバイスを頂けると嬉しいです。
ド素人ですが、よろしくお願い致します。

回答の条件
  • 1人20回まで
  • 13歳以上
  • 登録:2010/11/28 19:47:59
  • 終了:2010/12/05 19:50:02

ベストアンサー

id:niwa-mikiho No.5

niwa-mikiho回答回数508ベストアンサー獲得回数382010/11/29 08:02:24

ポイント25pt

質問ごとに php を大量生産した場合、php ファイルにエラーがあった場合それら全てに対して編集したファイルをコピーしなければなりません。

数百程度であれば問題無いでしょうが、数万にも及んだ場合はかなり面倒なことになります。



そこで、 Apache の設定に


/USERNAME/QUESTION/index.php


q_and_a.php?user=USERNAME&q=QUESTION


として呼ばせるように出来る機能 (mod_rewrite) があります。


こうすれば、質問ごとに php ファイルを大量生産しなくても済みますし、

php ファイルにエラーが出ても、1つのファイルを編集すれだけで全てのアクセスに編集結果が適応されます。



また、バイナリ (JPEG など) をバイナリに入れるの管理が簡単になるかと思いますが、

データベースが無駄に太るのであまりオススメは出来ません。


JPEG のハッシュ値を取り、例えば je74jgjksdr78yt445y895h みたいな値が取れた場合、

img/je/74/jg/jk/sdr78yt445y895h.jpg のようにディレクトリを掘り下げる方法がオススメ出来ます。




これは1つのディレクトリに数万というファイルが集まらないようにするための対策です。


ブログであればユーザーごとにディレクトリを作ってそこに置くべきでしょうが、 Q&A なら

そんなに頻繁に画像をアップされることも無いでしょうから、ユーザーごとのディレクトリは作らなくても

大丈夫かと思います。

id:pmvct

ご回答、有り難うございます。

なるほど、大変参考になりました。

確かにPHPファイルを多数持つのは問題がありそうだと

思っていたのですが、具体的に対策まで教えて頂き、恐縮です。

ハッシュ値については全く初耳で、これも参考になりました。

実は現在開発中のサイトはQ&Aと機能は似ているのですが、

かなり異なった性質を持つサイトになる予定で、

ほぼ全ての投稿に1〜2枚の写真が含まれることになると思います。

いずれにしろ、ハッシュ値のお話は活用できそうです。

調べたところ、連番よりも推測されるリスクも少ないのですね。

ところで「1つのディレクトリにファイルが集まらないように」

するためとのことですが、多数の画像が同一ディレクトリに存在すると、

取得するのに時間がかかってしまうということでしょうか?

ちなみに、img/質問のID/je/74/jg/jk/sdr78yt445y895h.jpg

のようなディレクトリ構成を考えています。

2010/11/29 16:47:21

その他の回答(6件)

id:windofjuly No.1

うぃんど回答回数2625ベストアンサー獲得回数11492010/11/28 20:41:32

ポイント26pt

【1】古風な方式

回線も細く、サーバーも貧弱(容量数MBでデータベースなども使えず)だった時代は、その方法が主流でした

投稿単位ではなく、スレッド単位(人力検索であれば質問単位に相当)でファイルを作成して、

レス(回答やコメントに相当)はファイルに追記するという手を私も使っていました

 

 最近はGB単位で借りることが出来ますし、サーバーも強力になって、データベースも容易に利用可能な環境が増えてますので、

今風であれば「そんなやり方はしないよ」ということになるかもしれませんが、サーバー負荷を考えて、

「記事は(検索しやすいように)データベースで、写真は(負荷を抑えるために)個別にファイルで保管」という手を、

使う場面もありますので一概にダメというものでもなく実際のところはケースバイケースです

  

【2】データベースの利便性

ファイルを作成する方法では検索やバックアップの仕組みを用意することが大変になりますが、

データベースであれば苦も無く一瞬で記事の検索もできますし、バックアップも楽です

 

【3】何を身に付けたいのかによっても選択肢は変わる

(1)phpを身に付けたい?

ゼロから作るのは言語の学習という点で悪くないと思うのですが、時間がかかる割には得るものが少ないとも言えます

特にphpで製作するWEBサイトは必要な関数だけ覚えれば出来てしまうので、作りながらは不適切と言っても良いでしょう

phpを身に付けたいのであればマニュアルにある言語リファレンスを熟読し、関数リファレンスのサンプルをじっくり試してみることが近道でしょう

http://www.php.net/manual/ja/

(2)Webシステムの製作を身に付けたい?

自力でゼロから作るよりも、世にある多くのフリーのシステム(wordpressなど)を使って、

「どこでどのような処理をしているのか?」を紐解いていくほうが早いでしょう

phpについては紐解いていく最中で、必要な関数について学んでいけばいいということになりますが、

言語リファレンスだけは先に身につけておかないと紐解くにも紐解けないので、先に熟読しましょう

 

以上、ひとまず、ざっくりとです

以下、今のところは雑談です

【4】管理方法 - ここはサイトのHTMLソースコードなどを読んで行った推測です

(1)人力検索

質問投稿、回答、コメントなど全てが1つの連番になっているようです(そのため前後の質問投稿の番号が続き番ではなく飛んでいる)

質問の場合と、回答/コメントの場合でデータベースに登録する際に違いをつけて区別しているようです

(2)OKWave

質問投稿は質問投稿として1つの連番になっていて、回答投稿は回答投稿として1つの連番となっているようです

id:pmvct

お返事大変有り難うございます。

【1】【2】私の説明が下手で申し訳ないのですが、

基本的に投稿内容のテキストデータやその他情報に

関してはMySQLでも管理するつもりです。

ただ、記事の実ファイル(PHPかHTML)を保持しておいて、

そのURLリンクを記事一覧画面で利用するのがわかりやすいと思いました。

しかし「OKWave等のサイトは動的URLを静的に偽装しているのでは」

などというネットの記事を読んでいるうちに、頭が混乱してしまいました…。

記事ごとの実ファイルを常に保持しておいた方がいいのか、

それとも、URL内で値を渡して動的に生成するのが常識的なのでしょうか?

私の不理解から、質問内容がおかしければご指摘くださると助かります。

【3】また、このサービスを開発する目的ですが、

勉強目的ではなく、この「システム開発」自体が目的です。

今まで頭に思い描いてきたことを自分自身で

実現したくなり、手探りで開発を始めました。

勿論、そのために必要な技術は喜んで習得したいと考えています。

ご紹介頂いた言語リファレンスも、是非読ませて頂きます!

【4】についても大変参考になりました。

連番の仕組みを自分でじっくりと見てみたいと思います。

2010/11/28 22:34:16
id:deflation No.2

deflation回答回数1036ベストアンサー獲得回数1262010/11/28 20:43:50

ポイント26pt

ユーザの投稿があった時点で投稿ごとのページの

PHPファイルをfopen関数で作成して、

これは「テキストファイル」の誤りではないかと想うのですが、それであれば適当な実装方法です。

ユニークなファイル名を作ることがポイントになります。たとえば以下のようなファイル名です。

  1. 年月日時分秒ミリ秒のファイル名にする。
  2. 投稿ユーザーごとのフォルダを作り、年月日時分秒のファイル名にする。
  3. 投稿内容からハッシュ値を計算し(例:md5関数)、それをファイル名にする。

ちなみに、写真もページに掲載できるようにする予定ですが、

写真はデータベース(MySQL)に入れることを考えています

データベースは、その内容を検索する時に役立つ仕組みですから、写真のようなバイナリデータはファイルとして保管するのが定石です。年月または年月日ごとに画像フォルダを作り、ユニークファイル名で保管していくといいでしょう。

id:pmvct

お返事有り難うございます。

ファイルの件については、PHPまたはHTMLのファイルなので、

テキストファイルではあるのですが、それでよろしいのでしょうか…??

私の素人的な発想なのですが、MySQLでデータを管理するとしても、

HTMLファイルなどの実ファイルがディレクトリに存在しないと、

投稿の一覧画面等でそのファイルのURLをリンクとして

貼ることができないのではないかとまず考えたのです。

しかし、ネットで色々と調べているうちに、

「OKWaveなどのURLは動的URLを静的に偽装しているのでは」

などという記事を目にして、実装方法について悩んでしまったのです。

記事ごとの実ファイルを保持しておいた方がいいのか、それとも、

URL内でGETで値を渡して動的に(?)生成するのがいいのでしょうか。

私の不理解からおかしなことを言っていたら、ご指摘頂けると助かります。

写真はファイルとして保管した方がいいのですね。

また、ユニークなファイル名の付け方も助かりました。

是非、参考にさせて頂きます!

2010/11/28 23:03:14
id:online_p No.3

online_p回答回数1153ベストアンサー獲得回数592010/11/28 22:34:23

ポイント9pt

ローカルファイルにためるだけならば、perlの方がよいのでは。http://www

id:pmvct

お返事有り難うございます。

まずローカルに貯めるべきなのかどうなのかがわかりません…。

こういったサイトを実装する場合の、

開発者の方々の「普通はこうするだろう」というような

常識的な発想がまだできていないのです。

また、PHPの研究をすでに始めているため、

できればPHPで実装したいと考えています。

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

2010/11/28 23:12:55
id:hiroponta No.4

ぽこたん回答回数517ベストアンサー獲得回数262010/11/28 22:55:42

ポイント17pt

fopenは、基本的にテキストを開く関数ですよね?

ログとかなら分かりますけど、投稿ならデータベースとPHPの方が圧倒的に良いです。

写真をデータベースに入れるとありますけど、写真ならむしろフォルダに入れる方がいいかもしれません。

発想がちょっと逆なのかもしれません。

はてな人力検索、OKWaveなどの質問回答サイトを作りたいのであれば、

オープンソースのCMSでそういうのが出ていたと思うので、

いろいろなCMSを見れば良いと思います。

id:pmvct

お返事有り難うございます。

私の書き方が下手で大変申し訳ないのですが、

投稿のテキストデータ類は基本的にMySQLで管理しています。

ただ、その一方で、投稿ごとにPHPの実ファイルがフォルダに存在しないと

記事一覧画面などでURLのリンクを作れないのではないかと思いました。

(この考え方に根本的に問題があったようです…。)

fopenは指定したファイルが存在しない場合にファイルを作成する

とのことなので、投稿ごとの実ファイル作成に使用していました。

そして、その中にfwriteで投稿内容のテキストを書き込んでいました。

皆さんのご意見を拝見すると、適切なやり方ではなかったようですね…。

写真の場合はフォルダに入れておけばいいのですね。

またCMSに関しては、自由があまり利かないイメージがあったのと、

プログラミングに慣れておきたいという気持ちもあったので

使用を考えていませんでしたが、一度検討してみたいと思います!

2010/11/29 15:25:58
id:niwa-mikiho No.5

niwa-mikiho回答回数508ベストアンサー獲得回数382010/11/29 08:02:24ここでベストアンサー

ポイント25pt

質問ごとに php を大量生産した場合、php ファイルにエラーがあった場合それら全てに対して編集したファイルをコピーしなければなりません。

数百程度であれば問題無いでしょうが、数万にも及んだ場合はかなり面倒なことになります。



そこで、 Apache の設定に


/USERNAME/QUESTION/index.php


q_and_a.php?user=USERNAME&q=QUESTION


として呼ばせるように出来る機能 (mod_rewrite) があります。


こうすれば、質問ごとに php ファイルを大量生産しなくても済みますし、

php ファイルにエラーが出ても、1つのファイルを編集すれだけで全てのアクセスに編集結果が適応されます。



また、バイナリ (JPEG など) をバイナリに入れるの管理が簡単になるかと思いますが、

データベースが無駄に太るのであまりオススメは出来ません。


JPEG のハッシュ値を取り、例えば je74jgjksdr78yt445y895h みたいな値が取れた場合、

img/je/74/jg/jk/sdr78yt445y895h.jpg のようにディレクトリを掘り下げる方法がオススメ出来ます。




これは1つのディレクトリに数万というファイルが集まらないようにするための対策です。


ブログであればユーザーごとにディレクトリを作ってそこに置くべきでしょうが、 Q&A なら

そんなに頻繁に画像をアップされることも無いでしょうから、ユーザーごとのディレクトリは作らなくても

大丈夫かと思います。

id:pmvct

ご回答、有り難うございます。

なるほど、大変参考になりました。

確かにPHPファイルを多数持つのは問題がありそうだと

思っていたのですが、具体的に対策まで教えて頂き、恐縮です。

ハッシュ値については全く初耳で、これも参考になりました。

実は現在開発中のサイトはQ&Aと機能は似ているのですが、

かなり異なった性質を持つサイトになる予定で、

ほぼ全ての投稿に1〜2枚の写真が含まれることになると思います。

いずれにしろ、ハッシュ値のお話は活用できそうです。

調べたところ、連番よりも推測されるリスクも少ないのですね。

ところで「1つのディレクトリにファイルが集まらないように」

するためとのことですが、多数の画像が同一ディレクトリに存在すると、

取得するのに時間がかかってしまうということでしょうか?

ちなみに、img/質問のID/je/74/jg/jk/sdr78yt445y895h.jpg

のようなディレクトリ構成を考えています。

2010/11/29 16:47:21
id:deflation No.6

deflation回答回数1036ベストアンサー獲得回数1262010/11/29 12:11:14

ポイント17pt

私の素人的な発想なのですが、MySQLでデータを管理するとしても、

HTMLファイルなどの実ファイルがディレクトリに存在しないと、

投稿の一覧画面等でそのファイルのURLをリンクとして

貼ることができないのではないかとまず考えたのです。

そのお考えは間違っています。


悪意のあるユーザーが、システムを破壊したり踏み台にするためのHTML(JavaScript)やPHPを埋め込むかもしれません。→クロスサイトスクリプティング(XSS)

これを避けるため、HTMLタグやJavaScript、PHPコードは一切受け付けない、純粋なテキストしか受け付けない投稿サイトが普通です。

「はてな」のように、文字修飾のためのHTMLタグを許しているところもあります。


PHPのhtmlspecialchars関数とstrip_tags関数の第2引数を指定することで、比較的簡単にXSS対策ができます。


こうして保管された、“ほぼテキストに近い”ファイルは、SSI(Server Side Include)を使って静的に読み込んだり、PHPを使って動的に読み込みます。

id:pmvct

ご回答有り難うございます。

クロスサイトスクリプティングについては、

是非、実装時に気をつけたいと思います。

テキストファイルを保持する場合は、

そのようにして作成した上で、PHPで動的に読み込むのですね。

今後、選択肢の一つとして検討させて頂きます。

2010/11/29 17:07:53
id:windofiuly No.7

windofiuly回答回数62ベストアンサー獲得回数22010/11/29 14:25:02

2番目の回答の方は、最近よく見かけますが、ググる能力だけでPHPに関する知識はあまりないようですね。もう少し勉強しましょう。

 

3番目の回答の方は、質問をきちんと読んでから回答しましょう。

 

4,5番目の回答の方は、そもそも回答になっていません。ポイントだけかすめ取ろうとする悪質回答者の一例です。

id:pmvct

コメントの方にお返事ありがとうございます。

なるほど、データはデータベースで一元管理は納得しました。

細かなアドバイス、大変参考になりました。

画像については、データベースで持たせるかどうか、

じっくりと検討したいと思います。

「既存のもの」というのはWordPressも含めて、でしょうか。

現在、WordPressでQ&Aサイトのような機能を

どこまで実現できるか調べています。

部分的に機能を利用できるのなら最高ですが…。

また、他のCMSも是非チェックしたいと思います。

「研究」という言葉についても、

今後「勉強している」と表現したいと思います。

ご指摘どうもありがとうございました。

2010/11/29 18:14:41
  • id:windofjuly
    うぃんど 2010/11/28 23:58:04
    >MySQLでも管理
     
    「でも」すなわち「ファイルとデータベースの両方で平行して管理」は複雑で面倒ですし、
    幾人もが読み書きをするシステムにおけるファイル操作は非常に難しくパフォーマンスもよくはありません
    データベースを用いた場合は読み書きをデータベース管理システム(MySQLやPostgreSQLなどのこと)が行ってくれますので、
    利用者はSQLを投げるだけで済み、誰が作っても「そこそこのパフォーマンス」を出すことはできます
    (高いパフォーマンスを得るためにはチューニングが必要なので熟練が必要です)
     
    >動的URLを静的に偽装している
     
    人力検索など多くのサイトで用いられていますね
    phpではなくWEBサーバーの方で q.hatena.ne.jp/1290941276 を、
    q.hatena.ne.jp/検索php?パラメータ=1290941276といった具合に動的に変換させるだけですから、
    php側では特に意識する必要も無く、非常に簡素で済みますし、システムの改変も楽になります
     
    >URL内で値を渡して動的に生成するのが常識的
     
    常識/非常識で選ぶものではなくて、求められた要件にあわせて選ぶものだと認識しておかないと後々面倒です
    わざわざファイルとデータベースの二元管理にするよりも、データベースで一元管理したほうが、
    簡素でミスも少なく、そこそこのパフォーマンスが得られるとなれば、どちらを選ぶかはおのずと・・・
     
    画像をデータベース内に収めるか、ファイルとして1枚1枚保管するかについては、
    記事と写真を常に一緒にして扱うならばデータベース内に収めて一元管理が楽ですし、
    記事を無視して画像に直接アクセスされることを前提(画像を直接アクセスされることが多い)とするならば、
    画像は単独のファイルで保持するほうが楽です
     
    >システム開発自体が目的 
    >頭に思い描いてきたこと
     
    「開発が目的」ではなくて「作り上げることが目的」なようですね
    開発を行うためには、ある程度はWEBの仕組みから学ばなければなりませんし、
    それはphpだけにあらずwebサーバーの動作やクライアントとのやりとりの仕組みなどにも及びます
    回答中にも少し書きましたが既存のものを利用することにしたほうがより早く目的に到達することでしょう
    phpを覚えれば出来るというものではないと理解しておくと良いでしょう
     
    余談ですが、
    「phpを研究」という表現は「phpを深く調べて真髄を追い求める」という重い意味になってしまい、
    本来の目的が何であるのかを見えなくしてしまうので、
    「phpを学んでいます」くらいの表現にしておいたほうがいいと思います
  • id:b-wind
    >記事ごとの実ファイルを常に保持しておいた方がいいのか、
    >それとも、URL内で値を渡して動的に生成するのが常識的なのでしょうか?
    わざわざ実ファイルを作成して参照させる理由が分からん。
    まぁ、高負荷サイトならわずかなコストでも無視できないからそういうチューニングをする事もあるが。

    パフォーマンスが気になるなら、1度目のアクセスで生成結果のキャッシュを作って置いて
    次からはキャッシュにアクセスすれば良いんじゃね?
  • id:pmvct
    >b-windさん

    ご回答ありがとうございます。
    皆さんのご指摘をうけて、現在、
    実ファイルを保持しない実装を検討しています。
    私の知識不足のせいで混乱を招いてしまい、失礼しました。
    キャッシュについてはまだ頭になかったため、
    早速調べたいと思います!
  • id:windofjuly
    うぃんど 2010/11/29 18:39:02
    追記をコメント欄に書き、あのようなくだらない事を回答欄に書くという時点でおかしいと気づいていただきたいですが、
    回答1とコメント欄一番上は私「7月の風windofjuly」です
     
    回答7は一文字違いのまぎらわしいIDで私の回答やコメントをコピーして投稿したり、
    今回のようなことを繰り返している愉快犯です
     
    回答7の内容には一部納得の部分もあったりはしますが(そこが憎たらしいけど巧い。慣れている人のようだ)、
    回答7の投稿者こそがポイントを掠め取るために質問とは関係ないことだけを書いていますので、
    不適切な回答者の欄にチェックを入れておくことを勧めます
    (先週木曜日に運営に通報したのですが放置状態です。運営は対処してくれないので自分たちでやるしかないです)
  • id:pmvct
    >windofjulyさん

    なんと、そうだったんですね・・・・。
    私も「妙だな」とは感じたのですが、
    まさかIDが一文字違いとは・・・。
    何度もご回答頂いたのに気付かず、大変失礼致しました。
    今後、よく確認したいと思います。
  • id:pmvct
    皆さん、多数の回答を寄せて頂き、本当に有り難うございました。
    どの回答も大変参考になりました。

    ベストアンサーをどの方に差し上げるべきか、大変悩みましたが、
    最終的に最も希望に近い答えを下さった方に差し上げました。

    また次回、質問させて頂く際にもよろしくお願い致します。

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

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

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

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません