概要
ホームページを作成する人は、CGIの知識も持たなければなりません。
勿論、CGIを全く使用しなくてもホームページを作成する事は出来ます。
官公庁のサイトでは、故意にCGIを使用しないようにしている場合もあります。
CGIを使用しなくても、決して見劣りがするようなサイトにはなりません。
しかし、私から見るとCGI(JavaScriptも含めて)を使用していないサイトは、何かが不足している感じがします。
料理で言えば、おいしいのだけれども何かが足りない味付けだと言う感じでしょうか。
画面をチカチカさせたり、キラキラさせたりするのがCGIだと思っている方も多いでしょうが、本当のCGIの使い方はさりげない中に力を発揮している場合だと思います。
縁の下の力持ち的な使い方が、CGIの最も適している使い方だと思っています。
ここでは、CGIを使った掲示板やメールフォームのような一般的な使い方と隠れた使い方について述べてみたいと思います。
CGIの提供サイト
PerlやPHPの文法を知っていても、いきなりプログラムを書ける人は居ないでしょう。
まずは、先駆者の方達が作成したプログラムを見て、そこから学んでいくべきでしょう。
他の方が作成したプログラムからは、解説書には無かった新しい発見とプログラムを作成する楽しさを学んでいく事が出来ます。
文法を先に学ぶよりは、いきなり他人の作成したプログラムを見る事の方が、単調な文法を学ぶよりも興味を失わないかも知れません。
どちらも欠かす事は出来ませんから、両方を交互に見て学んでいく事が自分でプログラムを作成する近道になると思います。
まずは、日本でフリーのCGIプログラムを提供しているサイトを御紹介します
サイト名 | 内容 |
---|---|
KENT WEB | 掲示板、カウンター、解析、リンク集、チャット、買い物カート |
CGI-design | 掲示板、日記、カウンター、解析、リンク集、メール、アルバム、その他多数 |
WonderLink | 高性能検索エンジン、リンク集、メール、ゲーム |
CJ-Club | 高性能アクセスランキング、掲示板、カウンター、リンク集、投票 |
CGIダウンロード | 掲示板、カウンター、日記、リンク集、チャット |
Perl CGI's | 掲示板、カウンター、日記、リンク集、メール、買い物カート、その他多数 |
AppsPage | 掲示板、カウンター、日記、メール、チャット |
CGI-PLANT | 掲示板、日記、リンク集、チャット、アップローダー |
レッツPHP! | 掲示板、カウンター、日記、情報収集、チャット、更新記録、アップローダー |
Web Liberty | 掲示板、ブログ・日記、データ収集、メール、ギャラリー、買い物カート |
MyTools.NET | 掲示板、カウンター、リンク集、メール、チャット、投票、辞書、クイズ |
CGI RESCUE | 掲示板、カウンター、ブログ・日記、解析、チャット、情報収集、買い物カート |
技林 | 掲示板、カウンター、解析、メール |
GROOWEB | 掲示板、カウンター、メール、チャット、検索エンジン |
CMF | 掲示板、カウンター、日記、解析、リンク集、メール |
Script Market | 掲示板、カウンター、解析、メール、チャット、検索 |
私が使用しているリンクサイトの内容をほぼ転記しただけですから、私の知らないサイトもありますし、場合によってはリンク切れになっている場合もあるかも知れません。(単なる転記ではなくて、徐々に自分のレイアウトや書き方に改めていきます。)
この中で、私が多く利用させていただいているのが KENT WEB さんのサイトです。
掲示板やメールフォーム、認証ページのソフトを使用しております。
どのCGIが人気なのか気になる方のために、CGIの検索サイトを以下に記載しておきます。
CGI-NOW
CGI-Search
記載内容が信頼できるのだろうかとかは、私は全く判りません。
CGIの設置方法
設置する前に ・・・・ |
1. ご自分のホームページスペースが自作CGI を許可しているかを確認する。 ホームページスペースによっては CGI を全く許可していない所や、提供されるもののみが動作許可されている場合があります。 許可されていない場合や、提供されるCGI のみ動作許可されている場合、残念ながら一般に配布されているCGIは動きません。 |
2. Perl のパスを確認する。 |
お使いのホームページスペースの解説サイトやマニュアルなどに記載されていると思いますが、 /usr/local/bin/perl や /usr/bin/perl のどちらを使用しなければいけないのか確認しましょう。 |
CGIの解説サイトでは、設置に関して必ずと言って良い程、上記のような注意書きがあります。
1番目の項目に関しては、プロバイダが無料で提供するホームページのスペースでは、プロバイダが提供するカウンターCGIなどを除いて、CGIを利用できないのが大部分だと思います。
2番目のPerl のパスについては、どちらで記入しても利用できるようになっているのが大部分ではないかと思いました。
理由は、その方が利便性が高い事と両方を使えるようにサーバーを設定するのが、簡単なためです。
試に、ヤフーの場合を確認して見る事にします。
#!/usr/local/bin/perl
print "Content-type:text/html\n\n";
print "<HTML><BODY><H1>Hello!</H1></BODY></HTML>\n";
exit;
上記の local の部分を削除したもの(#!/usr/bin/perl)と削除しないものの2通りで動作させてみます。
ヤフーでは、削除した#!/usr/bin/perlを記入するように指示しています。
最初に削除しないもの(#!/usr/local/bin/perl)で動作させてみます。
文字コードは、Shift_JISで改行コードはLFのみで記載しました。(文字コードは UTF-8 などでも当然動きます)
http://cgi.geocities.jp/yukke_no_kobeya/homepage/hello.cgi
次にヤフーの指定のlocalを削除したものです。
http://cgi.geocities.jp/yukke_no_kobeya/homepage/hello1.cgi
予想通り、どちらを記述しても動作するようです。
他のプロバイダでも同様だとは思いますが、指定されている通りにした方が良いのは確かでしょう。
CGI(perl)の文法
私はCGIのプログラムは多用している方だとは思いますが、CGIについて詳しい訳ではありません。
多くはフリーのプログラムを使用しておりますので、期待通りの動作をしない場合にはプログラムを眺めて修正する必要があります。
プログラムの文法が解らない場合には、解説サイトで調べばければなりません。
全くプログラムを理解出来なくても動作するソフトは多いですが、やはり最低限の知識は持つべきでしょう。
CGI(Perl)の優れた解説サイトはいくらでもあります。
検索して自分のレベルにあった解説サイトを見つけてください。
ここでは、主要なポイントだけ記載する事にします。
尚、内容は私のレベル(小学校4年生程度)で記載しておりますので、初心者(幼稚園レベル)の人は理解が難しいと思います。
変数
スカラー変数 |
$personal = '田中'; |
|
|
配列 |
@personal = ('田中', '山田', '渡辺'); |
|
|
ハッシュ (連想配列) |
$personal{'name'} = '田中'; $personal{'age'} = 38; $personal{'blood'} = 'A'; |
|
計算
$a1 = 3 + 5; $a2 = 93 - 23; $a3 = 10 * 5; $a4 = 12 / 4; $a5 = 10 % 8; |
# $a1 = 8 # $a2 = 70 # $a3 = 10 × 5 = 50 # $a4 = 12 ÷ 4 = 3 # $a5 = 2 ( % は10を8で割ったときの余りを返します。) |
$total1 = ( 2 + 3 ) * ( 7 + 1 ); $total2 = 2 + 3 * 7 + 1; |
# $total1 = 40; となります # $total2 = 24; となります |
$b1 += 5; $b2 -= 23; $b3 *= 5; $b4 /= 4; $b5 %= 8; |
# $b1 = $b1 + 5 と同じ # $b2 = $b2 - 23 と同じ # $b3 = $b3 * 5 と同じ # $b4 = $b4 / 4 と同じ # $b5 = $b5 % 8 と同じ |
$c1 = $c2 = $c3 = $c4 = 3; 【インクリメント】 $d1 = ++$c1; $d2 = $c2++; 【デクリメント】 $d3 = --$c3; $d4 = $c4--; |
← 変数に初期値3をセットしておく
# $d1 = 4; $c1 = 4; となる # $d2 = 3; $c2 = 4; となる # $d3 = 2; $c3 = 2; となる # $d4 = 3; $c4 = 2; となる |
print 2 ** 10; ← 2の10乗の解(1024) が表示されます。
演算子 | 意味 |
---|---|
$a == $b | $a と $b が等しい場合に真を返します。 |
$a != $b | $a と $b が等しくない場合に真を返します。 |
$a > $b | $a が $b より大きい数値の場合に真を返します。 |
$a < $b | $a が $b より小さい数値の場合に真を返します。 |
$a >= $b | $a が $b 以上の場合に真を返します。 |
$a <= $b | $a が $b 以下の場合に真を返します。 |
$a = int( 4 / 3 ); ← $a には 1 がセットされます。
文字列
$answer = 2 + 3;
print '2 + 3 = $answer です。'; ← 「2 + 3 = $answer です」 と表示される
print "2 + 3 = $answer です。"; ← 「2 + 3 = 5 です」 と表示される
print 'こんにちわ\n'; ← 「こんにちわ\n」 と表示されて、改行されません。
print "こんにちわ\n"; ← 「こんにちわ」 と表示されて、改行されます。
print "こんにちわ\n" . "さようなら" ; ← 「こんにちわ」 改行 「さようなら」 と表示さます。
$text1 = "こんにちわ\n";
$text2 = "さようなら";
print $text1 . $text2; ← 「こんにちわ」 改行 「さようなら」 と表示さます。
演算子 | 意味 |
---|---|
$a eq $b | $a と $b が等しい場合に真を返します。 |
$a ne $b | $a と $b が等しくない場合に真を返します。 |
$a gt $b | $a が $b より大きい数値の場合に真を返します。 |
$a lt $b | $a が $b より小さい数値の場合に真を返します。 |
$a ge $b | $a が $b より大きいか等しいの場合に真を返します。 |
$a le $b | $a が $b より小さいか等しいの場合に真を返します。 |
$charactor = 'abc';
$len = length $charactor; ← 3 が返される。
文字列の末尾からオフセット分戻った位置から参照を開始します。
参照する長さがセットされている場合は、開始位置から、長さの分だけ文字列を参照してその値を返します。
$text = "今日はよいお天気です。";
print substr( $text, 12 ); ← 「お天気です。」 と表示されます。
[書式]
split(/区切り文字/, 文字列, 回数)
文字列を区切り文字で分割して、分割された値は配列として返されます。
回数を指定すると、区切る回数を制限することが出来ます。
$cvs = "01,田中太郎,東京,17,A";
@data = split(/,/, $cvs);
print "氏名: $data[1]\n";
print "住所: $data[2]\n";
print "年齢: $data[3]\n";
print "血液型: $data[4]\n";
[書式] index 文字列, キーワード, (開始位置)
指定した文字列内からキーワードが見つかった場合にはその位置を数値で返します。
キーワードが見つからなかった場合には、-1 を返します。
(開始位置を指定するとその位置からキーワード検索を開始します。)
$text = "文字を検索してね!"; ← 検索対象の文字列をセットします
print index $text, "検索"; ← 6 と表示されます
uc ← すべて大文字に変換する
ucfirst ← 始めの1文字のみ大文字に変換する
lc ← すべて小文字に変換する
lcfirst ← 始めの1文字のみ小文字に変換する
$country = 'Japan'; ← 変数をセットする
$text1 = uc $country; ← JAPAN が代入される
$text2 = ucfirst $country; ← Japan が代入される
$text3 = lc $country; ← japan が代入される
$text4 = lcfirst; ← japan が代入される
HTMLソースのような改行を含む長い文章の場合には、print 関数での表示はとても大変です。
また、Perl のソース自体も分かりにくいものになってしまいます。
ヒアドキュメントを使うと、表示したい文章をそのまま記述できるためとても便利です。
【書式】
print <<終端文字; ← 直接表示する場合
・・・ ← この部分に表示したい文字列を記入
終端文字
$message = <<終端文字; ← 変数に代入する場合
・・・ ← この部分に変数に代入したい文字列を記入
終端文字
終端文字は半角英数字なら何でもよいのですが、大文字が比較的よく使われます。
【print 関数での表示】
print "Content-Type: text/html\n\n";
print "<html>\n";
print "<head>\n";
print "<body bgcolor=\"#ffffff\">\n";
print "TEST HTML\n";
print "</body>\n";
print "</html>\n";
print 関数での表示では、文字列をダブルクォーテーションで囲まなければならないほか、改行を 「\n」 で表示しなければなりません。 また、HTMLソース内でダブル-クォーテーションを使用している場合には、Perl で使用するものと区別するために、「\」 でエスケープする必要があります。
【ヒアドキュメントでの表示】
print "Content-Type: text/html\n\n";
print <<END_HTML;
<html>
<head>
<body bgcolor="#ffffff">
TEST HTML
</body>
</html>
END_HTML
ヒアドキュメントを使った場合には、HTMLソースをそのまま記述することが出来ます。
HTMLソース自体も閲覧性が高いため、記述が楽なだけではなく、HTMLソースの検証や変更等も簡単に行なえます。
また、下記のような方法を使うと、ヒアドキュメント内でもプログラムを使用することが出来ます。
print "Content-Type: text/html\n\n";
print <<END_HTML;
<html>
<head>
<body bgcolor="#ffffff">
$ { message() }
</body>
</html>
END_HTML
sub message {
print "TEST HTML\n";
}
時間の処理
現在時刻を取得する為には、time 関数を使います。
time 関数では1970年1月1日0:00からの経過秒数を取得できます。
また、これだけでは扱いづらいのですが、 localtime 関数を使うと年・月・日・曜日・・・など、項目ごとに時間のデータをリスト形式で取り出すことが出来ます。
取得されたリストデータは、下記のように別々の変数にセットすると扱いやすいでしょう。
$times = time();
($sec,$min,$hour,$mday,$month,$year,$wday,$stime) = localtime($times);
年のデータは、1900年からの経過年を返します(現在が2000年の場合は、100を返します)。
したがって、年のデータに1900をあらかじめ足しておく必要があります。
また、月のデータも同様には 0〜11の値を取得してくるため、あらかじめ1足しておく必要があります。
$year = $year + 1900; ← 年のデータに1900足す
$mon++; ← 月のデータに1足す
タイムゾーンを設定するとグリニッジ標準時からの時間のずれを修正できます。
タイムゾーンの設定は time 関数で時間を取得する前に設定してください。
$ENV{'TZ'} = "JST-9"; ← 標準時から -9 時間のずれ(日本の場合)
曜日は 0〜6までの数値で返されます。
このままでは分かりにくいため、下記のように表示したい曜日データを配列に入れておき、
取得された数値を曜日データの配列の添字として扱うことで、曜日を表示できます。
@weekly = ('Sun', 'Mon', 'Tue', 'Wed', 'Thr', 'Fri', 'Sut'); ← 表示したい曜日文字
print $weekly[$wday]; ← 曜日を表示
日時を 「2010/02/04 14:43」 などのように決まった書式で出力したい場合には、sprintf 関数を使います。
【書式】
sprintf( %4d, $year ); ← 4桁の数値のフォーマット(例:2012)
sprintf( %04d, $year ); ← 4桁に満たない場合は、足りない桁を0で埋める(例:0039)
サブルーチン
サブルーチンに値を受け渡したい場合は 「subroutin()」 の () 内に受け渡したい値をセットします。
受け渡す値のことを引数(ひきすう) と呼びます。
引数が複数ある場合には、「,(カンマ)」 区切りで引数を指定します。
● 引数が1個の場合
引数が1個の場合は、「$_ (標準変数)」 を使って受け取ります。
&message('こんにちは!'); ← サブルーチンmessage に 「こんにちは」 という文字列を渡す
sub message {
$msg = $_; ← 受け取った値を変数にセットする
print $msg; ← 値を表示する
● 引数が複数の場合
引数が複数の場合は、「@_ (特殊配列)」 を使って受け取ります。
&message('こんにちは!', 'さようなら'); ← サブルーチンmessage に文字列のリストを渡す
sub message {
@msg = @_; ← 受け取った値を配列にセットする
print @msg; ← 値を表示する
}
サブルーチンからの返り値は、何も指定しなければ、一番最後の行が評価されてその値がサブルーチンの返り値となります。
return 関数を使うと明示的にサブルーチンの返り値を指定することが出来ます。
下記のプログラムでは、引数として渡される2つの値の合計を返します。
【合計を求めるサブルーチン】
$total = &sum (22, 43); ← 22 と 43 の合計を変数にセットする
print $total; ← 合計を表示する
sub sum {
$a = $_[0]; ← 22 を変数にセット
$b = $_[1]; ← 43 を変数にセット
$c = $a + $b ← 2値の合計を求める
return $c; ← 合計の値を返す
}
サブルーチンや条件文など 「{ }」 で囲まれた処理単位のことをブロックと呼びます。
ブロックの外で定義している変数は、グローバル変数と呼びます。
変数をローカル化すると、その変数はローカル化したブロック内だけで有効となります。
● local 関数を使ったローカル変数
local 関数で指定した変数は、グローバル変数で使用している変数と同名であっても、全く別の変数として扱われます。
$text = "グローバル変数です。"; ← グローバル変数をセットする
&message(); ← サブルーチンを呼び出し
sub message {
local ($text); ← 変数をローカル化する
$text = "ローカル変数です。"; ← 変数に文字をセットする
print $text; ← 変数を表示する
}
このプログラムでは、「ローカル変数です。」 の文字が表示されます。
グローバル変数にも同名の $text 変数がありますが、サブルーチン内では、ローカル変数の $text が有効となります。
● my 関数を使ったローカル変数
my 関数は local 関数よりも強力にローカル化を行ないます。(Perl5 より有効)
$text = "グローバル変数です。"; ← グローバル変数をセットする
&message(); ← サブルーチンを呼び出す
sub message {
my $text = "ローカル変数です。"; ← ローカル変数をセットする
print $text; ← 変数を表示する
}
ブロックの外と内で同じ変数名を使いたい場合に、変数をローカル化すると便利です。
ファイルの読み書き
ファイルの読み込み・ファイルの書込み・ファイルの新規作成など、ファイルを操作する場合はすべて open 関数を使います。
【書式】
open ファイルハンドル "ファイル名";
例: open DATA "file.txt";
open DATA "file.txt"; ← file.txt をオープンします
@data = <DATA>; ← ファイルハンドルから配列にデータを読み込みます
close DATA; ← file.txt をクローズします
ファイルハンドル名には半角英数字が使えます(全角文字は指定できません)。
ファイル名の指定には変数を使うことも可能です。
指定されたファイルが存在しない場合には、エラーとなります。
● ファイルの書込み
ファイルの書き込みでは、ファイルの内容がすべて変更されます。
【書式】
open ファイルハンドル ">ファイル名";
例: open DATA ">file.txt";
open DATA ">file.txt"; ← file.txt をオープンします
print DATA @data; ← 配列の内容をファイルに書き込みます
close DATA; ← file.txt をクローズします
指定されたファイルが存在しない場合には、同名のファイルを作成して書込みます。
同名ファイルが存在する場合には、そのファイルを上書きして書き込みます。
● ファイルの変更書込み(読み書き両用)
ファイル内容を読み込んで、内容の一部を変更した後、再度、変更したデータを書き込む場合などに使います。
【書式】
open ファイルハンドル "+<ファイル名";
例: open DATA "+<file.txt";
open DATA "+<file.txt"; ← file.txt をオープンします
seek DATA 0, 2; ← ファイルの末尾に移動します
print DATA $data; ← ファイルの末尾に変数の内容を追加書き込みます
close DATA; ← file.txt をクローズします
● ファイルの追加書込み
追加書き込みでは、ファイルの末尾にデータを書き込みます。
【書式】
open ファイルハンドル ">>ファイル名";
例: open DATA ">>file.txt";
open DATA ">>file.txt"; ← file.txt をオープンします
print DATA @data; ← ファイルの末尾に配列の内容を追加して書き込みます
close DATA; ← file.txt をクローズします
順番にデータが追加されていくログファイルなどに使用します。
■ ファイルロックを行なう
複数のユーザーが一つのファイルに対して同時に読み書きを行なうと、ファイルの内容が壊れてしまうことがあります。
ファイルロックを行なうと、現在使用中のファイルをロックして、第三者がファイルにアクセス出来ないようにします。
【書式】
flock(ファイルハンドル, 操作モード);
操作モードは 下記の値で指定します。
LOCK_SH ・・・ 共有ロック・読み込み時に使用
LOCK_EX ・・・ 排他ロック・書き込み時に使用
LOCK_UN ・・・ ノンブロッキンモード・余り使われません
LOCK_NB ・・・ ロック解除
use Fcntl ':flock';
open DATA ">file.txt";
flock(DATA, LOCK_EX); ← ファイルロック開始
print DATA @data;
flock(DATA, LOCK_NB); ← ファイルロック解除
close DATA;
ここでは、明示的にファイルロックを解除させていますが、
ファイルをクローズすると自動的にファイルロックも解除されるため、特に指定する必要はありません。
* flock() は、WinNT以前の 32bit対応Windows や Windows98 など一部のOSには対応しておりません。
■ 読み込み位置を移動する
seek 関数を使うと、現在のファイルの読み込み位置を移動することが出来ます。
ファイルの先頭や途中に書き込みを行ないたい場合は、seek でその位置に移動して行ないます。
【書式】
seek ファイルハンドル, オフセット, 起点;
オフセットは起点からのバイト数です。
起点は 0, 1, 2 の数字で指定します。
0 ・・・ ファイルの先頭
1 ・・・ 現在のファイルポインタ
2 ・・・ ファイルの末尾
open DATA "+<file.txt"; ← file.txt をオープンします
seek DATA 0, 0; ← ファイルの先頭に移動します
print DATA $data; ← ファイルの先頭に変数の内容を追加書き込みます
close DATA; ← file.txt をクローズします
■ ファイルサイズの変更
truncate 関数を使うと、ファイルサイズを変更することが出来ます。
ファイルサイズを0に切り詰め、新にデータを書き込みたいときなどに使用します。
【書式】
truncate ファイルハンドル, ファイルサイズ;
open DATA "+<file.txt";
seek DATA 0, 0; ← ファイルの先頭に移動します
truncate DATA 0; ← データサイズを空にします
print DATA $data; ← ファイルの先頭に変数の内容を書き込みます
close DATA;
HTMLの表示方法
CGI を利用してHTMLを表示するには、HTMLソースの記述の始めに 「Content-Type: text/htl」 の記述が必要です。
この記述は、これから表示されるデータがHTML形式のデータであることをWEBサーバーに伝えるものです。
この1文がないとHTMLの出力結果がブラウザーに表示されないので注意してください。
「Content-Type」 の記述の後には、空白の改行が1個必要です。
print >>END_HTML;
Content-Type: text/html ← ここから先の記述がHTML文書であることを示します
<html>
<head>
<body>
TEST HTML
</body>
</html>
END_HTML
CGIを使ったデータの受け渡し方法は、下記のような流れになります。
○ ブラウザーから送信されたデータを受け取る
↓
○ 受け取ったデータをPerlで編集・加工する
↓
○ 結果をHMTL形式でブラウザーに返す
● ブラウザーからデーターを送る場合
ブラウザーにデータを入力してもらい、そのデータをサーバーに送信する為には、HTMLのフォームのタグを使います。
[書式]
<FORM action="CGIファイルの指定" method="POST">
〜
</FORM>
この「FORM」 タグに囲まれた中に下記のフォーム要素を配置していきます。
ここで入力されたフォームの情報を、FORM タグの 「action」 で指定されたCGIファイルに送信します。
フォーム要素の種類 | タグの説明 |
---|---|
<INPUT type=text> (テキストボックス) | 文字の入力ボックスを表示します。 |
<INPUT type=radio> (ラジオボタン) | 複数の選択肢の中から1つのみを選択させる場合 |
<CHECKBOX> (チェックボックス) | 選択肢の中から複数を選択させる場合 |
<SELECT> (セレクトボックス) | 複数の選択肢の中から1つの実を選択させる |
<TEXTAREA> (テキストエリア) | 複数行の入力ボックスを表示します。 |
● 送られたデータを受け取る場合
送信されたデータを受け取る場合は、POSTデータの場合は標準入力(STDIN)、
GETデータの場合は環境変数 $ENV{'QUERY_STRING'}を使います。
環境変数から受け取ったデータは下記のようなフォーマットで受信されます。
name=value&name=value&name=value&name=value ・・・
name にはフォーム要素の名前が、value にはフォームに入力されたデータが入ります。
また、value に日本語が入力された場合は、16進数の文字コードとして送信されます。
このままではデータが扱いにくいため、一旦、デコードという処理を行ない受け取ったデータを扱いやすく加工する必要があります。
[デコードの例]
# データがPOST形式の場合
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
# データがGET形式の場合
} else {
$buffer = $ENV{'QUERY_STRING'};
}
# データを name 別に分割する
@pairs = split(/&/, $buffer);
# データハッシュ形式に変換する(%FORM)
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
# 文字の処理
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
&jcode'convert(*value,'euc');
$FORM{$name} = $value;
}
デコード処理を行なうと、データが $FORM{データ名} の形のハッシュ変数に入ります。
ハッシュでデータ名を指定することで、データを取り出せるため大変便利です。
デコード処理を行なわなくても、STDIN や $ENV{'REQUEST_METHOD'} からデータを直接変数に入れて利用することは出来ますが、
複数のデータを受け渡す際には、デコード処理を行なった方がデータを扱いやすいと思います。