cgiにおける文字コードの扱いとか
Perlで日本語処理を書いてると文字コード周りでハマるのは誰もが一度は経験するはず。
慣れてくると、ちゃんとuse utf8 or encodingとbinmodeしてればいいんでしょ、となると思うんだけど、今回の敵はcgiでした。
今回の教訓は、utf8フラグ付いている文字列と付いていない文字列でeqしてもtrueが返ってくること。
そして、もう1つはwebにあるコードもきちんと意味を考えて使いましょうということ。
CGI.pmでutf8フラグの扱いがおかしい話は前から知っていて、このページCGI.pmとUTF8 flag : blog.nomadscafe.jpを参考に、
use utf8;
binmode STDOUT, ":utf8";
use Encode;
for my $p ($q->param) {
my @v = map {Encode::decode('utf8',$_)} $q->param($p);
$q->param($p,@v);
}
としていました。ところがどうもうまく行かないなと悩んでいたのですが、これパラメータの値の方だけutf8フラグをきちんと処理してて、キーの方は修正してないんですよね…
cgiのキーの方に日本語とか使う人がどれくらいいるかは知りませんが、その場合には
use utf8;
binmode STDOUT, ":utf8";
use Encode;
for my $p ($q->param) {
my @v = map {Encode::decode('utf8',$_)} $q->param($p);
$q->delete($p);
$p = Encode::decode('utf8',$p);
$q->param($p,@v);
}
とする必要があるみたいです。