Movable TypeをMySQLで運用している際に文字コードShift_JISで発生する問題。

| コメント(6) | トラックバック(1)

Movable TypeをMySQL(5.x)で運用し、且つ文字コードShift_JISで運用しているケースで、「表,—,ソ,噂,欺,圭,構,蚕,十,申,貼,能,表,暴,予,禄,兔」等の文字で終わっているデータ(entry_textとかblog_nameとかとにかく文字列型のデータ)が保存できないことに気づいた。サポートにも確認したけど「文字コードとしてShift_JISを利用している際、文字データの2バイト目が「0x5c」となる文字を使用した場合に発生」「MySQLの文字コードの扱いに起因する問題」とのことで、MT側の実装では対処できないとのこと。

不思議なのは、「表示」では問題なく「試算表」では問題になること(複数サーバーで確認してますが、他の環境でどうかはわかりません)。

つまり「表」等で終わっている場合にアウトになる模様(「表 」のように最後に空白文字を追加してやると保存できる模様)。

対象法2つ

一つ目はDB上はUTF-8で運用し、ファイル出力時にShift_JISに変換する方法。

ということでプラグイン (ダイナミックパブリッシングには対応しないけど) 。

ShiftJIS.pl(出力文字コードをShiftJISに、<$MTPublishCharset$>タグの出力を強制的に「Shift_JIS」にするプラグイン

もうひとつは(美しくはなく且つ強引なやり方だが)、無理矢理「0x5c」で終わる文字列を保存する際に末尾に空白文字を追加する。プラグインですべてのオブジェクトに対して処理するのは...ちょっと思いつかなかった。

手を入れるのは、lib/MT/Object.pm の892行目付近

オリジナル


sub set_values {
    my $obj = shift;
    my ($values) = @_;
    for my $col (keys %$values) {
        unless ( $obj->has_column($col) ) {
            Carp::croak("You tried to set inexistent column $col to value $values->{$col} on " . ref($obj));
        }
        $obj->$col($values->{$col}) if defined $values->{$col};
    }
}

修正後


sub set_values {
    my $obj = shift;
    my ($values) = @_;
    for my $col (keys %$values) {
        unless ( $obj->has_column($col) ) {
            Carp::croak("You tried to set inexistent column $col to value $values->{$col} on " . ref($obj));
        }
        my $str = $values->{$col};
        $str .= " " if (check5c($str));
        $obj->$col($str) if defined $str;
    }
}

sub check5c {
    my $str = shift || return(undef);
    my $format = '%X';
    $str =~ s/(.)/sprintf($format, ord($1))/eg;
    if ($str =~ /5C$/) {
    	return 1;
    } else {
        return 0;
    }
}

きれいな解決法あったら誰か教えてくださいな。

トラックバック(1)

トラックバックURL: http://junnama.alfasado.net/cgi/mt/mt-tb.cgi/95

Movable TypeをMySQLで運用している際に文字コードShift_JI... 続きを読む

コメント(6)

私の環境ではうまく問題が再現できません。

それはともかくとして、1つ目の方法について疑問があります。PublishCharsetはUTF-8であるという前提ですよね。さて、ShiftJISで出力されたページにコメントフォームがあったとします。その入力文字列はShiftJISで渡されますよね。そのShiftJIS文字列は、常にUTF-8に変換されてDBに格納されることが保証されるでしょうか。

>そのShiftJIS文字列は、常にUTF-8に変換されてDBに格納されることが保証されるでしょうか。

されないですね(CMS用途頭になってますね>自分)。コメントやトラックバックを考慮すると出力文字コード変えるだけでは確かに不十分だと思います。

DBの入出力はUTF-8、画面や再構築の入出力は指定されたエンコーディングにできれば(というかそれを前提にMTが実装されていれば)、問題がなくなるのでないかと前から思っていました。例えば、Google検索などはユーザが選択できますよね。
http://www.google.co.jp/search?hl=ja&q=MT&oe=ShiftJIS

変換オーバーヘッドが馬鹿にならないのかな…。

>DBの入出力はUTF-8、画面や再構築の入出力は指定されたエンコーディングにできれば(というかそれを前提にMTが実装されていれば)、問題がなくなるのでないかと前から思っていました

それ、私もそう思っていました(というか、暫く前までそうなってると勘違いしていしてた)。

>変換オーバーヘッドが馬鹿にならないのかな…。

馬鹿にならないでしょうねぇ。全再構築とかダイナミックパブリッシングとか...でもCMSの方はUTF-8で書かれたものを変換してるので、そっちの負担はなくなりますね。

mt-config.cgiに以下の行を追加すればSJISでエラーになるのを解決できませんか?

SQLSetNames 1

MySQLでShift_JISする場合、結構難しいですよね。
MySQLのバージョンによっても動きが変わります。
僕は二度と使いません。
↑なんじゃこのコメント

コメントする

Facebook

Twitter

このブログ記事について

このページは、Junnama Nodaが2008年4月18日 16:53に書いたブログ記事です。

ひとつ前のブログ記事は「携帯サイト+らくらくホンがウェブアクセシビリティを考える上での大きなヒントとなる。」です。

次のブログ記事は「リスト系アーカイブの静的ファイルを分割するMT Pagerプラグイン(修正)。」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 6.2.6