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;
}
}
きれいな解決法あったら誰か教えてくださいな。