データベースについてよく受ける相談、
- データが入らない。
- 番号の列しか保存されない。
- 日本語の部分が消えた。
など、ファイル側とデータベースの文字コードの違いによって日本語部分が保存されない問題について。
文字コードをわざわざ別々にする必要性・目的が明確にないならシステム内の文字コードは揃えるべき、という観点から文字コードを揃えるという解説が基本ですが、そうではないほうのパターンを紹介します。
保存時
日本語が消えてしまう現象は、保存できないから消去されるという形で、この場合、データベース内にも保存されていません。
文字列を書き換えたり比較したりする処理がすべて終わってから、書き込み処理のすぐ手前で、mb_convert_encoding関数を使い、現状の文字コード→データベースの文字コードに変換しましょう。
mb_conbert_engodingの引数は「データ、変換後の文字コード、変換前の文字コード」の順です。
// ここまでに、$in_nameという変数に日本語を含む名前を、 // $ageには整数の年齢を入れている。 $in_name = mb_convert_encoding($in_name, 'utf8','sjis');// 変換処理 $sql = "INSERT INTO `sample_users` (`name`, `age`) VALUES(:name, :age)"; $stmt = $pdo->prepare($sql); $stmt->bindValue(':name', $in_name, PDO::PARAM_STR); $stmt->bindValue(':age', $in_age, PDO::PARAM_INT); $stmt->execute();
当然ではありますが、検索する場合も、「MySQLが比較する」ので、変換した結果同士で比較できるよう、変換して送る必要があります。
表示時
保存ができても、そのままでは「UTF-8用のデータ」として保存されているので、出力結果は文字化けしてしまいます。
配列として取得したすぐ後のタイミングで、mb_convert_variables関数でまとめて、データベースの文字コード→ファイルの文字コードに変換すると良いでしょう。
こちらは引数の順番が「変換後の文字コード、変換前の文字コード、データ」の順であることに注意が必要です。また、元の配列の文字コードが変換されるため、結果を入れる書き方ではありません。
//ここまでに接続 $sql = "SELECT * FROM `sample_users`"; $table_data = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC); mb_convert_variables('sjis', "UTF-8", $table_data);// 変換処理 //この後で$table_dataの中身を出力