ID-Blogger

PHP+MySQL+UTF-8で文字化け回避

なんだかんだとWebの世界もグローバル化の波を受けて、「これからの文字コードはUTF-8が標準ですよ!」と言わんばかりに突き進んでいるような気がします。UTF-8だと日本が3バイト扱いになってデータ容量が1.5倍になってしまうデメリットもありますが、Google系API関係やMovableTypeをはじめとした海外産にこれだけ囲まれるようになってくると、Webサイトの構築時には初期段階からUTF-8で制作した方が親和性が高いようです。
という事で弊社でも文字コードはUTF-8で構築してみたのですが、PHPを絡めて制作すると文字化けするという問題が発生しました。

例えばこんなカンジでフォームの内容をPHPで受けるようなページを制作したとします。

この記事は2006年時点でのPHP4の場合での内容になります。ご注意ください。


<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="ja" />
<title>PHP送信テスト</title>
</head>
<body>
<? echo $_POST['aaaa']; ?>
<form action="" method="post">
送信テスト<input name="aaaa" type="text" value="" /><input type="submit" value="送信" />
</form>
</body>
</html>

送信ボタンを押すとフォームの内容がそのまま表示されるワケですが、UTF-8ベースのXHTMLでPHPを絡めてあると、日本語を入力した際に吐き出されるデータが「???????」という風に化けてしまうのです。

ググってみると同じようにこの問題にぶつかった方は結構多いみたいですね。原因はサーバで扱うPHPの内部処理の文字コードが、元々EUCをベースである事に起因している様です。
回避方法はPHPのフォーム情報の受け取り部分の前に以下のように追記して、

<?
mb_language("uni"); //<--追加
mb_internal_encoding("utf-8"); //<--追加
mb_http_input("auto"); //<--追加
mb_http_output("utf-8"); //<--追加
echo $_POST['aaaa'];
?>
内部処理の文字コードをUTF-8に変更してから受け取る様にしてあげればよいようです。


さらに今回制作したWebサイトではMySQLデータベースも併用していたので、コチラもUTF-8に対応するように変更します。
照合順序の文字セットを「utf8-unicode-ci」で選択しておけば間違いないようです。後々面倒になりますので、データベースの構築前に設定しておくことをオススメいたします。MySQLの管理は「PHPMyAdmin」で行いましたのであしからずw

PHPからMySQLに接続する際にはこんなカンジで別ファイルに書いておいてrequire文で呼び出したりすると思います。接続前にUTF-8を使ってますよと宣言しておきましょう。

<?
mb_language("uni");
mb_internal_encoding("utf-8");
mb_http_input("auto");
mb_http_output("utf-8");
$db=mysql_connect("DB鯖","接続ID","接続パスワード");
mysql_query("SET NAMES utf8",$db);
mysql_select_db("DB名");
?>
ちなみに"\"とか"〜"とか入力するとデータベース上ではやっぱり「??????」と文字化けしちゃってますが、取り出して出力するとちゃんと表示されるのであまり気にしない方向でm(_ _)m

概ねこんな所で回避できると思いますので、文字化けで悩んだ方は参考にしてください♪

トラックバック(1)

過去のトラブルシューティングでも「PHP+MySQLで日本語文字化けへの対処」と「PHP+MySQL+UTF-8で文字化け回避」のエントリでPHP関連の文... 続きを読む

コメント(5)

役立ちました。感謝です。

わーん
助かりましたー(泣)
ありがとうございます!!

ご苦労様です!

1週間悩んだ内容が一瞬で解決しました!
ありがとうございました!

??の文字がでてきました。
ありがとうございました。

小耳にはさんだ話ですが、
>mysql_query("SET NAMES utf8",$db);
より
>mysqli_set_charset($db, "utf8");
の方が安全のようですよ。

下記のブログ参照。
http://saboten009.blogspot.com/2008/01/phpmysqlutf-8.html

ただ、私のサーバはmysqli_set_charsetに対応してませんでしたが。。。

>なべさん
コメントありがとうございます。
この記事自体が2006年と現時点(2010年)から約4年前の内容になりPHP4を基準に書いてあります。
mysqli_set_charsetはサーバーがPHP5に対応してないと使えないんですよね…

PHP5の方はなべさんのくれたリンク先を参考にしていただいた方が良いかと思います。コメントを入力してください。