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

Posted

技术标签:

【中文标题】PDO 查询返回许多我无法转换为 unicode 字符的 \\uXXXX 字符代码【英文标题】:PDO query returns lots of \uXXXX character codes which I can't convert to unicode charactersPDO 查询返回许多我无法转换为 unicode 字符的 \uXXXX 字符代码 【发布时间】:2013-05-11 03:22:53 【问题描述】:

我有一个 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");

我错过了什么?感谢阅读。

【问题讨论】:

听起来您正在阅读 latin1 页面上的 UTF8 数据。仔细检查您的 HTML 或 json 页面发送的标题。 见***.com/questions/2934563/…。也尝试运行SET CHARSET 'utf8',以防您的默认编码不是UTF8。 我在PHP文件开头使用header('Content-Type: text/html; charset=utf-8');来设置字符集。 感谢您的链接和建议 【参考方案1】:

这不是 PDO 而是 json_encode 的常规行为。在现代 PHP 版本中,您可以将其关闭,但无论哪种方式都应该不是问题。

我不知道你为什么要回显原始 json,但通常它不打算直接回显到 HTML 中,而是由一些 JS 代码使用。而 JS 可以将这种编码整理出来。但是为了减少数据量,由于可以使用5.4JSON_UNESCAPED_UNICODE标志,.

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

【讨论】:

感谢您的建议 - 显然是我缺乏理解导致了这种情况,并且 [不正确地] 将示例/教程中的内容散列在一起。 你说得对——现在看来我应该这样做了。 我一定提到过JS会处理这些符号的【参考方案2】:

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

【讨论】:

感谢您的解释 - 我将研究解码,或者完全摆脱 JSON 部分。

以上是关于PDO 查询返回许多我无法转换为 unicode 字符的 \uXXXX 字符代码的主要内容,如果未能解决你的问题,请参考以下文章

PDO LastInsertId 不返回任何内容

PHP PostgreSQL PDO 无法使用 LIKE 绑定参数

PDO 不从 mysql 查询返回结果

使用 TCHAR 时出错,无法转换为 wchar_t

PDO 准备和执行查询总是返回错误

PDO 调试 - 绑定后查看查询? [复制]