10/26日 3限

情報アプリケーション1
2006年 10月 26日 第四回資料
担当 重定 如彦
目次
•
•
•
•
•
•
配列変数の中身の表示
フォームのデータの中身の解析
連想配列変数
日本語の処理
掲示板の仕組み
簡易掲示板
ファイルのロック
掲示板のように同時に複数の人がデータを書き込む可能
性のあるCGIは、ファイルの中身を書き込む前に、同時に複
数のCGIが同じファイルを編集しないようにする必要がある。
これをファイルのロックと呼ぶ。ロックされているファイルを
オープンしようとすると、ロックが解除されるまで待たされる。
Perlでは以下の方法でファイルをロックできる。
• ファイルのロック
flock(ファイルハンドル,2);
• ロックの解除
flock(ファイルハンドル,8);
CGIの変更
keijiban.cgi に以下の赤字の部分を追加すること
open OUT, ">>kakikomi.txt";
flock(OUT, 2);
print OUT "$query{'name'}:$query{'kakikomi'}\n";
close OUT;
flock(OUT, 8);
なお、ファイルのロックは、ファイルを読み込む場合は行う必要はない
掲示板の改良1
keijiban.cgiでは古い順に書き込まれた内容が表示されてい
たが、これは新しく書き込まれたデータをファイルの最後に
追加しているからである。
新しい順に内容を表示するには、以下の手順で表示するよう
にプログラムを変更すれば良い。
• ファイルからすべての書き込み内容を配列変数に読み込む
• 配列変数の最後の要素から順番に表示する
perlではファイルからデータを読み込む際に、
@配列変数名 = <ファイルハンドル>;
と記述することでファイルの各行を配列変数に代入することができる。
掲示板の改良2
配列変数の要素数を調べるには
$#配列変数名
と記述すれば良い
keijiban.cgiを以下のように書き換えよ。
open IN, "<kakikomi.txt";
@linedata = <IN>;
for ($i = $#linedata ; $i >= 0 ; $i--) {
print "$linedata[$i]<BR>\n";
}
close IN;
掲示板の改良3
次はもう少し掲示板らしく改良してみることにする
改良点
• 書き込みの部分をTEXTAREAを使って複数行書き
込めるようにする(INPUTタグではない点に注意)
• メールも書き込めるようにする
• CGIのほうも、それぞれ表示できるようにし、
メールの部分はクリックするとメールソフトが立ち上
がるようにする。
掲示板の改良4
keijiban.htmlの以下の赤の部分を書き換えよ
<FORM method="POST" action="keijiban.cgi">
お名前<INPUT TYPE="text" name="name"><BR>
メール<INPUT TYPE="text" name="mail"><BR>
<TEXTAREA rows="3" cols="50" name="kakikomi"></TEXTAREA><BR>
<INPUT TYPE="submit" value="送信">
<INPUT TYPE="reset">
</FORM>
掲示板の改良5
keijiban.cgiのファイルの書き込みの部分を以下のように変更せよ
open OUT, ">>kakikomi.txt";
flock(OUT,2);
$name = &henkan($query{'name'});
$mail = &henkan($query{'mail'});
$kakikomi = &henkan($query{'kakikomi'});
$kakikomi =~ s/\r\n/<BR>/g;
print OUT "$query{'name'}:$query{'mail'}:$query{'kakikomi'}\n";
close OUT;
flock(OUT,8);
掲示板の改良6
keijiban.cgiのファイルの読み込みと表示の部分を以下のように変更せよ
open IN, "<kakikomi.txt";
@linedata = <IN>;
for ($i = $#linedata ; $i >= 0 ; $i--) {
($name, $mail, $kakikomi) = split(/:/, $linedata[$i]);
print <<KAKIKOMI_DATA;
名前:$name<BR>
メール:<A HREF="mailto:$mail">$mail</A><BR>
$kakikomi<BR>
<HR>
KAKIKOMI_DATA
}
close IN;
掲示板の改良7
プログラムの最後に以下の関数を記述すること
sub henkan {
$_[0] =~ s/:/:/g;
$_[0] =~ s/&/&amp;/g;
$_[0] =~ s/"/&quot;/g;
$_[0] =~ s/</&lt;/g;
$_[0] =~ s/>/&gt;/g;
return $_[0];
}
関数の記述
Perlでは
sub 関数名 {
プログラムを書く
}
と書くことで自分で関数を作ることができる。
作成した関数を呼び出すにはプログラム内で
関数名(引数)
または
&関数名(引数)
と書けばよい。なお、後者の書き方は、関数呼び出しであることを
明確にするための書き方である
引数と返り値
関数に渡すデータのことを引数と呼び、引数は
$_という名前の配列変数に入っている
また、関数の中で計算した結果を
return 計算結果の式;
と記述することで返すことができる。これを返り値と呼ぶ
$name = &henkan($query{'name'});
と記述すると
• henkanという関数の中のプログラムが実行される。
• $_[0]の中に$query{‘name’}が代入される。
• 関数の中で return 命令が実行された場合、returnの後ろに記述されて
いる式の計算結果が戻ってきて、$nameに代入される。
置換
perlでは
$変数名 =~ s/置換前の文字列/置換後の文字列/g;
と記述することで、指定した変数の中の文字を置換すること
ができる。なお、最後にgと書くことで変数の中に複数置換
したい文字がでてきた場合すべて置換される。
(書かなかった場合は最初のものだけ置換される)
例
$text の中身が “abcabc”の時に
$text =~ s/abc/def/g; を実行すると$textの中身は”defdef”になる
$text =~ s/abc/def/; を実行すると$textの中身は”defabc”になる
henkan関数の意味 1
このCGIでは名前、メール、書き込み内容を
1行で :(半角)で区切って保存している。
従って、名前などに:(半角)が使われると保存した
データの区切りがおかしくなってしまう。
そこでhenkan関数は : (半角)を : (全角)に
置換している
henkan関数の意味 2
HTMLでは < > “ & などの記号は特別な
意味をもつので、それらの文字を名前などに記述さ
れるとそれを表示した場合におかしなことになってし
まう。それらの文字をHTMLで表示する場合、実体参
照と呼ばれる特別な書き方をしなければならない。
henkan関数はこれらの記号を実体参照に置換する。
記号と実体参照の対応は以下の通り
< → &lt;
“ → &quot;
> → &gt;
& → &amp;
テキストエリアの改行の置換
テキストエリアは、テキストボックスと異なり改行することが
できるが、改行をそのままkakikomi.txtに保存するとおかしな
ことになってしまう。
テキストエリアの改行は \r\n の2文字でCGIに送られるの
で、それをHTMLの改行を表す<BR>に置換する。
$kakikomi =~ s/\r\n/<BR>/g;
課題
• 次スライドのいずれかの動作を行うCGIを法政大学の自分の
ウェブページとして作成すること
• CGIのファイル名は kadai.cgi とすること
• 完成後は、動作の確認を行ったうえで、メールで
私のアドレス [email protected] に
件名は「情報アプリケーション課題」、本文には下記のCGIのアドレスを
本文に書き、作成したファイルをすべて添付ファイルで送ること
アドレス: http://www.edu.i.hosei.ac.jp/~ユーザID/kadai.cgi
• 他人の作ったもののコピーは不可とする。他人と相談して
作成するのはかまわないが必ず自分独自のものをつくること
• 締め切りは12月14日です
課題のCGI1
• クイズCGI
クイズを5問(問題内容は自分で考えること)
表示し、答えを選んでボタンをクリックすると、
何問正解したかを表示するCGIを作成すること
また、何か工夫できる点があれば工夫すること
ヒント:何問正解したかを表す変数を用意し、
正解が確認されるごとにその変数の中身を
1つ増やせば正解の数を数えることができる
課題のCGI2
• 掲示板CGI
 授業で作った掲示板に自分が欲しいと思った機能を付け加えて拡張
せよ
 書き込まれた内容の表示のレイアウトをTABLEタグなどを使って一
般の掲示板らしくなるように工夫せよ
• その他のCGI
クイズ、掲示板以外でチャレンジしたいCGIがあれば、
相談の上それを作り課題としても良い。
来週の授業はまるまる課題の時間に当てる予定です。
何か質問があればその時にして下さい。