6.二重送信チェック

参照 URL http://horiuchi.akira.ne.jp/cgi/giho-06.html
■概要  生徒会選挙や1人1回と決められているアンケート調査などでの「二重送信チェック」を行ってみます。 同一のパソコンからの二重送信をチェックすることもできますが、それでは1人1票とならないのでここ では「番号」と「パスワード」によるチェックを行ってみます。    まず、3年1組、2組の番号とパスワードの表 "id-pass-3.txt" を次のプログラムでつくります。  (20033101, efg3101), (20033102, efg3102), ・・・, (20033140, efg3140) / 40 件  (20033201, fgh3201), (20033202, fgh3202), ・・・, (20033240, fgh3240) / 40 件
# pass_3.pl

open F, ">id-pass-3.txt";

$a = 20033100, $b = "abc3100";
for (1..40)
  {++$a, ++$b; print F "$a,$b,"}

$a = 20033200, $b = "bcd3200";
for (1..40)
  {++$a, ++$b; print F "$a,$b,"}
 この登録番号者に対して、卒業旅行のアンケートを1人1回の制限をつけて行います。ここでは、リアルタイム に結果を反映させていますが、投票締め切り後に結果を HTML 上に発表するのも1つの方法です。また、更にここ では動作確認のために未投票者番号を表示させていますが、実際は管理者用のパスワードを設けて管理者のみが見 れるようにします。 <手順・流れ> 1.3年のパスワード表 "id-pass-3.txt" 及び、投票済みの生徒番号を書き込むファイル "giho-06-sumi.txt"  、投票内容の結果を書き込むファイル "giho-06-kekka.txt" をサーバーに転送します。書き込みファイルは  何れも空のファイルで構いませんが、投票内容のファイルは初期値として「0,0,0,0,0,0」を与えておくと、  "0" が表示されるので確認が行えます。 * 書き込み用ファイルには「書き込み」権限が必要です。  2.CGI 側では入力された番号が投票済み番号ファイル "giho-06-sumi.txt" にあれば、前の結果のみを表示して、  なければ新規投票として、結果書き込みファイル "giho-06-kekka.txt" に追加します。 3.投票済み者リストはソートして番号順に表示します。これはテーブル・タグを用い、1行に 10 人が表示される  ようにしてあります。 ■データファイルの変化
giho-06-kekka.txtgiho-06-sumi.txt
0,0,0,0,0,0
0,1,0,0,0,0
0,1,0,1,0,0
1,1,0,1,0,0
  ・
  ・
  ・
10,6,4,2,1,3
10,7,4,2,1,3
 
20033105,
20033105,20033237
20033105,20033113,20033237
 ・
 ・
 ・
20033101,20033105,・・・・・・・・,20033240
20033101,20033102,20033105,・・・・・・・・,20033240
入力フォーム画面 giho-06.html
<HTML>
<HEAD>
<TITLE>Giho 06</TITLE>
</HEAD>
<BODY BGCOLOR="#7ffffe">
<FORM ACTION="giho-06.cgi" METHOD="POST">
<PRE>

<H2> 卒業旅行アンケート / 1人1回</H2>
<HR>
 学生番号  : <INPUT SIZE="16" MAXLENGTH="16" NAME="bango">

 パスワード: <INPUT TYPE="password" SIZE="16" MAXLENGTH="16" NAME="pass">

<HR>

 行きたい国
 <INPUT TYPE="radio" NAME="travel" VALUE="0" CHECKED>イタリア <INPUT TYPE="radio" NAME=
"travel" VALUE="1">フランス <INPUT TYPE="radio" NAME="travel" VALUE="2">スペイン <INPUT TYPE=
"radio" NAME="travel" VALUE="3">イギリス <INPUT TYPE="radio" NAME="travel" VALUE=
"4">ドイツ <INPUT TYPE="radio" NAME="travel" VALUE="5">スイス

<HR>
 <INPUT TYPE="submit" VALUE="投票">

 (生徒番号, パスワード) = 
 (20033101, efg3101), (20033102, efg3102), ・・・, (20033140, efg3140) / 40 件
 (20033201, fgh3201), (20033202, fgh3202), ・・・, (20033240, fgh3240) / 40 件
</PRE>
</FORM>
</BODY>
</HTML>
CGI 画面 giho-06.cgi
#!/usr/local/bin/perl

require 'cgi-lib.pl';
&ReadParse(\%moji);

# エラー処理/外部サブルーチンの呼び出し
 $hyo = 'id-pass-3.txt';
 $url = 'giho-06.html';
 require 'pass_err.pl';
 &pass_err($hyo, $moji{bango}, $moji{pass}, $url);

# 投票結果の読み込み
  open K, '+<giho-06-kekka.txt';
  @a = split /,/,<K>;

# 投票済み者の読み込み
  open F, '+<giho-06-sumi.txt';
  @sumi = split /,/,<F>;
  $kazu = @sumi;
  $" = ", ";

  # 該当有り(投票済み)
    if (map /$moji{bango}/, @sumi)
      {$message = '* 投票済み / 投票結果は反映されません'}

  # 該当無し(未投票)
    else {

    # 番号を投票済み者配列に追加
      push @sumi, $moji{bango};

    # 投票数・選択項目のカウント値を +1
      ++$kazu;
      ++$a[$moji{travel}];

      $message = '新規投票 / 投票結果を反映'}

# 投票済み者をソート、保存、クローズ
  @sumi = sort @sumi;
  $temp = join ",", @sumi;
  seek F,0,0;
  print F "$temp";
  close F;

# 投票結果の保存とクローズ
  $temp = join ",", @a;
  seek K,0,0;
  print K "$temp";
  close K;

# 本文
print &PrintHeader;
print <<EOH;
<HTML>
<HEAD>
<TITLE>Giho 06</TITLE>
</HEAD>
<BODY BGCOLOR="#7ffffe">
<PRE>

<H3> $message</H3>
<HR WIDTH="622" ALIGN="left">

  イタリア <FONT COLOR="#0000ff">$a[0]</FONT>, フランス <FONT COLOR=
"#0000ff">$a[1]</FONT>, スペイン <FONT COLOR="#0000ff">$a[2]</FONT>, イギリス <FONT COLOR=
"#0000ff">$a[3]</FONT>, ドイツ <FONT COLOR="#0000ff">$a[4]</FONT>, スイス <FONT COLOR=
"#0000ff">$a[5]</FONT>

<HR WIDTH="622" ALIGN="left">

投票者 $kazu 名

<TABLE WIDTH="640" STYLE="font-size:1.0em">
<TR><TD>@sumi</TD></TR>
</TABLE>
</PRE>
EOH
print &HtmlBot;