2012-10-23 7 views
6

これはおそらく単純なものです。私は答えをオンラインで探していて、見つけていないと誓っています。私の特定のケースは少し異型であるので、私は最終的にここで尋ねることにしました。PHPでMySQLからutf8mb4データを操作する

私は中国語のプログラムに使用しているいくつかのテーブルをMySQLに持っています。それは、偉大なフォントのサポートを持っていない珍しいものを含む、すべての可能な漢字をサポートすることができる必要があります。表中のサンプルセルは、このようになります。それは、データベースに右仕事を得るためには

東菄鶇䍶倲涷蝀凍鯟崠埬䰤

、私が持っていましたエンコード/照合をutf8mb4に設定します。ここまでは順調ですね。 ??私はPHPに同じ文字列を引っ張ったときに残念なことに、それはこのように印刷されます:?

東菄鶇䍶倲??涷蝀凍鯟崠埬䰤

私は最終的にどのように殺すことができます残りの疑問符を消して、それらをユニコードのグリフとして表示するようにしてください。私はタグでUTF8エンコーディングを使用し、メタタグとしてPHPページ自体を持っています。

なぜ彼らは互いに通信できませんか?私は間違って何をしていますか?

+0

データベース接続のエンコーディングを設定していますか?もしそうなら、どのように、そして何に?文字は実際にどこかに変換されているのか、それとも単なる表示の問題ですか?その文字列の 'bin2hex()'はPHPであなたに何を与えるのでしょうか? – deceze

答えて

15

私は単純に表をutf8mb4に設定していますが、接続エンコーディングはutf8に設定されていると思います。 utf8mb4に設定する必要があります。そうしないと、MySQLは格納されたutf8mb4データをutf8に変換します。後者は、「高」Unicode文字をエンコードできません。 (はい、それはMySQLの特異体質だ)

生MySQLの接続には、それはこのように見えることがあります:あなたは、クライアントの最善の方法にそれを適応させる必要があります

SET NAMES 'utf8mb4'; 
SELECT * FROM `my_table`; 

によってPHP(mysql、mysqli、またはPDO)からMySQLに接続する方法について説明します。本当に明確にする


(はい、簡略化のためmysql_拡張子を使用して、自宅でそれをしないでください):

mysql_connect(...); 
mysql_select_db(...); 
mysql_set_charset('utf8mb4');  // adapt to your mysql connector of choice 

$r = mysql_query('SELECT * FROM `my_table`'); 

var_dump(mysql_fetch_assoc($r)); // data will be UTF8 encoded 
+0

私はPHPからアクセスしていて、現在 'mb_internal_encoding( 'UTF-8');を使用しています;それは解決策に影響しますか? 'mb_internal_encoding( 'UTF-8MB4');というようなものがありますか? – Yhilan

+0

いいえ、 'mb_internal_encoding'は' mb_'関数の内部エンコーディングのみを設定します。これはMySQLとは関係ありません。あなたは通常のUTF-8をMySQLから取得し、 'utf8mb4'はMySQLの内部的なものです。 – deceze

+0

PHP内からSET NAMESを使用するにはどうすればよいですか?あるいは、私はこの間違いを犯して、何とかphpmyadminのようなものからそれを設定する必要がありますか? – Yhilan

2

だけの@ decezeの答えに追加するには、私はよく構成されたお勧めしますMySQLサーバ(私にとっては、/etc/mysql/mysql.conf.d/mysqld.cnf)。ここにはutfmb4を使用していることを確認するための設定オプションがありますが、私はすべてのMySQL設定オプションを実行することをお勧めしますが、それは難しいので、非常に最適ではないデフォルトがたくさんあります。

[client] 

default-character-set   = utf8mb4 

[mysql] 

default_character_set   = utf8mb4 

[mysqld] 

init-connect     = "SET NAMES utf8mb4" 
character-set-client-handshake = FALSE 
character-set-server   = "utf8mb4" 
collation-server    = "utf8mb4_unicode_ci" 
autocommit      = 1 
block_encryption_mode   = "aes-256-cbc" 

最後の1つはデフォルトにする必要があります。また、init-connectは毎回実行する必要はありません。コードをきれいに保ちます。今すぐ実行します。

SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%'; 

あなたは、次のようなものを返す必要があります:

+--------------------------+--------------------+ 
| Variable_name   | Value    | 
+--------------------------+--------------------+ 
| character_set_client  | utf8mb4   | 
| character_set_connection | utf8mb4   | 
| character_set_database | utf8mb4   | 
| character_set_filesystem | binary    | 
| character_set_results | utf8mb4   | 
| character_set_server  | utf8mb4   | 
| character_set_system  | utf8    | 
| collation_connection  | utf8mb4_unicode_ci | 
| collation_database  | utf8mb4_unicode_ci | 
| collation_server   | utf8mb4_unicode_ci | 
+--------------------------+--------------------+ 

そして、あなたはすでにこれをやっているが、明示的にテーブルの作成に定義するために悪くはないように見えます:

CREATE TABLE `mysql_table` (
    `mysql_column` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`mysql_column`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 

これは誰かを助けることを願っています。

+0

設定ファイルを変更した後、 'service mysqld start'または' /etc/init.d/mysqld restart'でmysqlを再起動することを忘れないでください。 – salvob

+1

同じ名前の設定がハイフンやアンダースコア、引用符で囲まれているのはなぜですか?引用符なし? –

+0

私は遅れているので?編集済み(ありがとう!) – Eugene

関連する問題