ラベル CGI の投稿を表示しています。 すべての投稿を表示
ラベル CGI の投稿を表示しています。 すべての投稿を表示

2007年6月29日金曜日

CGIで日本語を正しく扱う方法

CGIで日本語を正しく扱うのは意外と難しい。
最近のPerl5.8ではプログラム自体の文字コードが多言語化された。それに伴い、日本語を扱うCGIでは文字コードなどを指定するプログラムを追加する必要があるため、若干複雑になる。
日本語の処理をきっちり説明した解説書も少ない。
そこで、CGIで日本語パラメータの受け渡しを行う例を示しておく。

#!c:/xampp/perl/bin/perl -w
use strict; # 安全のための制限を課す
use warnings; # 警告を出す(same as -w)
use utf8; # UTF-8で書いている
use CGI; # CGIである。
binmode STDOUT,":utf8"; # 標準出力はUTF8
my $encoding = 'utf8'; # HTMLの文字コード
my $lang = 'ja'; # 言語は日本語
my $q = CGI->new();
unless ($q->param) {
response(<<HTML);
<form method="post" action="hello-form.cgi">
あだ名 <input type="text" name="nickname" />
<input type="submit" />
</form>
HTML
exit 0;
}
my $nickname = $q->param('nickname'); # native bytes
utf8::decode($nickname); # utf8
response("こんにちは、$nickname");
exit 0;

sub response {
my ($body) = @_;
print $q->header(-type=>'text/html',-charset=>$encoding);
print $q->start_html(-title=>'Hello Perl',
-lang=>$lang,-encoding=>$encoding);
print $body;
print $q->end_html();
}

CGIの進化(2)

初期のCGIではページごとにCGIを開発していた。小規模アプリケーションではそれでもよいが、大規模アプリケーションでは通用しない。ファイルが多くなり、維持管理が困難となる。そこで複数のCGIを1つにまとめる技法が必要となった。
パラメータで判断する方法もあるが、その方法ではいつもフォームを使わなければならない。そこで、一般的にはPATH_INFOを用いることが多い。
PATH_INFOとはURLのCGI以下のパスである。例えば、foo.cgi/barというURLがあると/barがPATH_INFOである。このbarと同じ名前の関数を呼び出せば(1つのアプリケーションの)複数のプログラムを1つのCGIに同居させることができる。この技法はCGI::Applicationでも使われている。
以下に例を示す。

#!c:/xampp/perl/bin/perl -w
##!!
use strict; # 安全のための制限を課す
use warnings; # 警告を出す(same as -w)
use utf8; # UTF-8で書いている
use CGI; # CGIである。
binmode STDOUT,":utf8"; # 標準出力はUTF8
my $encoding = 'utf8'; # HTMLの文字コード
my $lang = 'ja'; # 言語は日本語

my $q = CGI->new();
dispatch();
exit 0;

# foo.cgi/bar.doなら関数barを呼び出す
sub dispatch {
my $path_info = $q->path_info();
my $action = "do_index"; # 省略時のアクション
if ($path_info =~ /\/([^\/\.]*)\.do/) { # .doはアクションを区別する拡張子
$action = "do_$1"; # アクションは接頭語do_から始まる
}
eval {
no strict 'refs'; # ここだけ参照の制限を緩める
&{$action}(); # 関数を呼び出す
};
do_nothing($action) if $@; # 関数がない場合
}

sub do_nothing {
my ($action) = @_;
response("no such an action $action");
}

sub do_index {
my $url = $q->url();
response(<<HTML);
<p><a href="$url/english.do">English</a></p>
<p><a href="$url/japanese.do">Japanese</a></p>
HTML
}

sub do_english {
response("Hello");
}

sub do_japanese {
response("こんにちは");
}

sub response {
my ($body) = @_;
print $q->header(-type=>'text/html',-charset=>$encoding);
print $q->start_html(-title=>'Hello Perl',-lang=>$lang,-encoding=>$encoding);
print $body;
print $q->end_html();
}

CGIの進化(1)

CGIは進化してきた。
最初のCGIはHTTP応答をそのまま表す以下のようなものだった。

print "Content-Type: text/html\n\n";
print "<html><body>Hello</body></html>";

ちなみに、これはPerlというプログラミング言語で書かれたプログラムである。PerlはCGIの定番言語である。
やがて、cgi-lib.plやCGI.pmなどのライブラリが充実してきた。cgi-lib.plはPerl4、CGI.pmはPerl5用のライブラリである。以下はCGI.pmを用いた例である。

use CGI;
$q = new CGI;
print $q->header();
print $q->start_html();
print "Hello";
print $q->end_html();

意味不明な部分がそれなりにわかりやすくまとまっていることがわかる。
最近のPerl5.8ではプログラム自体の文字コードが多言語化された。それに伴い、日本語を扱うCGIでは文字コードなどを指定するプログラムを追加する必要があるため、若干複雑になる。

CGIのすすめ

CGIはWebサーバに代わりHTTP応答文を生成する外部プログラムである。CGIによって動的なページを作成できるようになってきた。
CGIは古い技術だ。最新技術だけに興味のある人には見向きもされないが、きちんと動くものづくりが要求される現場の技術者にはありがたい。そもそも古いということは枯れている、すなわちバグが少ないことを意味する。これがなにより重要だ。
また、CGIはその他の技術の母体でもある。CGIを飛び越してJavaから学び始めた若い人もぜひ一度腰を据えて学ぶことをおすすめする。CGIは簡単なのでWebの原理を知るのに適している。
また、実際問題としてサーバでプログラムを動かすときGIしか選択肢がないこともある。CGIに必要なハードルは低い。
CGIを試すにはWebサーバが必要だ。非公開でよければ自分のPCにXAMPPをインストールするとよい。CGIはPerlという言語で作ることが多い。PerlはXAMPPのアドインとして同じサイトで配布されている。