スタッフブログ
XOOPS Cube Legacy2.1系の初期の頃は、日本語文字コードEUC-JPがデフォルトでした。
今ではUTF-8を使うことが主流になってきているため、お客様から文字コードEUC-JPで構築したXOOPS CubeサイトをUTF-8化するご依頼を受けることが度々あります。
そんな文字コード変換中に、メールフォームモジュールのLiaiseではまったことがあります。
通常文字コード変換するときは、DBデータをダンプして、ダンプファイルの文字コードを変換してインポートする程度で済むのですが、Liaiseはこれだけではすみませんでした。
■原因はserialize
Liaiseではフォーム要素のデータをPHPのserialize関数を使って変換してDBに保存していました。
serialize関数を使うと配列やオブジェクトを文字列にしてくれるので、項目数が増減する値をDBカラムに保存するときなどに便利に使うことがあります。
この文字列にする過程で、変数内のも文字列のバイト数も書き出されます。
このバイト数が、EUC-JPとUTF-8で異なるため、EUC-JPでserializeされた値をUTF-8でunserializeしても元にもどせなくなっていました。
■EUC-JPでunserializeしてUTF-8でserializeしなおす
そこで、インポートしたDBからEUC-JPでunserializeしてUTF-8でserializeしなおして保存しなおすプログラムを書いて対処しました。
下記を書いたファイルをXOOPS_ROOT_PATH直下へ配置してアクセスするだけで、Liaiseのフォーム要素をEUC-JPでunserializeしてUTF-8でserializeしなおします。
今ではUTF-8を使うことが主流になってきているため、お客様から文字コードEUC-JPで構築したXOOPS CubeサイトをUTF-8化するご依頼を受けることが度々あります。
そんな文字コード変換中に、メールフォームモジュールのLiaiseではまったことがあります。
通常文字コード変換するときは、DBデータをダンプして、ダンプファイルの文字コードを変換してインポートする程度で済むのですが、Liaiseはこれだけではすみませんでした。
■原因はserialize
Liaiseではフォーム要素のデータをPHPのserialize関数を使って変換してDBに保存していました。
serialize関数を使うと配列やオブジェクトを文字列にしてくれるので、項目数が増減する値をDBカラムに保存するときなどに便利に使うことがあります。
この文字列にする過程で、変数内のも文字列のバイト数も書き出されます。
このバイト数が、EUC-JPとUTF-8で異なるため、EUC-JPでserializeされた値をUTF-8でunserializeしても元にもどせなくなっていました。
■EUC-JPでunserializeしてUTF-8でserializeしなおす
そこで、インポートしたDBからEUC-JPでunserializeしてUTF-8でserializeしなおして保存しなおすプログラムを書いて対処しました。
下記を書いたファイルをXOOPS_ROOT_PATH直下へ配置してアクセスするだけで、Liaiseのフォーム要素をEUC-JPでunserializeしてUTF-8でserializeしなおします。
<?php
require 'mainfile.php';
$sql = sprintf("SELECT * FROM %s ", $xoopsDB->prefix('liaise_formelements');
$result = $xoopsDB->query($sql);
while($row = $xoopsDB->fetchArray($result)){
$ele_value = reserialize($row['ele_value']);
$sql = sprintf("UPDATE %s SET ele_value=%s WHERE ele_id=%d",
$xoopsDB->prefix('liaise_formelements'),
$xoopsDB->quoteString($ele_value),
$row['ele_id']
);
$xoopsDB->queryF($sql);
}
function reserialize($str)
{
$s = $str
$euc = mb_convert_encoding($s, 'EUC-JP', 'UTF-8');
mb_internal_encoding('EUC-JP');
$un = unserialize($euc);
// var_dump($un);
mb_internal_encoding('UTF-8');
array_walk($un, 'c');
$seri = serialize($un);
// var_dump($seri);
return $seri;
}
function c(&$var, $key){
$var = mb_convert_encoding($var, 'UTF-8', 'EUC-JP');
}