phpMyAdminを用いてデータベース上のレコードをエクスポートする際、レコードに日本語が含まれると文字化けして正しくエクスポートできない!というのを経験された方は多いのではないでしょうか。
多くの方は、phpMyAdminからエクスポートしてファイルとして保存した後に、保存したファイルをテキストエディタ等で開き、文字コードをSJISやその他希望する文字コードに変換してさらに保存することで、参照可能にされていると思います。
私もその一人でした。UTF-8のレコードをSJIS指定でエクスポートしても、UTF-8のまま出力されてしまうのです。SQL実行画面では正しく日本語が見えるのに、なぜかエクスポートして保存したファイルは文字化けしているんですよね。
今回、最近PHPに関する知識と興味が増えているので、なぜユーザーが指定する文字コードで変換されないのかを調べてみることにしました。長くなるといけないので、今回はシンプルに原因と修正方法をできるだけわかりやすく記述したいと思います。
原因
エクスポート時に選択できる「エンコーディングへの変換」で選択した項目が正しく処理対象として認識されていないから
2014.02.03追記
本記事の下部にありますとおり、バグ報告した結果4.1.7からは修正されるようになりました!
bug #4263 Japanese character encoding not working properly when exportin… · ceecaa4 · phpmyadmin/phpmyadmin · GitHub
修正方法
これでなおります!
phpMyAdminに含まれる「export.php」に1行追加します。
変更前:
35 /** 36 * Sets globals from $_POST 37 * 38 * - Please keep the parameters in order of their appearance in the form 39 * - Some of these parameters are not used, as the code below directly 40 * verifies from the superglobal $_POST or $_REQUEST 41 */ 42 $post_params = array( 43 'db', 44 'table', 45 'single_table',
変更後:
35 /**
36 * Sets globals from $_POST
37 *
38 * - Please keep the parameters in order of their appearance in the form
39 * - Some of these parameters are not used, as the code below directly
40 * verifies from the superglobal $_POST or $_REQUEST
41 */
42 $post_params = array(
43 'knjenc',
44 'db',
45 'table',
46 'single_table',
これで修正は完了です。
今一度phpMyAdminからエクスポートをしてみてください(^^)
以下は少し興味がある方へ
knjencってなに?
エクスポートを行う画面のHTMLソースをブラウザから確認するとわかるのですが、ここでの選択項目は「knjenc」というnameでexport.phpに渡されています。
<form method="post" action="export.php" name="dump"> ~省略~ <div class="exportoptions" id="kanji_encoding"><h3>エンコーディングへの変換:</h3> <ul> <li> <input type="radio" name="knjenc" value="" checked="checked" id="kj-none"><label for="kj-none">なし</label> <input type="radio" name="knjenc" value="EUC-JP" id="kj-euc"><label for="kj-euc">EUC</label> <input type="radio" name="knjenc" value="SJIS" id="kj-sjis"><label for="kj-sjis">SJIS</label> </li> <li> <input type="checkbox" name="xkana" value="kana" id="kj-kana"> <label for="kj-kana">全角カナへ変換する</label><br> </li> </ul></div>
export.phpでPOSTされてきた値を取り出す際に利用されているname一覧が$post_paramsで指定されておりますが、ここにknjencが含まれないのでせっかく搭載されている変換機能が有効にならずに、そのままエクスポートされてしまっているわけです。
以下はわかる人だけ用
配列$post_paramsに含まれるものを使って配列$_POSTに含まれているものに限り配列$GLOBALSに収めています。
144 foreach ($post_params as $one_post_param) { 145 if (isset($_POST[$one_post_param])) { 146 $GLOBALS[$one_post_param] = $_POST[$one_post_param]; 147 } 148 }
上記で配列$GLOBALSに収められているべきである $GLOBALS[‘knjenc’] を使って文字変換を行っています。
332 // Kanji encoding convert feature 333 if ($GLOBALS['output_kanji_conversion']) { 334 $line = PMA_Kanji_strConv( 335 $line, 336 $GLOBALS['knjenc'], 337 isset($GLOBALS['xkana']) ? $GLOBALS['xkana'] : '' 338 ); 339 }
ファンクション「PMA_Kanji_strConv」は libraries/kanji-encoding.lib.php に記述があるファンクションです。
69 * @param string $str the string to convert 70 * @param string $enc the destination encoding code 71 * @param string $kana set 'kana' convert to JIS-X208-kana 72 * 73 * @global string $kanji_encoding_list the available encoding codes list 74 * 75 * @return string the converted string 76 */ 77 function PMA_Kanji_strConv($str, $enc, $kana) 78 { 79 global $kanji_encoding_list; 80 81 if ($enc == '' && $kana == '') { 82 return $str; 83 } 84 $string_encoding = mb_detect_encoding($str, $kanji_encoding_list); 85 86 if ($kana == 'kana') { 87 $dist = mb_convert_kana($str, 'KV', $string_encoding); 88 $str = $dist; 89 } 90 if ($string_encoding != $enc && $enc != '') { 91 $dist = mb_convert_encoding($str, $enc, $string_encoding); 92 } else { 93 $dist = $str; 94 } 95 return $dist; 96 } // end of the 'PMA_Kanji_strConv' function
ということで、phpMyAdminでエクスポートする際に指定する文字コードは「mb_convert_encoding」を用いて文字変換を行うのに必要とされる要素なのですが、選択した文字コードをexport.phpに渡すときに利用しているname「knjenc」がexport.phpに受け取ってもらえていないというのが原因のまとめになります。
export.phpに正しく認識させるためには、配列「$post_params」へ「knjenc」を追加してあげます。
一応phpMyAdminへバグの報告を行っておきましたので、近い将来修正されるかもしれませんが、それまでは手動で変更してがんばりましょう!
コメント
nginxでphpmyadminいれてましたけど、色々いじっていたらおかしくなって面倒でけしましたw
くりくりさん
phpmyadminって、いままでの意識だと「脆弱性がたくさんあるし利用頻度が少ないからいらない」
でしたけど、自分以外の一般人がDBから情報を引き出すときなどには便利と思っています。
SQL文だけ教えてあげれば、phpmyadminからログインして実行するってのも簡単ですからね。
ちなみに、個人用のこのサーバーには無論phpmyadminは入れていません。
こんにちは
>自分以外の一般人がDBから情報を引き出すときなどには便利と思っています。
会社でwordpressを増やした時、データベースのメンテナンスをサイト管理者にまかせようとしてwordpressのプラグインや
phpmyadminを導入しようかなと話ししたんですが、お前がやれと一蹴されました(w
他のwebクリエイターをみてると御自分でやる方が多いのでそういう先入観がありました。
Web開発者側から見れば、クエリーが通ってるかとか、デバッグ用にテーブル作ったりとか出来たら便利なことはたくさんあるんですけどねぇ。
全部でなくても少しはサーバ側の知識あったほうが、Web開発は進めやすいと思います(^_^.)
こんなことになってたとは…参考になりました。