買い物かご 掲示板 メール DB 利用規定 FAQ サポートBBS


次(エラー処理)
前(ファイルの書きこみ)
必要なツール
最低限必要な知識
Make CGI Top
Basic

Home



ファイルの読みこみ --最低限必要な知識--


■例:掲示板の仕組み2

掲示板は、データをかきこんだだけでは役に立ちません。書き込まれたデータをホームページ上に出力できて、初めて掲示板が完成します。

前回、OPEN関数を使って、フォームから送信されたデータを「data.dat」へかきこみました。今回は、「data.dat」の内容を読み出し、HTMLタグを生成します。


■OPEN関数2

ファイルからデータ読み出す方法は以下の通りです。今回もOPEN関数を使います。

公式は・・・

open (IN,"$data_file") || &error('オープンエラー','指定された書込みファイルが開けません。');
@LINES = <IN>;
close (IN);

となります。

$data_fileが、書きこみデータを保存しているファイル名です。通常、初期設定で、
$data_file = 'data.dat'; 等と指定するようになっていますね。

|| &error('オープンエラー','指定された書込みファイルが開けません。')

は、設置するときに、書きこみファイルのアップロードを忘れたり、パーミッションの指定を間違えた場合に、サーバーエラーを出すことなく、終了できるようにエラーメッセージを出力させています。

||の右側は、$data_fileが何らかの原因で使えない場合の処理を記述します。

@LINES = <IN>;

は、「data.dat」内のデータを1行ずつ読み込み、配列「LINES」にセットしています。

close (IN)で、処理を終了します。

これで、data.dat内のデータが@LINESという配列に読みこまれました。以後、この配列を使って、処理を行ないます。配列に関しては、「配列」をご覧ください。



作ってみよう

用意するのは・・・

データ保存用のファイル「data.dat」
CGIスクリプト「view.cgi」
言わずと知れた「jcode.pl」

の3つのファイルです。「data.dat」の名前はお好きなように。拡張子もお好きなように。私のスクリプトでは、cgiになっています。cgiにすると、直接指定されても開けませんので、比較的安心です。

CGIスクリプトファイル名もお好きなように。

サンプルを用意していますので、ダウンロードして開いて見ましょう。このサンプルを使って説明します。理解できたら、今度は自分で作ってみましょうね。

このスクリプトでは、「data.dat」に書きこまれているデータを読み出し、テーブルタグを生成します。

pogi pogi@xxx.co.jp こんにちは。よろしくお願いします。
pagi pagi@xx.com よい天気ですね。
今日はハイキングに行きました。
pegi pegi@xxxx.net 仕事が忙しくて、せっかくの日曜日
なのに、休日出勤です。

こんな形で表示します。最も基本的な形ですね。

サンプルview.cgi

サンプル(sample.lzh)

初期設定(Perl Editorから貼りつけたものです)を入力します。このスクリプトでは、一つの処理しか行ないません(エラー処理を除く)ので、サブルーチンはありません。

エラー処理に付いては次回説明します。

open (IN,"$data_file") || &error('オープンエラー','指定された書込みファイルが開けません。');
@LINES = <IN>;
close (IN);

で、data.datを呼び出し、内容を配列@LINESへセットしています。配列名はお好きな名前に変更してもかまいません。

書き込みデータの容量が大きくなると、読み込みに時間がかかり、かつ、メモリーも消費します。(配列はメモリーに保存されるので、当然といえば当然ですね)

掲示板がページ処理 (1ページに表示する件数を指定し、それ以上の発言がある場合、次へボタンやリンクを表示させる処理のこと) を行なっているのは、見た目の問題だけではなく、大量のメモリーを消費することによる弊害を回避するためなのです。

CGIスクリプトは、10人がアクセスすれば10個起動します。100件の書き込みデータを10人が読みこめば、実質1000件のデータをメモリに保存することになります。大量のデータを配列にセットしてしまうと、サーバーの処理が遅くなりますので、できるだけ少ないメモリーで動作するように配慮する必要があるのです。


これでデータが読みこまれました。次は、読み込んだデータを使ってテーブルを生成します。

print "Content-type: text/html\n\n";

これは、CGIスクリプト上で、HTMLタグを出力させるための命令です。このとおり覚えてしまいましょう。

中略・・・

foreach ( @LINES ) {
($name,$email,$rem) = split (/\,/,$_);
print "<tr><td>$name</td><td><a href=mailto:$email>$email</a></td><td>$rem</td></tr>\n";
}

以下略

上のソースは、foreach 関数を使って、data.datから読み出した内容を一行一行書き出して、テーブルの行を生成しています。

foreach ( @LINES ) {


}

foreach 取り出したデータ ( データをセットしたリスト ) {

ここでは、「データをセットしたリスト」配列@LINESが入っています。

そして、配列「@LINES」のデータを一つずつ取りだし「{」と「}」の間に書かれている処理を行います。正確には、

foreach $_ ( @LINES ) {
($name,$email,$rem) = split (/\,/,$_);

なのですが、「$_」は省略しています。

($name,$email,$rem) = split (/\,/,$_);

ここでは、「split」関数を使って、一行のデータを「お名前」「email」「コメント」に分割しています。前回ユーザーのデータを書き込み時に、一つ一つの項目を「,半角カンマ」で区切りました。今度は、半角カンマでデータを分割しているのです。

(/\,/,$_);

の「\,」(,は半角カンマです)はperlでは特別な意味を持つため、このカンマは特別な意味を持たない単なる区切り文字ですよ、ということをperlに教えるために「\」を使ってエスケープしています。

「split」関数の公式は・・・

(分割されたデータ) = split (/区切り文字/,分割するデータ);

「分割されたデータ」を変数に代入します。
ここでは,「お名前が$name」、「emailが$email」、「コメントが$rem」に代入されます。それぞれの項目間を「,半角カンマ」 で区切ります。

「区切り文字」はなんでもかまいませんが、半角カンマのようにperlで特別な意味を持つ記号を使った場合は「\」でエスケープします。

「分割するデータ」はforeach関数で取り出したデータですから、ここでは「$_」を指定しています。

もし、

foreach $data ( @LINES ) {

としたなら、

($name,$email,$rem) = split (/\,/,$data);

とします。

print "<tr><td>$name</td><td><a href=mailto:$email>$email</a></td><td>$rem</td></tr>\n";

次に、分割したデータを使ってHTMLタグを生成します。

最後に「}」でforeach関数を終了させます。最後の「}」を忘れると、サーバーエラーを起こします。必ず閉じるように。

foreach関数は、配列から一つ一つのデータを取り出して処理しますから、一つ目のデータをHTMLタグに書きこんだら、二つ目のデータを処理し・・・と、全てのデータなくなるまで同じ処理を繰り返します。

結果として、

<tr><td>pogi</td><td>pog@xxx.co.jp</td><td>こんにちは。よろしくお願いします。</td></tr>
<tr><td>pagi</td><td>pagi@xx.com</td><td>よい天気ですね。<br>今日はハイキングに行きました。</td></tr>
<tr><td>pegi</td><td>peg@xxx.net</td><td>仕事が忙しくて、せっかくの日曜日<br>なのに、休日出勤です。 </td></tr>

というタグを生成します。

改行されたデータは、初期設定で自動的に改行タグ(<br>)に変換されています。


最後に、

print "</table></body></html>\n";
exit;

で、テーブルを閉じ、HTMLを終了させます。
そして、exitでCGIスクリプトそのものを終了します。


*注意!

このサンプルスクリプトでは、データの区切り文字として半角カンマを使っています。
ということは、 ユーザーがコメント欄で半角カンマを使った場合、コメントが途切れてしまいます。

今日ハイキングに行きました。参加者は、POGI,PAGIの二人でした。

,は半角カンマです。このように入力されると・・・

pogi pogi@xxx.co.jp こんにちは。よろしくお願いします。
pagi pagi@xx.com よい天気ですね。
今日はハイキングに行きました。
pegi pegi@xxxx.net 仕事が忙しくて、せっかくの日曜日
なのに、休日出勤です。
pogi pogi@xxx.co.jp 今日ハイキングに行きました。参加者は、POGI

黄色く塗りつぶした部分のように、カンマの前で書き込みが途切れます。
「,半角カンマ」でデータを区切っているため、ユーザーが半角カンマを入力すると、perlは4つの項目があると判断し、3つ目の「$rem」には「今日ハイキングに行きました。参加者は、POGI」までしか代入されません。

4つ目の項目は無視されるので、画面上どこにも表示されず、途切れたように見えるのです。deta.datを確認してみましょう。きちんと全文保存されています。

このような不具合を回避するには、

  1. 半角カンマ以外の区切り文字を使う。

    でも、その区切り文字をユーザが使ったら同じことですね。 ちなみにKent-Webでは、<>を使っています。普通に使っている限り,「<」と「>」が並んで入力されることはありませんから・・・

  2. ユーザーに、半角カンマを使わないよう告知する。

    注意書きを読まない人やうっかり使ってしまう人もいるかもしれません。また、掲示板の目的上半角カンマが必須のこともありますね。

  3. 半角カンマを別の文字列に置きかえる。

    これが最適かと思います。

    エラー処理を追加する方法もありますが、せっかく書きこんだのにはじかれて、あげくフォームの再読みこみを強制された日には、「や〜〜めた」なんてことになりかねません。


特定の文字を別の文字に置き換えるには「正規表現」を使います。
正規表現に付いては別途説明します。


Web寺子屋 OGIPOGI E-mail:info@web-terakoya.net
Copyright© 2000-2001 OGIPOGI All Rights Reserved.