web-dev-qa-db-ja.com

MySQLがUTF-8を返すようにするにはどうすればよいですか?

PHPUnitを使用してPHPコードからのXML出力を検証していますが、文字エンコーディング MySQL で問題が発生しているようです。DOMDocumentから取得したエラーは次のとおりです。 :

_Input is not proper UTF-8, indicate encoding!
Bytes: 0xE9 0x20 0x42 0x65
_

正しいエンコードを使用するようにDOMDocumentを初期化します。

_$domDocument = new DOMDocument('1.0','UTF-8');
_

そして、mb_detect_encodingを使用してsaveXML()からの出力を確認すると、結果は TF-8 になります。

また、XMLの作成に使用されたすべての呼び出しを確認しました。検出されたすべてのcreateCDATASectionパラメーターでmb_detect_encodingを使用し、それらはすべてUTF-8またはASCIIのいずれかです(プレーンテキストノードはなく、すべてが- [〜#〜] cdata [〜#〜] ブロック)。

問題は「é」文字( ISO 8859-1 では0xE9)の使用に起因すると思います。その文字をXMLに追加する行は次のとおりです。

_$domDocument->createCDATASection($place->name);
_

そしてmb_detect_encoding($ place-> name)は私にUTF-8を与えます。

データ($ place-> name)は、MySQLデータベースから取得されます。このデータベースにはUTF-8文字セットがあります。

ここにいくつかのサンプルコードがあります:

_$query = sprintf('SELECT name FROM place where id = 1');
$result = mysql_query($query);
$result = mysql_fetch_assoc($result);


// -- Feeding UTF-8 data directly WORKS
$domDocument = new DOMDocument('1.0','UTF-8');
$rootNode = $domDocument->createElement('Response');
$rootNode->appendChild($domDocument->createCDATASection('Café Belga'));
$domDocument->appendChild($rootNode);

$matcher = array('tag' => 'Response');
self::assertTag($matcher, $domDocument->saveXML(), '', FALSE);

// -- Feeding UTF-8 data from the resultset FAILS
$domDocument = new DOMDocument('1.0','UTF-8');
$rootNode = $domDocument->createElement('Response');
$rootNode->appendChild($domDocument->createCDATASection($result['name']));
$domDocument->appendChild($rootNode);

$matcher = array('tag' => 'Response');
self::assertTag($matcher, $domDocument->saveXML(), '', FALSE);
_

PHPStormデバッガーでは、データベースからフェッチされた文字列は次のようになります。

カフェベルガ

それが問題の根源だと思います。 MySQLWorkbenchでは、文字列は正しいです:CaféBelga。

ただし、utf8_encode($result['name'])を使用すると、すべてが正常に機能します。

ウォッチウィンドウでもう1つ確認します。

mb_detect_encoding($result['name'])-> "UTF-8"

mb_detect_encoding(utf8_encode($result['name']))-> "UTF-8"

余談ですが、これらの16進値をコピーアンドペーストして、異なる文字セットにあるはずの文字を確認できるサイトはありますか?

17
Joris Mans

データベースへの接続を TF-8 として定義する必要があります。

// Set up your connection
$connection = mysql_connect('localhost', 'user', 'pw');
mysql_select_db('yourdb', $connection);
mysql_query("SET NAMES 'utf8'", $connection);

// Now you get UTF-8 encoded stuff
$query = sprintf('SELECT name FROM place where id = 1');
$result = mysql_query($query, $connection);
$result = mysql_fetch_assoc($result);
50
strauberry

バージョンPHP 5.5.0から使用する必要があります

mysqli_set_charset($connection,"utf8");
6
Eric Korolev