フォームからの入力を受け取る

フォームからの入力を受け取る

フォームからの入力を受け取る

掲示板などで使用されるフォームからデータを受け取る方法です。フォームとは、以下のようなものです。

サンプルフォーム
お名前
性別
男性 / 女性
職業
メッセージ
  • 送信前にプレビューを表示

フォームから値を受け取るためのプログラムは以下のようになります。少々難しいので、完全に理解できなくても大丈夫です。とりあえず、決まり文句だと思っておいてください。(詳しい内容はフォームからの入力を受け取る処理の詳細解説をご覧ください。)

if ($ENV{'REQUEST_METHOD'} eq 'POST') {
  read(STDIN, $alldata, $ENV{'CONTENT_LENGTH'});
} else {
  $alldata = $ENV{'QUERY_STRING'};
}
foreach $data (split(/&/, $alldata)) {
  ($key, $value) = split(/=/, $data);

  $value =~ s/\+/ /g;
  $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg;
  $value =~ s/\t//g;

  $in{"$key"} = $value;
}

この処理を通過すると、フォームから送信された各内容が %in(連想配列) に代入されます。その後

$in{'フォームで指定したnameの値'}

と記述すると、実際に入力された値を参照することができます。

フォームからの入力内容を表示するプログラム

実際にフォームからデータを送信し、CGIで受け取るプログラムを作成してみます。

まず form.html を作成し、以下の内容を記述してください。ブラウザにメッセージの入力欄と送信ボタンを表示するHTMLファイルです。

<html>
<head>
<title>フォームサンプル</title>
</head>
<body>
<form method="post" action="form.cgi">
  <p>
    メッセージ<br>
    <input type="text" name="message" size="20" value="">
  </p>
  <p><input type="submit" value="送信する"></p>
</form>
</body>
</html>

次に form.cgi を作成し、以下の内容を記述してください。form.html から送信されたデータを受け取り、ブラウザに表示するCGIです。

#!/usr/local/bin/perl

#送信されたデータを受け取る
if ($ENV{'REQUEST_METHOD'} eq 'POST') {
  read(STDIN, $alldata, $ENV{'CONTENT_LENGTH'});
} else {
  $alldata = $ENV{'QUERY_STRING'};
}
foreach $data (split(/&/, $alldata)) {
  ($key, $value) = split(/=/, $data);

  $value =~ s/\+/ /g;
  $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg;
  $value =~ s/\t//g;

  $in{"$key"} = $value;
}

print "Content-Type: text/html; charset=Shift_JIS\n\n";
print "<html>\n";
print "<head><title>フォームサンプル</title></head>\n";
print "<body>\n";

#受け取ったデータを表示する
print "<p>入力されたメッセージは$in{'message'}です。</p>\n";

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

exit;

これで form.html を表示し、メッセージを入力して送信ボタンを押すと form.cgi に入力した内容が表示されます。なお、form.html には http:// 経由でアクセスしてください。ダブルクリックでHTMLファイルを開いてから操作しても、正しく動作しません。

フォームからの複数の入力内容を表示するプログラム

前回は入力項目が1つでしたが、今度は入力項目を2つにしてみます。…と言っても、1つのときと同じ要領で作成することができます。

まず form.html を作成し、以下の内容を記述してください。ブラウザにハンドルネームの入力欄とメッセージの入力欄と送信ボタンを表示するHTMLファイルです。

<html>
<head>
<title>フォームサンプル</title>
</head>
<body>
<form method="post" action="form.cgi">
  <p>
    ハンドルネーム<br>
    <input type="text" name="handle" size="20" value=""><br>
    メッセージ<br>
    <input type="text" name="message" size="20" value="">
  </p>
  <p><input type="submit" value="送信する"></p>
</form>
</body>
</html>

次に form.cgi を作成し、以下の内容を記述してください。form.html から送信されたデータを受け取り、ブラウザに表示するCGIです。

#!/usr/local/bin/perl

#送信されたデータを受け取る
if ($ENV{'REQUEST_METHOD'} eq 'POST') {
  read(STDIN, $alldata, $ENV{'CONTENT_LENGTH'});
} else {
  $alldata = $ENV{'QUERY_STRING'};
}
foreach $data (split(/&/, $alldata)) {
  ($key, $value) = split(/=/, $data);

  $value =~ s/\+/ /g;
  $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg;
  $value =~ s/\t//g;

  $in{"$key"} = $value;
}

print "Content-Type: text/html; charset=Shift_JIS\n\n";
print "<html>\n";
print "<head><title>フォームサンプル</title></head>\n";
print "<body>\n";

#受け取ったデータを表示する
print "<p>入力されたハンドルネームは$in{'handle'}です。</p>\n";
print "<p>入力されたメッセージは$in{'message'}です。</p>\n";

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

exit;

print "<p>入力されたハンドルネームは$in{'handle'}です。</p>\n"; の1行のみ追加しています。これで form.html を表示し、メッセージを入力して送信ボタンを押すと form.cgi に入力した内容が表示されます。

フォームからの入力内容をファイルに記録するプログラム

前回は入力された内容をブラウザに表示するだけでしたが、今度は入力された内容を順にファイルへ記録していくように変更します。保存するファイルは、今回は form.txt とします。

form.html の内容は前回と同じです。form.cgi の内容は、以下のように変更します。

#!/usr/local/bin/perl

#送信されたデータを受け取る
if ($ENV{'REQUEST_METHOD'} eq 'POST') {
  read(STDIN, $alldata, $ENV{'CONTENT_LENGTH'});
} else {
  $alldata = $ENV{'QUERY_STRING'};
}
foreach $data (split(/&/, $alldata)) {
  ($key, $value) = split(/=/, $data);

  $value =~ s/\+/ /g;
  $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg;
  $value =~ s/\t//g;

  $in{"$key"} = $value;
}

print "Content-Type: text/html; charset=Shift_JIS\n\n";
print "<html>\n";
print "<head><title>フォームサンプル</title></head>\n";
print "<body>\n";

#受け取ったデータをファイルに書き込む
if (open(FH, "form.txt")) {
  @file = <FH>;
  close(FH);

  unshift(@file, "$in{'handle'}\t$in{'message'}\n");

  if (open(FH, ">form.txt")) {
    print FH @file;
    close(FH);
  } else {
    print "<p>ファイルに書き込めません。</p>";
  }
} else {
  print "<p>ファイルを読み込めません。</p>";
}

#受け取ったデータを表示する
print "<p>入力されたハンドルネームは$in{'handle'}です。</p>\n";
print "<p>入力されたメッセージは$in{'message'}です。</p>\n";

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

exit;

これで form.html を表示し、メッセージを入力して送信ボタンを押すと form.cgi に入力した内容が表示され、なおかつ form.txt 入力内容が記録されていきます。

unshift は配列の先頭にデータを追加する関数です。@file にはファイルの内容が格納されているので、ファイルの先頭行に新しいデータが追加されることになります。

なお、入力内容は1件が1行となり、ハンドルネームとメッセージはタブで区切られて保存されます。区切り文字によく使用されるのは、タブの他に ,<> があります。