任务
我希望获取具有重音字符的行。列(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,但如果可以避免,我宁愿不这样做。
答案 0 :(得分:38)
// 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);
答案 1 :(得分:11)
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的第一步。
答案 2 :(得分:5)
我的解决方案是在mysql_query('SET CHARACTER SET utf8');
之前插入此行SELECT
。
这种方法很好。
答案 3 :(得分:4)
似乎不应该把它放在查询中,而应该放在:
mysql_set_charset('utf8');
在mysql连接语句之后。
答案 4 :(得分:1)
在您的连接中: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);
...
希望有所帮助。
答案 5 :(得分:0)
在iconv_r($row,"LATIN1","UTF-8//TRANSLIT");
结果之前尝试json_encode()
(下面的功能)。
我有UTF-8作为表编码和结果集编码,但有时人们仍然设法通过表单提交非UTF-8字符,跟踪每个输入源很麻烦,所以我也包裹了{ {1}}使其更安全。特别是我在它上面有一个NULL字符串,包含度数符号和“智能引号”,英国人似乎非常喜欢。
json_encode()