PHP中的array_key_exists和UTF-8

4
我有一个数据库,编码为 UTF-8,以支持多种语言。我认为我的应用程序中的所有内容都是UTF-8编码。
尽管如此,我在使用 array_key_exists 函数时遇到了问题。
以下是解决方案:
  1. 首先查询数据库:

SELECT name, value from TABLE

  1. 然后将结果填充到哈希映射表中:

$hashmap[ $row['name'] ] = $row['value']

但当 DB 中的名称包含像“é”这样的重音符号时,会返回 false:

$this->db->select('name');
$this->db->select('value');
$this->db->from('table');
$q = $this->db->get();
$res = $q->result_array();

    foreach ($res as $value) {
        $hashmap[$value['name']] = $value['value'];
    }

$key = 'name é'; // an ord here returns 233
array_key_exists($key, $hashmap) 

我不知道该怎么进一步处理,你遇到过这个问题吗?

我有一个性能要求。

谢谢你的帮助。


我自己尝试了一下,它可以工作。你能否使用var_dump函数检查$hashmap数组中是否包含namé键值? - SERPRO
2
如果éord值为233,那么它不是UTF-8。 - deceze
4个回答

3

如果来自数据库的数组键确实是UTF-8字符串,则其编码为UTF-8。显然,您的源代码文件未以UTF-8编码,我猜测它使用的是Latin-1编码。因此,在UTF-8字节序列和Latin-1字节序列之间进行比较是不成功的。将源代码文件保存为UTF-8格式,问题就可以解决了(请咨询您的文本编辑器)。


谢谢,但那不是一个好方法,我的所有文件都是UTF-8编码,在Eclipse中配置。 - Nicolas Thery
那么它应该可以工作。请给我展示两个字符串上的bin2hex,谢谢。 - deceze
1
这就是答案。后面的字符串,é 的编码是 c3a9,属于 UTF-8 编码。前面的字符串,é 的编码是 e9,属于 Latin-1 编码。 - deceze
你说得对,我错了。我在这个页面上看错了列:http://fr.wikipedia.org/wiki/UTF-8 - Nicolas Thery
显示剩余2条评论

1
但是当数据库中的名称包含像' é '这样的重音符号时,以下语句返回false: array_key_exists('namé', $hashmap)
唉,直到现在,PHP中的字符串并不是UTF-8编码的。我相信你必须自己进行编码:
<?php
array_key_exists(utf8_encode('namé'), $hashmap);

实际上,$key字符串是从数据库返回的。这个字符串肯定是UTF-8编码的,因为当我使用Ord()函数对字符进行编码时,得到的结果是233。但是在构建地图时,我会检查代码。 - Nicolas Thery
2
PHP 字符串是字节数组,本身并没有任何编码。如果源字符串是 UTF-8,则该字符串就是 UTF-8 编码的;如果不是,则不是。而 utf8_encode 函数则将 Latin-1 编码的字符串转换为 UTF-8 编码的字符串。 - deceze

0

代码:

<?php
$foo = array('namé' => 1);
var_dump($foo);
var_dump(array_key_exists('namé', $foo));
var_dump(isset($foo['namé']));

输出:

array(1) {
  ["namé"]=>
  int(1)
}
bool(true)
bool(true)

PHP版本:

PHP 5.3.3 (cli) (built: Sep 13 2011 11:17:59)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies

在 PHP 5.3.3 中对我来说似乎运行良好。


0

@Berry

实际上,当我构建哈希表时,调试时会得到这个:

 $res = getDATABASEVALUES();
 //res contains 20 rows, the number 11 has accent
 $res[11]['name'] => returns 'name é'
 ord($res[11]['name'][5]) => returns 195 and not 233

2
“e acute”字符在UTF-8中编码为两个字节,即0xC3 0xA9,因此ord(5)应返回195,ord(6)应返回169。请记住,PHP字符串只是一系列字节,如ord()strlen()等函数并不设计“理解”UTF-8,它们只能处理字节。请参考deceze的答案和评论,它们是正确的。 - Josh Davis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接