【问题标题】:UTF-8 character encoding battles json_encode() [duplicate]UTF-8 字符编码之战 json_encode() [重复]
【发布时间】:2011-02-16 21:59:06
【问题描述】:

任务

我正在寻找具有重音字符的行。列 (NAME) 的编码是 latin1_swedish_ci

守则

以下查询使用 phpMyAdmin 返回Abord â Plouffe

SELECT C.NAME FROM CITY C
WHERE C.REGION_ID=10 AND C.NAME_LOWERCASE LIKE '%abor%'
ORDER BY C.NAME LIMIT 30

以下显示预期值(函数名为db_fetch_all( $result )):

  while( $row = mysql_fetch_assoc( $result ) ) {
    foreach( $row as $value ) {
      echo $value . " ";
      $value = utf8_encode( $value );
      echo $value . " ";
    }

    $r[] = $row;
  }

显示的值:5482 5482 Abord â Plouffe Abord â Plouffe

然后使用json_encode对数组进行编码:

$rows = db_fetch_all( $result );
echo json_encode( $rows );

问题

网络浏览器接收到以下值:

{"ID":"5482","NAME":null}

代替:

{"ID":"5482","NAME":"Abord â Plouffe"}

(或编码的等价物。)

问题

文档指出json_encode() 适用于 UTF-8。我可以看到从 LATIN1 编码为 UTF-8 的值。然而,在调用json_encode() 之后,值变为null

如何使json_encode() 正确编码 UTF-8 值?

一种可能的解决方案是使用Zend Framework,但如果可以避免,我宁愿不使用。

【问题讨论】:

    标签: php mysql ajax character-encoding json


    【解决方案1】:
    // Create an empty array for the encoded resultset
    $rows = array();
    
    // Loop over the db resultset and put encoded values into $rows
    while($row = mysql_fetch_assoc($result)) {
      $rows[] = array_map('utf8_encode', $row);
    }
    
    // Output $rows
    echo json_encode($rows);
    

    【讨论】:

      【解决方案2】:
      foreach( $row as $value ) {
        $value = utf8_encode( $value );
      

      您实际上并没有将编码值写回到那里的$row 数组中,您只是更改了局部变量$value。如果您想在更改变量时回写,则需要将其视为参考:

      foreach( $row as &$value ) {
      

      我个人会尽量避免引用,对于这种情况,请改用 Kemo 发布的array_map

      或将mysql_set_charset 转换为 UTF-8 以获取 UTF-8 格式的返回值,而不考虑实际的表排序规则,这是将应用程序迁移到 UTF-8 的第一步。

      【讨论】:

        【解决方案3】:

        我的解决方案是在SELECT 之前插入这一行mysql_query('SET CHARACTER SET utf8');。 这个方法不错。

        【讨论】:

          【解决方案4】:

          似乎与其将其放入查询中,不如将其放入:

          mysql_set_charset('utf8');
          

          在 mysql connect 语句之后。

          【讨论】:

            【解决方案5】:

            在您的连接中:mysql_set_charset('utf8', $link);

            例子:

            <?php
            $link = mysql_connect('localhost', 'your_user', 'your_password');
            mysql_set_charset('utf8', $link);
            $db_selected = mysql_select_db('your_db', $link);
            ...
            

            希望能有所帮助。

            【讨论】:

              【解决方案6】:

              在你json_encode()你的结果之前尝试iconv_r($row,"LATIN1","UTF-8//TRANSLIT");(下面的函数)。

              我将 UTF-8 作为表编码和结果集编码,但有时人们仍然设法通过表单提交非 UTF-8 字符,而且跟踪每个输入源很麻烦,所以我还包装了 @ 987654323@ 使其更安全。特别是我的 NULL 字符串包含英国人似乎非常喜欢的学位符号和“智能引号”。

              function safe_json_encode($mixed,$missing="TRANSLIT"){
                 $out=json_encode($mixed);
                 if ($err=  json_last_error()){
                    iconv_r("UTF-8","UTF-8//$missing",$mixed);
                    $out=json_encode($mixed);
                 }
                 return $out;
              }
              function iconv_r($charset_i, $charset_o, &$mixed) {
                 if (is_string($mixed)) {
                    $mixed = iconv($charset_i, $charset_o, $mixed);
                 } else {
                    if (is_object($mixed)){
                       $mixed = (array) $mixed;
                    }
                    if (is_array($mixed)){
                       foreach ($mixed as $key => &$value) {
                          iconv_r($charset_i, $charset_o, $value);
                       }
                    }
                 }
              }
              

              【讨论】:

                猜你喜欢
                • 2012-09-11
                • 2011-08-28
                • 2011-09-30
                • 1970-01-01
                • 1970-01-01
                • 2019-01-26
                • 1970-01-01
                • 2013-05-07
                • 1970-01-01
                相关资源
                最近更新 更多