PDO查询返回许多\ uXXXX字符代码,我无法将其转换为unicode字符

时间:2013-05-16 09:39:34

标签: php json unicode utf-8 pdo

我有一个MySQL数据库表,我在其中存储不同语言的国家/地区名称,我无法以unicode字符显示数据 - 我只能在特殊字符所在的位置显示\ uXXXX代码。

该查询用于AJAX请求,结果编码为JSON对象。

这是表格(截断):

CREATE TABLE IF NOT EXISTS `tbl_countries` (
  `ccode` varchar(2) character set utf8 collate utf8_unicode_ci NOT NULL default '',
  `country_en` varchar(100) character set utf8 collate utf8_unicode_ci NOT NULL default '',
  `country_fr` varchar(100) character set utf8 collate utf8_unicode_ci NOT NULL,
  `country_de` varchar(100) character set utf8 collate utf8_unicode_ci NOT NULL,
  `country_es` varchar(100) character set utf8 collate utf8_unicode_ci NOT NULL,
  `country_ru` varchar(100) character set utf8 collate utf8_unicode_ci NOT NULL,
  `country_tr` varchar(100) character set utf8 collate utf8_unicode_ci NOT NULL,
  `country_ar` varchar(100) character set utf8 collate utf8_unicode_ci NOT NULL,
  PRIMARY KEY  (`ccode`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Dumping data for table `tbl_countries`
--

INSERT INTO `tbl_countries` (`ccode`, `country_en`, `country_fr`, `country_de`, `country_es`, `country_ru`, `country_tr`, `country_ar`) VALUES
('AF', 'Afghanistan', 'Afghanistan', 'Afghanistan', 'Afganistán', 'Афганистан', 'Afganistan', 'أفغانستان'),
('AX', 'Aland Islands', 'Îles Åland', 'Alandinseln', 'Islas Åland', 'Аландские острова', 'Aland Adaları', 'جزر أولان'),
('AL', 'Albania', 'Albanie', 'Albanien', 'Albania', 'Албания', 'Arnavutluk', 'ألبانيا'),
('DZ', 'Algeria', 'Algérie', 'Algerien', 'Argelia', 'Алжир', 'Cezayir', 'الجزائر'),
('AS', 'American Samoa', 'Samoa américaines', 'Amerikanisch-Samoa', 'Samoa Americana', 'Американское Самоа', 'Amerikan Samoası', 'ساموا الأمريكية');

这是创建PDO的代码:

$conn = new PDO("mysql:host=$dbhost;dbname=$dbname",
    $dbuser,
    $dbpass,
    array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")
);

$return_arr = array ();

if ($conn) {
    $ac_term = $_GET['term'];
    $query = "SELECT * FROM `tbl_countries` WHERE `country_en` LIKE :term";
    $result = $conn->prepare ($query);
    $result->bindValue (":term", "%".$ac_term."%");
    $result->execute ();

    /* Retrieve and store in array the results of the query.*/
    while ($row = $result->fetch (PDO::FETCH_ASSOC)) {
        $row_array['country_en'] = $row['country_en'];
        $row_array['country_de'] = $row['country_de'];
        $row_array['country_es'] = $row['country_es'];
        $row_array['country_fr'] = $row['country_fr'];
        $row_array['country_ru'] = $row['country_ru'];
        $row_array['country_tr'] = $row['country_tr'];
        $row_array['country_ar'] = $row['country_ar'];
        $row_array['ccode'] = $row['ccode'];
        array_push ($return_arr, $row_array);
    }
}

unset ($conn);

echo json_encode ($return_arr);

在PHP脚本的开头是以下行:

header('Content-Type: text/html; charset=utf-8');

这是我输入搜索字词united%20king时获得的典型输出:

[{
   "country_en":"United Kingdom",
   "country_de":"Vereinigtes K\u00f6nigreich",
   "country_es":"Reino Unido",
   "country_fr":"Royaume-Uni",
   "country_ru":"\u0412\u0435\u043b\u0438\u043a\u043e\u0431\u0440\u0438\u0442\u0430\u043d\u0438\u044f",
   "country_tr":"Birle\u015fik Krall\u0131k",
   "country_ar":"\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629",
   "ccode":"GB"
}]

在PHP代码中,我尝试使用htmlentities,但显示了德语输出的特殊字符:

$row_array['country_de'] = htmlentities ($row['country_de'], ENT_QUOTES, "UTF-8");

我错过了什么?谢谢你的阅读。

2 个答案:

答案 0 :(得分:2)

它不是PDO,而是json_encode的常规行为。在现代PHP版本中,您可以将其关闭,但它不应该是一个问题。

我不知道为什么你想要回显原始json,但通常不打算直接回显到HTML,而是由一些JS代码使用。 JS可以对此编码进行排序。但是,为了减少数据量,可以使用5.4 JSON_UNESCAPED_UNICODE标志,。

另外,我建议您在提出问题之前先调试一下代码 如果要检查PDO的输出,请为PDO执行,而不是为json执行。验证程序执行的每一步,找到破坏数据的步骤。

答案 1 :(得分:2)

这是完全有效的 JSON ;这些转义序列是编码非ASCII字符的常规JSON方式。如果使用常规JSON解码器在客户端上对其进行解码,则最终会得到正确的字符。