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つ目の方法について疑問があります。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のバージョンによっても動きが変わります。
僕は二度と使いません。
↑なんじゃこのコメント