This question already has an answer here:
这个问题已经有了答案:
- UTF-8 all the way through 14 answers
- UTF-8一直到14个答案。
Quest
追求
I am looking to fetch rows that have accented characters. The encoding for the column (NAME
) is latin1_swedish_ci
.
我正在寻找具有重音字符的行。列(名称)的编码是latin1_swedish_ci。
The Code
的代码
The following query returns Abord â Plouffe
using phpMyAdmin:
下面的查询使用phpMyAdmin返回一个Plouffe:
SELECT C.NAME FROM CITY C
WHERE C.REGION_ID=10 AND C.NAME_LOWERCASE LIKE '%abor%'
ORDER BY C.NAME LIMIT 30
The following displays expected values (function is called db_fetch_all( $result )
):
下面显示期望值(函数名为db_fetch_all($result)):
while( $row = mysql_fetch_assoc( $result ) ) {
foreach( $row as $value ) {
echo $value . " ";
$value = utf8_encode( $value );
echo $value . " ";
}
$r[] = $row;
}
The displayed values: 5482 5482 Abord â Plouffe Abord â Plouffe
显示的值:5482 5482的各大剧院巡回演出¢Plouffe Plouffe各大剧院巡回演出
The array is then encoded using json_encode
:
然后使用json_encode对数组进行编码:
$rows = db_fetch_all( $result );
echo json_encode( $rows );
Problem
问题
The web browser receives the following value:
web浏览器接收以下值:
{"ID":"5482","NAME":null}
Instead of:
而不是:
{"ID":"5482","NAME":"Abord â Plouffe"}
(Or the encoded equivalent.)
编码(或等效)。
Question
问题
The documentation states that json_encode()
works on UTF-8. I can see the values being encoded from LATIN1 to UTF-8. After the call to json_encode()
, however, the value becomes null
.
文档说明json_encode()在UTF-8上工作。我可以看到从LATIN1到UTF-8编码的值。然而,在调用json_encode()之后,该值将变为null。
How do I make json_encode()
encode the UTF-8 values properly?
如何使json_encode()正确地编码UTF-8值?
One possible solution is to use the Zend Framework, but I'd rather not if it can be avoided.
一种可能的解决方案是使用Zend框架,但如果可以避免的话,我宁愿不使用Zend框架。
6 个解决方案
#1
37
// 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
10
foreach( $row as $value ) {
$value = utf8_encode( $value );
You're not actually writing your encoded value back into the $row
array there, you're only changing the local variable $value
. If you want to write back when you change the variable, you would need to treat it as a reference:
实际上,你并没有把编码后的值写回$row数组中,你只是改变了局部变量$value。如果您想在更改变量时回写,则需要将其作为参考:
foreach( $row as &$value ) {
Personally I would try to avoid references where possible, and for this case instead use array_map
as posted by Kemo.
就我个人而言,我尽量避免在可能的情况下使用引用,而在本例中,我将使用由Kemo发布的array_map。
Or mysql_set_charset
to UTF-8 to get the return values in UTF-8 regardless of the actual table collations, as a first step towards migrating the app to UTF-8.
或者mysql_set_charset到UTF-8以获取UTF-8中的返回值,而不考虑实际的表排序,这是将应用程序迁移到UTF-8的第一步。
#3
5
My solution is insert this line mysql_query('SET CHARACTER SET utf8');
, before the SELECT
. This method is good.
我的解决方案是插入这行mysql_query(“设置字符集utf8”);这个方法很好。
#4
4
It seems that rather than putting it in a query, one should put:
似乎与其将其放入查询中,还不如将其放入:
mysql_set_charset('utf8');
after the mysql connect statement.
在mysql连接语句之后。
#5
1
In your connect: mysql_set_charset('utf8', $link);
在您的connect中:mysql_set_charset('utf8', $link);
Example:
例子:
<?php
$link = mysql_connect('localhost', 'your_user', 'your_password');
mysql_set_charset('utf8', $link);
$db_selected = mysql_select_db('your_db', $link);
...
Hope that helps somewhat.
希望有所帮助。
#6
0
Try iconv_r($row,"LATIN1","UTF-8//TRANSLIT");
(function below) before you json_encode()
your result.
尝试iconv_r(美元行,“LATIN1”中的一个,“utf - 8 / / TRANSLIT”);在json_encode()结果之前。
I have UTF-8 as the table encoding and as the result set encoding, but sometimes folks still manage to submit non-UTF-8 characters via forms and it's troublesome to track down every single input source so I have also wrapped json_encode()
to make it safer. In particular I've had it NULL strings on me containing the degree symbol and "smart quotes" which folks in the UK seem so fond of.
我有UTF-8作为表编码和结果集编码,但有时人们仍然设法通过表单提交非UTF-8字符,并且很难跟踪每一个输入源,所以我还封装了json_encode()以使它更安全。特别是,我已经有了它的空字符串,包含了学位符号和“智能报价”,在英国,人们似乎很喜欢它。
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);
}
}
}
}
#1
37
// 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
10
foreach( $row as $value ) {
$value = utf8_encode( $value );
You're not actually writing your encoded value back into the $row
array there, you're only changing the local variable $value
. If you want to write back when you change the variable, you would need to treat it as a reference:
实际上,你并没有把编码后的值写回$row数组中,你只是改变了局部变量$value。如果您想在更改变量时回写,则需要将其作为参考:
foreach( $row as &$value ) {
Personally I would try to avoid references where possible, and for this case instead use array_map
as posted by Kemo.
就我个人而言,我尽量避免在可能的情况下使用引用,而在本例中,我将使用由Kemo发布的array_map。
Or mysql_set_charset
to UTF-8 to get the return values in UTF-8 regardless of the actual table collations, as a first step towards migrating the app to UTF-8.
或者mysql_set_charset到UTF-8以获取UTF-8中的返回值,而不考虑实际的表排序,这是将应用程序迁移到UTF-8的第一步。
#3
5
My solution is insert this line mysql_query('SET CHARACTER SET utf8');
, before the SELECT
. This method is good.
我的解决方案是插入这行mysql_query(“设置字符集utf8”);这个方法很好。
#4
4
It seems that rather than putting it in a query, one should put:
似乎与其将其放入查询中,还不如将其放入:
mysql_set_charset('utf8');
after the mysql connect statement.
在mysql连接语句之后。
#5
1
In your connect: mysql_set_charset('utf8', $link);
在您的connect中:mysql_set_charset('utf8', $link);
Example:
例子:
<?php
$link = mysql_connect('localhost', 'your_user', 'your_password');
mysql_set_charset('utf8', $link);
$db_selected = mysql_select_db('your_db', $link);
...
Hope that helps somewhat.
希望有所帮助。
#6
0
Try iconv_r($row,"LATIN1","UTF-8//TRANSLIT");
(function below) before you json_encode()
your result.
尝试iconv_r(美元行,“LATIN1”中的一个,“utf - 8 / / TRANSLIT”);在json_encode()结果之前。
I have UTF-8 as the table encoding and as the result set encoding, but sometimes folks still manage to submit non-UTF-8 characters via forms and it's troublesome to track down every single input source so I have also wrapped json_encode()
to make it safer. In particular I've had it NULL strings on me containing the degree symbol and "smart quotes" which folks in the UK seem so fond of.
我有UTF-8作为表编码和结果集编码,但有时人们仍然设法通过表单提交非UTF-8字符,并且很难跟踪每一个输入源,所以我还封装了json_encode()以使它更安全。特别是,我已经有了它的空字符串,包含了学位符号和“智能报价”,在英国,人们似乎很喜欢它。
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);
}
}
}
}