Param関数

「#--Param」で検索すると確実にヒットします。

この関数は、入力された内容(この場合はURL)を取得し、デコードした値を返します。

引数はなしで、戻り値は入力されたURLです。

それでは、この関数の流れを見てみましょう。

入力値の取得

HTMLのFormタグからGETまたはPOST形式で入力値が送られてくるため、どちらでも受け取れるようにします。

if ($ENV{'REQUEST_METHOD'} eq 'GET') {
$query_string = $ENV{'QUERY_STRING'};
} elsif ($ENV{'REQUEST_METHOD'} eq 'POST') {
read(STDIN, $query_string, $ENV{'CONTENT_LENGTH'});
}

環境変数「$ENV{'REQUEST_METHOD'}」を参照すれば、どちらの形式で入力されたのかがわかります。

GET送信であれば、環境変数「$ENV{'QUERY_STRING'}」に値が格納されているのでそこから取得します。

POST送信であれば、read関数を使って値を取得します。

デコード

次に、取得した値から入力されたURL部分を取り出しデコードします。

入力値が送信されるときにはデータを整理するためエンコードされます。

そして、Perl/CGIが入力値を受け取ったときもエンコードされたままなので、デコードしてもとの入力値に戻してやる必要があります。

今現在取得した値は「URL=http%3A%2F%2F~」となっています。

頭の「URL」というのは、Page関数で出力されたURL入力欄に付けられた名前です。

次の「=」というのは、それ以降(「&」が出てくるまで)の文字列が入力された値であることを表しています。

ただしこの場合は、入力値がURLだけなので「&」は出てきません。

たとえURL内に「&」があったとしても、入力値が送信されるときにはエンコードされ「%26」になります。

なので、パターンマッチで「URL=~」の「~」部分を取り出しデコードしてやればよいわけです。

if ($query_string =~ /^URL=(.+)$/) {
$input = $1;
$input =~ tr/+/\x20/;
$input =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg;
...
...
}

デコード作業は、「+」を半角スペースに、「%」とその後に続く16進2桁をバイナリにパックします。

バイナリにパックというのはものすごく乱暴に説明すると、組み合わせて文字データを完成させるということです。

なので、ものすごく広く考えれば、ここでのデコードとは「文字にすること」だと言えます。

return $input;

そうして無事に入力されたURLを取得したら、その文字列を返して関数終了です。