CGI WEB [ CGI配布 CGI解説 ホームページ作成支援 ]
ホーム|CGI配布|CGIランキング|CGIサポート|CGI解説|ワンタッチボード|ワンタッチメール|クイズ|自宅サーバ|サーバガイド|登録太郎|CGI WEBサーチ|CGI WEB窓口


back
デコード処理





<form method="post" action="./sample.cgi">
 <input type="text" name="title" />
 <input type="text" name="comment" />
 <input type="submit" value="送信" />
</form>

例えば上記のフォームから入力されたデータをCGIプログラム(sample.cgi)に送信したとします。 入力されたデータは以下の形式でsample.cgiに送信されます。

title=データ1&comment=データ2

その際、送信されたデータは以下のように変換(URLエンコード)される事になっています。

・半角英数字     ⇒ 無変換
・* - @ . _      ⇒ 無変換
・半角スペース    ⇒ +(半角プラス)
・その他の文字と和文 ⇒ %に続く16進2桁の文字コード

CGIプログラムではこれらの送信データを受け取り、デコード処理を行って元の入力されたデータに戻す必要があります。

■デコード処理サブルーチン例1

require './jcode.pl';
sub decode {
if ($ENV{'REQUEST_METHOD'} eq 'POST') {
  read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
} elsif ($ENV{'REQUEST_METHOD'} eq 'GET') {
  $buffer = $ENV{'QUERY_STRING'};
}
@pair = split(/&/, $buffer);
foreach (@pair) {
  ($name, $val) = split(/=/, $_);
  $val =~ tr/+/ /;
  $val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
  &jcode'convert(*val, 'sjis');
  $buf{$name} = $val;
}
}

入力データをCGIプログラムで受け取る場合、そのデータが「POST」(標準入力)または「GET」(クエリ入力)のどちらで送られたのかを確認してデータを取り出します。 送信形式(メソッド)は環境変数$ENV{'REQUEST_METHOD'}に格納される事になっています。 ちなみに冒頭のフォームでは<form method="post">と指定されていますので「POST」で送られる事になります。 「POST」の場合はread()関数で$bufferにデータを読み込みます。

read(ファイルハンドル, 読み込み先, 読み込む長さ, オフセット);

ファイルハンドルをSTDIN(標準入力)と指定するとPOSTメソッドで送られたデータを読み込みます。 データ長(読み込む長さ)は環境変数$ENV{'CONTENT_LENGTH'}に格納される事になっています。 オフセット省略時は先頭から読み込むので、この場合は省略する事になります。 「GET」の場合は環境変数$ENV{'QUERY_STRING'}にデータが格納されるので$bufferにそのまま取り出しています。

和文コードの取り扱いについてですが、まず

require './jcode.pl';

として和文コード変換ライブラリの取り込みを行います。次に

&jcode'convert(*val, 'sjis');

として$valに格納した入力データ内の和文コードをシフトJISコードへ変換します。 和文コードは他に「jis」又は「euc」が指定出来ます。 jcode.plの最新版はこちらで入手する事が出来ます。

$nameについて変換を行っていないのはCGIプログラム開発者がURLエンコードされない名前を付けるように気を付けていれば済む事なので処理の高速化も含めて変換の処理を省くようにしています。 最後に変換が終わったデータをハッシュ(%buf)に格納します。 これでフォームから送信されたデータは$buf{'title'}と$buf{'comment'}で参照する事が出来るようになりました。

■デコード処理サブルーチン例2(cgi-lib.pl使用時)

require './jcode.pl';
require './cgi-lib.pl';
sub decode {
&ReadParse;
while (($name, $val) = each %in) {
  if ($name ne 'upfile') { &jcode'convert(*val, 'sjis'); }
  $buf{$name} = $val;
}
}

&ReadParse;とするとcgi-lib.plによってフォームから送信されたデータのパラメータ名(フォーム指定名)と値(入力データ)がセットになってハッシュ(%in)に格納されます。 この際、デコード処理も同時に行われていますので便利です。 格納されたデータのパラメータ名と値を1組ずつ取り出し、アップロードファイルのデータ以外は和文コード変換処理を行います。 変換が終わったらハッシュ(%buf)に格納します。

■補足

<form action="./sample.cgi" method="post" enctype="multipart/form-data">
 <input type="file" name="upfile" />
 <input type="submit" value="送信" />
</form>

上記のように「enctype="multipart/form-data"」と指定したフォームでは<input type="file">と指定するとファイルのアップロードが出来るようになりますが「デコード処理サブルーチン例1」のような普通のデコード処理ではアップロードファイルのデータの受け取りが出来ません。 この時に威力を発揮するのがcgi-lib.plの&ReadParse;です。 これにより%inのパラメータ名に対応してアップロードされたファイルのデータそのものを受け取る事が出来る様になります。 この場合は「name="upfile"」としていますので$in{'upfile'}にアップロードされたファイルのデータが入る事になります。

このように、ファイルをアップロードするCGIプログラムを作成する時はcgi-lib.plを利用した「デコード処理サブルーチン例2」のようなデコード処理を行う事になります。 受け取ったファイルのデータを実際にアップロードする方法については以降の項目で解説します。

また、大容量ファイルのアップロードが必要な場合はCGI.pmモジュールを利用する方法が一般的です。 こちらも以降の項目で解説しています。



□更新履歴
 2007.04.22 全体的に内容を見直し
 2006.11.06 CGI.pmの紹介文を追加




CGI WEB