フォームからの入力を受け取る処理の詳細解説

フォームからの入力を受け取る処理の詳細解説

最後に、フォームからの入力を受け取る処理の詳細な解説をしておきます。ここまで読み進めてきた方ならば理解できると思います。

フォームからの入力を受け取る処理は以下になります。

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;

  &jcode::convert(*value, 'sjis');

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

まず1行目が

if ($ENV{'REQUEST_METHOD'} eq 'POST') {

となっていますが、これはフォームボタンを押してCGIを呼び出したか、もしくはリンクをクリックしてCGIを呼び出したかを判断するものです。

$ENV{'REQUEST_METHOD'} という環境変数にはフォームボタンを押してCGIを呼び出した場合に POST という値が格納されます。リンクをクリックしてCGIを呼び出した場合は GET が格納されます。それぞれの場合で値の受け取り方が異なるので、処理を振り分けています。POSTとGETについては、POSTとGETの違いもご覧ください。

read(STDIN, $alldata, $ENV{'CONTENT_LENGTH'});

これはフォームボタンを押した場合に値を受け取る処理です。read はデータを読み込むための関数です。STDIN は標準入力を表します。とりあえず、フォームからの入力内容がここに格納されていると思っておいてください。$ENV{'CONTENT_LENGTH'} には、受信データの長さが格納されています。

上の処理で STDIN から $alldata$ENV{'CONTENT_LENGTH'} の長さだけ読み込む事ができます。

$alldata = $ENV{'QUERY_STRING'};

これはリンクをクリックしたときに値を受け取る処理です。$ENV{'QUERY_STRING'} には、CGIが受け取った内容が格納されています。

これで、受け取ったないようが $alldata に格納されました。これらの処理で格納されたデータは以下のような内容になります。

handle=%8A%C7%97%9D%8E%D2&mail=abc@abc.com&message=%83e%83X%83g%81B

これは、以下の内容を送信した際のデータです。

name value
handle 管理者
mail abc@abc.com
message テスト。

送信されたnameと値が = で連結され、さらにすべての値が & で連結されています。さらにデーターに日本語が含まれる場合、URLエンコードと呼ばれる手法で半角英数字のみに変換されます。これを解析するのが以下に続く処理です。

foreach $data (split(/&/, $alldata)) {

この部分で、まずはデータ全体を & で分割しています。分割したデータは $data に格納され、順に処理されていきます。具体的には以下のようなデータです。

&で分割されたデータ
handle=%8A%C7%97%9D%8E%D2
mail=abc@abc.com
message=%83e%83X%83g%81B
($key, $value) = split(/=/, $data);

この部分で、$data の内容をさらに = で分割します。分割された各値は $key$value に格納します。

さらに=で分割されたデータ
handle
%8A%C7%97%9D%8E%D2
$value =~ s/\+/ /g;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg;
$value =~ s/\t//g;

この部分でURLエンコードされた文字列を元に戻します。正規表現を使用して文字列を日本語に戻します。

&jcode::convert(*value, 'sjis');

この部分で、受け取った文字列の文字コードをShift-JISに統一します。

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

この部分で、各データを連想配列に代入します。最終的に、連想配列の内容は以下のようになります。

連想配列
$in{'handle'} 管理者
$in{'mail'} abc@abc.com
$in{'message'} テスト。