概要
cgi-lib.pl の ReadParse() 関数を CGI.pm で実装するサンプルです。
あと Qiita への投稿テスト用として。
経緯
今時知っている人の方が少ないだろう cgi-lib.pl の ReadParse を使っている CGI(文字コードはInもOutもEUC-JP前提)をメンテする羽目に。
当然以下の様な要望がわき上がって来ます。
新規に追加するソースコードぐらいは UTF-8で書きたい!
ってことで、お手軽に実現する定番の方法を採用
binmode STDIN,":encoding(eucjp)"
binmode STDOUT,":encoding(eucjp)"
binmode STDERR,":encoding(eucjp)"
use utf8;
cgi-lib.pl 先生の ReadParse のワナ
どうも cgi-lib.pl 先生に ReadParse して貰うとなんか文字化ける。
どうやら ReadParse 先生は QUERY_STRING やらを読み出す時に binmode STDIN/STDOUT を設定してしまう模様(ソース確認してないけど)。
まあ、ReadParse したらもう一回":encoding(eucjp)"を設定すれば回避も出来るのだけど、なんかスマートじゃない。
CGI.pm の param で読み取る場合はこの問題は起きないので、んじゃリハビリがてら CGI.pm で ReadParse を実現しますかーっていう感じです。
コード
=head2 FUNCTION ReadParse( \%parsedParams [,\@keysYouNeed]) CGI.pm を使った ReadParse 実装 + ちょっと拡張 =head3 DESCRIPTION cgi-lib.pl の ReadParse() 関数を CGI.pm で実装 & ちょっと拡張したサンプルです。=head3 cgi-lib 版との違い - 第二引数でハッシュに読み込むキーを制限することが出来ます。 - チェックボックスなど複数のバリューを持つ場合、配列リファレンスで格納します。
=head3 \%parsedParams CGI.pm の param()メソッドを用いて取得したキー&バリューを格納します。
=head3 PARAM @keysYouNeed
このオプションが渡されなかった場合すべてのインプットキーをハッシュ化します。
cgi-lib.pl 版と異なり、単一キーに複数の値があった場合、リストに展開して
リファレンスとして格納します。 @keysYouNeed に取得するキーのリストをセットした時はそれらのキーに
対応する値のみをハッシュに格納します。 ただし、そのキー値がそもそも存在しない場合何もセットしません。
これは exists や defined による各種判定が有効に
使えるようにするためです。=head3 MEMO 文字コードを指定してデコード済み(いわゆる flagged utf8 )の値として扱う場合 コメントアウトをはずして弄れば OK。< もう少しスマートにかたづけたいけど
また今度。・・・もしかして CGI.pm に用意されていたりして。 =cutsub ReadParse{ my $q = new CGI(); my $hashRef = shift @_ || {}; my $enableKeys = shift @_; # my $encoder = find_encoding('eucjp'); my $parseMethod = sub { my $key = shift @_; my @values = $q->param($key);# map { $_ = $encoder->decode($_) } @values; $hashRef->{$key} = scalar(@values)>1?\@values:$values[0]; }; if( 'ARRAY' eq ref $enableKeys) { my @keyList = $q->param(); foreach my $key ( @$enableKeys ) { next if( ! grep{ $key eq $_ } @keyList ); $parseMethod->( $key ); } } else { foreach my $key ( $q->param() ) { $parseMethod->( $key ); } }}```
まあ、今時こんなコードほしがる人いないと思うけど。