アルファサード株式会社 代表取締役 野田 純生のブログ


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


公開日 : 2008-04-18 16:53:06


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;
    }
}

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

カテゴリ


このブログを書いている人
野田純生の写真
野田 純生 (のだ すみお)

大阪府出身。ウェブアクセシビリティエバンジェリスト。 アルファサード株式会社の創業者であり、現役のプログラマ。経営理念は「テクノロジーによって顧客とパートナーに寄り添い、ウェブを良くする」。 プロフィール詳細へ