|
サンプル(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を確認してみましょう。きちんと全文保存されています。
このような不具合を回避するには、
- 半角カンマ以外の区切り文字を使う。
でも、その区切り文字をユーザが使ったら同じことですね。 ちなみにKent-Webでは、<>を使っています。普通に使っている限り,「<」と「>」が並んで入力されることはありませんから・・・
- ユーザーに、半角カンマを使わないよう告知する。
注意書きを読まない人やうっかり使ってしまう人もいるかもしれません。また、掲示板の目的上半角カンマが必須のこともありますね。
- 半角カンマを別の文字列に置きかえる。
これが最適かと思います。
エラー処理を追加する方法もありますが、せっかく書きこんだのにはじかれて、あげくフォームの再読みこみを強制された日には、「や〜〜めた」なんてことになりかねません。
特定の文字を別の文字に置き換えるには「正規表現」を使います。
正規表現に付いては別途説明します。
|