フリーCGIスクリプト配布サイト。
これまでで作成した掲示板は、すべて文字コードがShift-JISでした。しかし、インターネット上では色々な文字コードが使用されています。Shift-JISのほかにも、EUCやJISなどがあります。
掲示板などでデータ送信元ページの文字コードがEUCなのにCGIはShift-JIS…などとなると、データが文字化けしてしまい、正しく表示することができません。
これを解決するために、どの文字コードで送られてきても正しく処理できるように、CGI側で文字コードの変換処理を行います。ですが、文字コードの変換処理を一から用意するのは結構大変です。
ですが、jcode.pl
という文字コードを変換するためのライブラリがあり、一般に配布されています。Perl4では、文字コードの変換にはこのライブラリがよく利用されます。jcode.pl
は、以下のサイトからダウンロードすることができます。
使用するにはCGIと同じフォルダ内に jcode.pl
を置きます。そしてCGIファイル内に以下の処理を追加します。
require 'jcode.pl';
これで jcode.pl
を読み込むことができますので、jcode.pl
で定義されている関数を使用することができるようになります。
文字コードの変換を行う関数は convert
です。書式は以下のようになります。
&jcode::convert(*変数名, '変換後の文字コード');
例えば、$value
に格納されている文字列の文字コードをShift-JISに変換したい場合は、以下のように記述します。
&jcode::convert(*value, 'sjis');
この処理をCGIに加えてやります。
#!/usr/local/bin/perl
#ライブラリの読み込み
require 'jcode.pl';
#投稿された値を受け取る
if ($ENV{'REQUEST_METHOD'} eq 'POST') {
read(STDIN, $alldata, $ENV{'CONTENT_LENGTH'});
} else {
$alldata = $ENV{'QUERY_STRING'};
}
foreach $data (split(/&/, $alldata)) {
($key, $value) = split(/=/, $data);
$value =~ s/\+/ /g;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg;
$value =~ s/\t//g;
&jcode::convert(*value, 'sjis');
$in{"$key"} = $value;
}
#ヘッダの表示
print "Content-Type: text/html; charset=Shift_JIS\n\n";
print "<html>\n";
print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=Shift_JIS\">\n";
print "<head><title>掲示板</title></head>\n";
print "<body>\n";
#受け取ったデータをファイルに書き込む
if ($in{'handle'} ne '' && $in{'message'} ne '') {
if (open(FH, "bbs.txt")) {
@file = <FH>;
close(FH);
#改行コードを改行タグに変換
$in{'message'} =~ s/\r\n/<br>/g;
$in{'message'} =~ s/\r/<br>/g;
$in{'message'} =~ s/\n/<br>/g;
#現在日時の取得
($sec, $min, $hour, $day, $mon, $year, $week) = localtime(time());
@week = ('日', '月', '火', '水', '木', '金', '土');
$year = $year + 1900;
$mon = $mon + 1;
$week = $week[$week];
$date = "$year年$mon月$day日($week) $hour時$min分$sec秒";
unshift(@file, "$in{'handle'}\t$in{'message'}\t$date\n");
if (open(FH, ">bbs.txt")) {
print FH @file;
close(FH);
} else {
print "<p>ファイルに書き込めません。</p>";
}
} else {
print "<p>ファイルを読み込めません。</p>";
}
}
#投稿フォームの表示
print "<form method=\"post\" action=\"bbs.cgi\">\n";
print "<p>\n";
print "ハンドルネーム<br>\n";
print "<input type=\"text\" name=\"handle\" size=\"20\" value=\"\"><br>\n";
print "メッセージ<br>\n";
print "<textarea name=\"message\" cols=\"50\" rows=\"5\"></textarea>\n";
print "</p>\n";
print "<p><input type=\"submit\" value=\"送信する\"></p>\n";
print "</form>\n";
#記事の一覧表示
if (open(FH, "bbs.txt")) {
while ($data = <FH>) {
($handle, $message, $date) = split(/\t/, $data);
print "<p>\n";
print "投稿者:$handle<br>\n";
print "メッセージ:$message<br>\n";
print "投稿日時:$date\n";
print "</p>\n";
}
} else {
print "<p>ファイルを読み込めません。</p>";
}
#フッタの表示
print "</body>\n";
print "</html>\n";
exit;
プログラムのはじめに require 'jcode.pl';
を追加し、値を受け取る処理に &jcode::convert(*value, 'sjis');
を追加しています。これで、受け取った値がすべてShift-JISになります。
また、ヘッダの表示処理に print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=Shift_JIS\">\n";
を追加しています。これにより、このページの文字コードがShift-JISである事が宣言できますので、文字化けの防止になります。