初心者だけどPerlが大好き

コードが世界を変える!

use Encodeで掲示板

404 Blog Not Found というブログをお書きになっている 小飼 弾さんが
Encodeモジュールを制作されまして
詳しいことが書かれているのが以下のリンクページです

404 Blog Not Found:perl - Encode 入門
http://blog.livedoor.jp/dankogai/archives/51031595.html

404 Blog Not Found:perl - Encode 中級
http://blog.livedoor.jp/dankogai/archives/51047005.html

404 Blog Not Found:perl - use encoding; #は黒歴史
http://blog.livedoor.jp/dankogai/archives/51221731.html

スクリプトUTF-8で書き、use utf8;するのがモダンPerlのあり方です

入り口で decode して、
内部ではすべて flagged utf8 で扱い、出口で encode する。
これがすべてです!とにかくこの基本方針をまもっていれば幸せになれます。

と はてなID tokuhirom さんが言っています

Perl で utf8 化けしたときにどうしたらいいか
http://d.hatena.ne.jp/tokuhirom/20080408/1207619640


内部では utf8フラグを立てたコードで処理 というのが肝です
utf8フラグさえ立ててしまえば
どんなコードも処理できるのであります
ちなみに
utf8フラグを落として 外部に出さないと 
Apachのログに
WideCharacterエラーが出ます

Wide character in print atというエラーは
UTF-8フラグが付いた文字列をprintしようとしているからです。
なのでUTF-8フラグを取り外してからprintすればエラーがでなくなります。

さくらのサーバーで動く掲示板です
文字コードは UTF-8N
sakurakeijiban.cgi

#!/usr/bin/perl
use CGI;
use open ":utf8";
use Encode;
use utf8;
my $q = CGI->new();
print $q->header(-charset => 'utf-8'),
$q->start_html(-title=>"Example CGI.pm Form", -style=>{'src'=>'form.css'}),
$q->h1(' Example CGI.pm Form'),
$q->start_div({-class=>"aaa"}),
$q->start_form(-action=>"sakurakeijiban.cgi"),
$q->em("What's your name?"),
$q->textfield('name'),
$q->checkbox('Not my real name'),
$q->br,
$q->em("What's your e-mail?"),
$q->textfield('email'),
$q->br,
$q->em("What's your subject?"),
$q->textfield('subject'),
$q->br,
$q->em('Any parting comments?'),
$q->textarea(-name=>'comments',-rows=>3,-columns=>50),
$q->br,
$q->reset,
$q->hidden(-name =>'mode', -value =>'write'),
$q->submit(-name =>'Action', -value =>encode('utf8', '送信')),
$q->end_form,
$q->end_div,
$q->end_html;
($sec, $min, $hour, $mday, $mon, $year) = localtime(time);
$mytime = sprintf("%04d年%d月%d日%02d時%02d分%02d秒", $year + 1900, $mon +1, $mday,$hour, $min, $sec);
$name= decode('utf8', $q->param('name'));
$email= decode('utf8', $q->param('email'));
$subject= decode('utf8', $q->param('subject'));
$comments= decode('utf8', $q->param('comments'));
$name = $q->escapeHTML($name);
$email = $q->escapeHTML($email);
$subject = $q->escapeHTML($subject);
$comments = $q->escapeHTML($comments);
$comments=~ s/\r\n|\r|\n/br/eg;
$fname = 'trinity777.dat';
open(FILE, "<$fname") || &error(404," ファイル読み込みに失敗しました");
binmode FILE, ":encoding(:utf8)";
@data=<FILE>;
close(FILE);
if($q->param(mode) eq "write")
{#// ファイル書き込み
unshift @data, join("\t", map {$_} ($mytime, $name, $email, $subject, $comments)) . "\n";
    warn encode('utf8', @data);
    open(FILE, ">$fname") || &error(404," ファイル書き込みに失敗しました");
    print FILE @data;
    close(FILE);
foreach $line(@data) {
        chomp $line;
        my ($mytime,$name,$email,$subject,$comments) = split(/,/,  $line);
print $q->start_html(-title=>"Example CGI.pm Form", -style=>{'src'=>'form.css'}),
$q->em($subject),
        $q->p($mytime),
        $q->a({href=>'mailto:'.$email}, $name),
        $q->p($comments),
        $q->hr,
$q->end_html;
}
}
else{
open(FILE, "<$fname") || &error(404," ファイル読み込みに失敗しました");
binmode FILE, ":encoding(:utf8)";
@data=<FILE>;
close(FILE);
foreach $line(@data) {
        chomp $line;
        my ($mytime,$name,$email,$subject,$comments) = split(/,/,  $line);
print $q->start_html(-title=>"Example CGI.pm Form", -style=>{'src'=>'form.css'}),
$q->em($subject),
        $q->p($mytime),
        $q->a({href=>'mailto:'.$email}, $name),
        $q->p($comments),
        $q->hr,
$q->end_html;
}
}


trinity.dat というファイルを事前に空で作成してね
スタイルシートは form.css

body{background-color:#66ffcc;font-size:20px;}
h1{text-align:center;margin:0 15%;
background-color:#eea8aa;
font-size:20px;
color:#ffffff;
font-style:italic;}
em{font-size:20px;
border-bottom:dashed;
color:#808000;}
.aaa{border:solid 20px red;margin:2px 15%;padding:0px;line-height:40px;}