Skip to content

Instantly share code, notes, and snippets.

@clairvy
Created July 25, 2010 23:13
Show Gist options
  • Select an option

  • Save clairvy/489979 to your computer and use it in GitHub Desktop.

Select an option

Save clairvy/489979 to your computer and use it in GitHub Desktop.
AddHandler cgi-script .cgi
Options +ExecCGI

最初に

どんな問題にも言えることですが,何か技術的な疑問があった場合は, できるだけ最小のもので再現できるように努力してください. それが問題への理解を深め,問題解決を早めます.

質問内容

unshift  しなければ utf-8で奇麗に出力されます 一度 @data に入れて printしたものを読み込むと 文字化けしてしまいます

疑問

比較する

ソースコードでの違いを見ます. 問題が何処で起きているかを確認するためです. 今回は,unshift があるところの差分で確認できそうです.

$ diff -w index{1,2}.cgi
44,45c46
<     unshift @data,"$mytime','$name','$email','$subject','$comments\n";
<     print @data;
---
>     print FILE $mytime,",",$name,",",$email,",",$subject,",",$comments,"\n";

そもそも,print と print FILE という違いがあります.

typo と予想して FILE を追加します.

文字コード指定

そもそも open で utf-8 としてファイルをロードしているのかどうかという話があります.

質問者への前提知識で,

  • Windows の Perl

  • Perl 5.8.X らしいので,デフォルトの PerlIOレイヤは,Shift_JIS になっているのかもしれません. 明示的に PerlIO を指定するのに open プラグマを使います.

    use open ':utf8'; use open ':std';

入出力の両方のopen に :utf8 レイヤを指定して, :std は標準入出力へも :utf8 を指定しています.

と思ったけど,うまくいかなかったので, use open ':utf8'; binmode(STDOUT, ':utf8'); のように STDOUT にのみ :utf8 フラグを付けてみた.

自分の環境だとbinmode の方で上手くいったように見える.

その他

あと気になるところとして,

  • 出力された HTML が lang=en になってる.
  • が複数表示されるようになっている
  • 前者の方だけ,'(シングルクォート)が入っている.(typo?)

とかがあります.

<body>
<ul>
<li><a href="index1.cgi">できてない</a></li>
<li><a href="index2.cgi">できた</a></li>
</ul>
</body>
#!/usr/bin/env perl
use utf8;
use CGI;
use open ':utf8';
binmode(STDOUT, ':utf8');
$q = CGI->new();
print $q->header(-charset => 'utf-8'),
$q->start_html(-title=>"Example CGI.pm Form"),
$q->h1(' Example CGI.pm Form'),
$q->start_div({-class=>"aaa"}),
$q->start_form(-action=>"index1.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 =>'送信'),
$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= $q->param('name');
$email= $q->param('email');
$subject= $q->param('subject');
$comments= $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';
if ($q->param(mode) eq "write") { #// ファイル書き込み
open(FILE, ">>$fname") || &error(404," ファイル書き込みに失敗しました");
unshift @data,"$mytime','$name','$email','$subject','$comments\n";
print FILE @data;
close(FILE);
}
#// ファイル読み出し
open(FILE, "<$fname") || &error(404," ファイル読みだしに失敗しました");
while (<FILE>) {
chomp;
my ($mytime,$name,$email,$subject,$comments) = split(/,/, $_,);
print $q->start_html,
$q->em("$subject"),
$q->p("$mytime"),
$q->a({href=>'mailto:'.$email}, $name),
$q->p("$comments"),
$q->hr,
$q->end_html;
}
close(FILE);
#!/usr/bin/env perl
use utf8;
use CGI;
use open ':utf8';
binmode(STDOUT, ':utf8');
my $q = CGI->new();
my $PAGESIZE = 10;
print $q->header(-charset => 'utf-8'),
$q->start_html(-title=>"Example CGI.pm Form"),
$q->h1(' Example CGI.pm Form'),
$q->start_div({-class=>"aaa"}),
$q->start_form(-action=>"index2.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 =>'送信'),
$q->end_form,
$q->end_div,
$q->end_html;
if ($q->param(mode) eq "write") {
($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= $q->param('name');
$email= $q->param('email');
$subject= $q->param('subject');
$comments= $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," ファイル書き込みに失敗しました");
print FILE $mytime,",",$name,",",$email,",",$subject,",",$comments,"\n";
close(FILE);
}
#// ファイル読み出し
open(FILE, "<$fname") || &error(404," ファイル読みだしに失敗しました");
while (<FILE>) {
chomp;
my ($mytime,$name,$email,$subject,$comments) = split(/,/, $_,);
print $q->start_html,
$q->em("$subject"),
$q->p("$mytime"),
$q->a({href=>'mailto:'.$email}, $name),
$q->p("$comments"),
$q->hr,
$q->end_html;
}
close(FILE);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment