Mojoliciousで文字化けが起こった時の対処法2つ

PerlのMVSフレームワーク「Mojolicious」を使っていて、$c->renderでHTMLを表示した時に日本語が文字化けしたので、その対処法を2つ紹介していきます。

そもそもPerlで文字化けが起こる原因とは?

そもそも、Perlで文字化けが起こる原因とは何でしょうか?

起こりうる原因は色々ありますが、多くの場合は「内部文字列」と「バイト文字列」の誤った扱いによる所が多いです。

バイト文字列とは、簡単に言うと「文字コード」の事ですね。文字を扱う上で基本になるのが文字コードですが、こんにちわと言う文字の長さが15(utf8の場合)と出たりする等、プログラムをする時に直感的に理解できる処理にならない、と言う欠点があります。

そう言う通常の文字コードの欠点を補ったのが、Perl独自の「内部文字列」と言うやつ。

基本的にutf8と同じ動作をしますが、こんにちわの文字列の長さが5になる等、プログラムを組むのに理解しやすい処理をしてくれます。

ただ、Perlの内部文字列はPerl独自の物なので、ファイル操作とかDB操作(DBIやMySQL操作)の外部プログラムとのやり取りで文字列を扱う時に、不自然な挙動をし始めるのが文字化けの原因です。

(今回の記事では内部文字列と言う表記をしていますが、他のネットの記事や本によっては、「テキスト文字列」「内部表現」「Perl文字列」と言う表現をしている場合もあります。)

また、Perlの内部文字列については以下の記事が詳しいです。

参考:第16回 Perl内部構造の深遠に迫る(2):Perl Hackers Hub|gihyo.jp … 技術評論社

参考:Perl の文字列エンコーディングの話 | Hachioji.pm 日めくりテックトーク

Mojoliciousで文字化けが起こった時の対処法2つ

実際にMojolicousで文字化けが起こった場合の対処法には、以下の2つがあります。

1, DBIのオプションにmysql_enable_utf8 => 1をつける

PerlのデータベースのモジュールとしてDBIを使っている場合は、mysql_enable_utf8 => 1のオプションをつける事で簡単に解決できます。

実装方法は簡単で、DBI->connectの第4引数にオプションとして付けるだけです。今回の例ではMySQLにしていますが、他のDBでもできるはずです。(調べていない)

    DBI->connect( "DBI:mysql:database=sample;host=localhost",
"root", "pass", { mysql_enable_utf8 => 1 } )
or die $DBI::errstr;

また、DBI関連で調べる時は、perl DBIとググるだけでなく、perl DBI myslqのようにそれぞれのDBで調べた方が調べたい事がよく出てきます。

参考:DBD::mysql – MySQL driver for the Perl5 Database Interface (DBI) – metacpan.org

Encodeモジュールのdecodeメソッドを使う

PerlにはEncodeモジュールと言うものがあって、そのdecodeメソッドを使うと文字化けが解決できます。

例えば、以下のようにコントローラー内にindexメソッドを定義しているとします。以下の例では$c->stash( str => $str );で$str変数をテンプレートに渡していますが、このままでは文字化けしてしまうとします。

sub index {
my $c      = shift;
my $str = $c->post_db->find;
$c->stash( str => $str );
$c->render;
}

しかし、以下のようにdecodeをして、普通の文字列をPerlの内部文字列に変える事で文字化けを防ぐ事ができます。

use Encode;
sub index {
my $c      = shift;
my $str = $c->post_db->find;
$str = decode('utf8', $str);
$c->stash( str => $str );
$c->render;
}

ReratedPosts

Perlモジュール「Moo」(Moose)の使い方をまとめてみる
perlモジュール「Exporter」の使い方
perlでファイルの中身を全て読み込みたい時の方法
PerlのDBIで新規レコードを作成(INSERT)した時にレコードのIDを取得する方法
perlのgrep関数の使い方|変数とか戻り値とか複数条件とかのまとめ
perlでファイルの読み込みとか作成とか削除のまとめ