- 締切済み
スレッド式掲示板の作成について。
お暇を縫いこの質問を閲覧してくださり誠にありがとうございます。 Perlとプログラミング関連のほぼ初心者です。勉強そして修行中です…。 とあるちょっとした理由から今現在、最低限の機能のみを備えた極簡単なスレッド式の掲示板を作ろうとしています。 おそらく想定できる方法は幾つかあると思うのですが、スレッド(=すなわち一つ一つ独立したページとして存在する記事(の集まり))そのものを作り、その一つ一つへリンクさせ内容を閲覧するには具体的にどうすればいいでしょうか。 具体的にとは難しいかもしれませんが、重要なポイントを教えて頂ければ嬉しいです。 例えばWebPatioでは、スレッド一つ一つのリンクのURLの最後の部分が read.cgi “ ?no=(スレッド番号) ” となっているのですが、この部分のスレッド番号および“?no”はどういう風に割り振られているのでしょうか。 用意すべきログファイルは、インデックス(=トップページ、各スレッドへのリンクを表示する一覧・インデックス)に表示するスレッドの情報(スレッドタイトルと投稿者)を保存するものと、各スレッド内で返信された記事の投稿情報を保存するものが必要なのかなと考えています。 仮に一つ一つのスレッドのページを作るような処理を成功させ、そのリンクをインデックスに貼れたとして、各スレッド内にてコメントを返信しその内容を反映させるにはどういう処理を施すのが手っ取り早いのでしょうか。 それから素朴な疑問なのですが、スレッドを作成した際の親記事(=仮にNo0とする)もスレッド内の記事の一つ(No1以降の記事)と考えるべきですよね? 現在はまだ、トップのページのフォームから入力したもの(投稿者名、件名、コメント内容)をトップのページにポンと、上から投稿順に表示させるだけ、単一の記事を表示させるだけの状態です。とてもスレッド式とはいえないただの掲示板なので、この状態からどうすればスレッド式(っぽい)の状態を作り出せるのか、初心者なので至らないところもあると思いますが、何でも良いのでアドバイスをくだされば嬉しいです。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- shiren2
- ベストアンサー率47% (139/295)
データの保存形式にはCSVを使うのが基本です。 Text::CSVというモジュールを使っても良いですが、それ以外ならsplitとjoinを使います。 一行に纏めた形式で書き込んで、表示するときはそれを復元して使います。 my $name = "名前"; my $mail = "a@test.com"; my $str = join("<>", $name, $mail); print "$str\n"; # 名前<>a@test.com my @a = split("<>", $str); print "$a[0]\n"; # 名前 print "$a[1]\n"; # a@test.com ファイルのフォーマットはこんな感じでしょうか。 # THREAD id<>datetime<>name<>email<>message<>password # INDEX id<>datetime<>title<>count もし難しいようなら、入門書を一冊購入することをお勧めします。 私のお勧めは「10日でおぼえる Perl/CGI 入門教室」です。 これ一冊で、基本的な部分はすべて押さえられると思います。 http://www.amazon.co.jp/dp/4798109703/
- kabaokaba
- ベストアンサー率51% (724/1416)
コードを見る限り突っ込みところはあるのですが サーバの環境がわからないので・・・ #けどいまさら jcode.pl はないだろうし・・・ #ライブラリの拡張子が「cgi」なのもあれです. #warning/strictもお約束としていれておくほうがいいのかなとか #サブルーチン呼び出しに接頭辞「&」とか・・ #・・・全体的にperl4の雰囲気 アルゴリズムとデータ構造を考えましょう. 「IOの手間」とか そういうことは一切抜きにして 一つの考え方を. ある記事Aに対して,子供記事「B」がついたときに A -> B のように「方向つきリンク」がつくわけです. さらに,同じ記事「A」に,子供「C」がつけば A -> B -> C のように「枝分かれする」ことになります. となると,「記事」に必要なのはまずは 「本文」と「子供が何かを指すポインタ」です. さらに「記事」が別の記事の子供であることも示したいですので, 結局,一つの「記事」に対して ・自分自身のID ・「本文」 ・「親へのポインタ」 ・「子供へのポインタ」 の三つのものが必要です.これはハッシュとかオブジェクトにするのが お約束ですけど,とりあえずハッシュですか. %article = { ID -> "idnumber", #記事を一意に特定する番号 text => "本文", #本文を別ファイルにしてばらしているならそのファイル名とか parent => "親のID", children => ["子のID", "子のID"], # 子のIDで構築される無名配列 } こういうような構造をつくっておく必要があるでしょう. こういうデータ構造をつくっておけば, IDを指定することで ・記事の表示 ・親の提示 ・子供の提示 は可能です.また,ある記事「A」に対して,子供記事「B」を作る場合は ・記事「B」にIDをふって, ・本文を記録し, ・親が「A]であることを記録し ・子供が存在しないことを記録, ・記事「A」の子供ポインタに「B」を追加する ことで,できます. 記事の削除に関しては仕様を明確にすることが必要ですが, たとえば「記事」のデータ構造「%article」に 「表示」「非表示」のフラグをいれて「削除=非表示」とするとかが考えられます. ある記事を「削除」した場合に,それに子供があった場合にどうするのかとか そこは仕様を明確にしないといけません. 何はともあれ,「記事」とは「本文とポインタのセット」としおけば それで「ツリー」は構築できるわけで, あとは,巷の「アルゴリズム本」で「ツリー構造」の扱いを学べば どうとでもできるでしょう. 記事のタイトルや投稿時間・投稿者とかの追加は容易なので 適宜処理すればいいのだと思います.
お礼
お返事が遅くなりました。とても参考になりました。ご回答ありがとうございます、
- shiren2
- ベストアンサー率47% (139/295)
見た限りでは問題ないと思います。 スレッド単位で一つのファイルに出来れば、I/O処理は増えますが簡単になると思います。 スレッドIDと書き込みIDを組み合わせれば、書き込みまで特定出来ます。 #例えば52100番なら、52番スレッドの100番の書き込み レスポンス先の書き込みIDも記録すれば、後々ツリー式にも変更出来て便利だと思います。 そのくらいでしょうか。 特に問題はないですから、とりあえずやってみて、問題が出たら対応するでいいと思います。
補足
早速のご回答ありがとうございます。参考になりました。 仰るようにスレッド単位で一つのファイルを生成し保存できれば良いと思っております。 IDを分ければ書き込みも特定できるとのことで確かに便利だと思いましたので、後々にじっくり考えてみようかなと思います。 では、とりあえずどうにか初心者なりにやってみます…。 以下拙いですが現在のメイン表示部分のコードです。 外側からsetup.cgiを読み込んでデコード処理等を通しています。 もしご参考になれば、ここからどういう変更をすればスレッド式を確立できるか、重要なポイントをご教授頂ければ嬉しいです。 #!/usr/bin/perl -- require 'setup.cgi'; require 'jcode.pl'; &decode; if ( $FORM{'mode'} eq "regist" ) { ®ist; } &main; sub main{ &HTMLheader; print <<"FREE"; <div style="text-align:center; font-size:35">$title</div> <br> <hr> <div style="text-align:left; margin-left:30"> <table bgcolor="#F8EDCC" cellpaddi7ng="6"> <tr><td width="150"><a href="form.cgi">新しいスレッド</a></td><td><a href="">管理者</a></td></tr></table> </div> <hr> <div style="margin:45px"> <table width="80%" cellpadding="10"><tr bgcolor="#99CC99"> <td><span style="font-size:25; color:#ED6755"><b>スレッド一覧</b></span></td><td></td></tr> <tr><td width="55%"<span style="font-size:23">スレッド名</span></td><td width="25%"><span style="font-size:23">作成者</td></tr> FREE open(IN,"$data_file"); print <IN>; close(IN); print <<END; </table></div></BODY></HTML> END } sub regist{ open(OUT,">> $data_file"); print OUT "<tr><td>$FORM{'subt'}</td>\n"; print OUT "<td>$FORM{'name'}</td></tr>\n"; close(OUT); } ↓setup.cgiから sub decode { local($buf); read(STDIN, $buf, $ENV{'CONTENT_LENGTH'}); foreach ( split(/&/, $buf) ) { local($key, $val) = split(/=/); $val =~ tr/+/ /; $val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("H2", $1)/eg; &jcode'convert(*val, 'sjis'); $val =~ s/&/&/g; $val =~ s/"/"/g; $val =~ s/</</g; $val =~ s/>/>/g; $val =~ s/\r\n/<br>/g; $val =~ s/\r/<br>/g; $val =~ s/\n/<br>/g; $FORM{$key} = $val; } }
お礼
返事が遅くなってしまいました。ご回答ありがとうございます。なんとなく構想が描けてきました。