utf8プラグマを付けると 受け取った内容の一部が文字化けます。
CGIモジュールを利用して、フォームを作成しているのですが、入力画面からフォームの内容を受け取る際、utf8プラグマを付けると
受け取った内容の一部が 文字化けます。
以下のようにパラメーターを取得しています。
どうしたらよいでしょうか
現象はLaten-1の文字コードが表示されてしまいます。
#!/usr/bin/perl
use strict;
use Encode;
use Encode::Guess;
use Encode::EUCJPMS;
#use Jcode;
use CGI;
use utf8;
my $cgi = new CGI;
require 'mimew.pl'; # jcode($subject)->mime_encode が動かないとき
#エラーメッセージをブラウザに表示
use CGI::Carp qw(fatalsToBrowser);
use Data::Dumper;
###################################
print "Content-Type: text/html; charset=utf-8\n\n";
# 項目名
my @item_names = ();
# 項目の日本語表示名
my %item_disp = ();
# 項目の値
my %item_value = ();
# 項目の必須有無
my %item_need = ();
# フォームパラメータ
my %fm_param = ();
my $cgi_url = $cgi->url();# このCGIのURL
#######################################################################
# 入力文字コード判定
#######################################################################
my $input_value = '';
my $name;
my $value;
my @values;
foreach $name ($cgi->param) {
if ($name !~ /^submit$/i) {# 項目('submit'は除く)
@values = $cgi->param($name);
$value = join(',', @values);
if($cgi->param('fm_command') eq 'confsend') {# 確認フォームからのときデコード
$value = pack_param($value);
}
$input_value .= $value;
}
}
#エラーメッセージ配列
my @err_namelist = ();
#送信データがなければエラーとする
if (0 == length($input_value)) {
push(@err_namelist, '呼び出しエラーです。管理者にお問い合わせ下さい。');
print_input_error(@err_namelist);
exit;
}
#$input_jcode = Jcode::getcode($input_value);
my $guess = guess_encoding($input_value, qw/euc-jp shiftjis 7bit-jis/);
my $guess_encode = ($guess->name eq 'euc-jp') ? 'eucJP-ms' : $guess->name;
#######################################################################
# パラメータ読み込み
#######################################################################
my @checkboxes_array;
foreach $name ($cgi->param) {
if ($name =~ /^fm_/) {# フォームパラメータ
$value = $cgi->param($name);
if($cgi->param('fm_command') eq 'confsend') {# 確認フォームからのときデコード
$value = pack_param($value);
}
#$value = jcode($value, $input_jcode)->sjis;
$value = ($guess->name ne 'shiftjis') ? encode('utf8', decode($guess_encode, $value)) : $value;
$fm_param{$name} = $value;
if($name =~ /^fm_disp_(\w+)/) {# 項目の日本語表示名
$item_disp{$1} = $value;
if(!defined $item_value{$1}) {
push(@item_names, $1);
$item_disp{$name} = ($guess->name ne 'shiftjis') ? encode('utf8', decode($guess_encode, $value)) : $value;
$item_value{$1} = '';
}
} elsif($name =~ /^fm_need_(\w+)/) {# 項目の入力必須
$item_need{$1} = $value;
}
} elsif($name !~ /^submit$/i) {# 項目('submit'は除く)
if(!defined $item_value{$name}) {
push(@item_names, $name);
}
@values = $cgi->param($name);
my $len = @values;
if ($len > 1) {
logger($name . 'はチェックボックスなのです!で項目数は' . $len . 'なのです!(ただし複数選択可能なselectタグかもしれない・・・けど項目の上限を決めておけばいい($lenが上限以下ならselectでも項目をCSVに出す等))');
for (my $k=0; $k<$len; $k++) {
logger(@values[$k]);
}
#MEMO:
#確認画面で項目数がここでわかったので、後ろの画面に$nameは$len項目ですと渡せばcsvでいい感じにできるのです!
#実際の処理には現状確認画面でスペース?区切りか何かにされてしまっているため、項目数がうまくは取れないと思われる(確認画面のhiddenタグ参照の事)
my $object = {
name => $name,
len => $len,
#values => @values,
values => [],
};
for (my $k=0; $k<$len; $k++) {
logger(@values[$k]);
push(@{$object->{values}}, @values[$k]);
}
push(@checkboxes_array, $object);
}
$value = join(',', @values);
if($cgi->param('fm_command') eq 'confsend') {# 確認フォームからのときデコード
$value = pack_param($value);
}
#$item_value{$name} = jcode($value, $input_jcode)->sjis;
$item_value{$name} = ($guess->name ne 'shiftjis') ? encode('utf8', decode($guess_encode, $value)) : $value;
if($item_disp{$name} eq '') {
$item_disp{$name} = $name;
}
}
}
my $len = @checkboxes_array;
if ($len > 0) {
logger('新規オブジェクト配列は' . $len);
for (my $i=0; $i<$len; $i++) {
logger(@checkboxes_array[$i]->{name});
logger(Dumper @checkboxes_array[$i]);
}
}
$value= decode('utf-8', $value);
foreach my $key (@item_names) {
#print $item_disp{$_} .':'.$item_value{$_};
$name = conv_html($item_disp{$key});
$value = conv_html($item_value{$key});
}
exit;
### csvに書けるように変換
sub conv_csv {
my ($str) = @_;
#$str =~ s/</</g;
#$str =~ s/>/>/g;
$str =~ s/\t//g;
$str =~ s/\r//g;
$str =~ s/\n//g;
$str =~ s/\,/"\,\"/g;
#$str =~ s/"/""/g;
return '"' . $str . '"';
#return '' . $str . '';
}
sub conv_tsv {
my ($str) = @_;
#$str =~ s/</</g;
#$str =~ s/>/>/g;
$str =~ s/\t//g;
$str =~ s/\r//g;
$str =~ s/\n//g;
$str =~ s/\,/"\t\"/g;
#$str =~ s/"/""/g;
return '"' . $str . '"';
#return '' . $str . '';
}
### htmlで表示できるように変換
sub conv_html {
my ($str) = @_;
$str =~ s/</</g;
$str =~ s/>/>/g;
$str =~ s/\t//g;
$str =~ s/\r//g;
$str =~ s/\,/ /g;
$str =~ s/\n/<br>\n/g;
return $str;
}
### htmlで表示できるように変換
sub conv_html2 {
my ($str) = @_;
$str =~ s/</</g;
$str =~ s/>/>/g;
$str =~ s/\t//g;
$str =~ s/\r//g;
#$str =~ s/\,/ /g;
$str =~ s/\n/<br>\n/g;
return $str;
}
sub conv_mail {
my ($str) = @_;
#$str =~ s/</</g;
#$str =~ s/>/>/g;
$str =~ s/\t//g;
$str =~ s/\r//g;
$str =~ s/\n//g;
$str =~ s/\,/"\t\"/g;
#$str =~ s/"/""/g;
return '"' . $str . '"';
#return '' . $str . '';
}
### hiddenパラメータに格納できるようにエンコード
sub unpack_param {
my ($str) = @_;
$str =~ s/([^\w.\/\-@ ])/'%'.unpack('H2',$1)/eg;
return $str;
}
### エンコードしたhiddenパラメータをデコード
sub pack_param {
my ($str) = @_;
$str =~ s/%([A-Fa-f0-9]{2})/pack('H2', $1)/eg;
return $str;
}
sub conv_ahtml {
my ($str) = @_;
#$str =~ s/</</g;
#$str =~ s/>/>/g;
$str =~ s/\t//g;
$str =~ s/\r//g;
$str =~ s/\n/<br>\n/g;
return $str;
}