PHP多字节字符串函数

时间:2009-03-19 11:24:43

标签: php utf-8 multibyte

今天我遇到了php函数strpos()的一个问题,因为它返回FALSE,即使正确的结果显然为0.这是因为一个参数是用UTF-8编码的,但是另一个参数(原点是HTTP GET参数)显然不是。

现在我注意到使用mb_strpos函数解决了我的问题。

我现在的问题是:明智地使用PHP多字节字符串函数来避免将来出现这些问题吗?我应该完全避免使用传统的strposstrlenereg等功能吗?

注意:我不想在php.ini中设置mbstring.func_overload global,因为这会在使用PEAR库时导致其他问题。我使用的是PHP4。

5 个答案:

答案 0 :(得分:4)

5.2之前的PHP版本中的mb_ *函数存在一些问题。因此,如果您的代码使用不同版本的PHP进行多个平台,则可能会发生奇怪的行为。此外,mb_ strpos函数相当慢,它必须跳过offset参数指定的字符数才能获得内部使用的实际字节位置。在循环中,取决于strpos / mb_strpos功能,这可能成为一个主要的瓶颈。

答案 1 :(得分:4)

这取决于您使用的字符编码。在单字节字符编码或UTF-8(字符内的单个字节永远不会被误认为是另一个字符)中,只要您搜索的字符串和您用于搜索的字符串相同编码然后你可以继续使用常规的字符串搜索功能。

如果使用UTF-8以外的多字节编码,这不会阻止字符中的单个字节像其他字符一样出现,那么使用常规字符串搜索功能进行字符串搜索绝不是安全的。你可能会发现误报。这是因为PHP在strpos等函数中的字符串比较是按字节进行的,除了专门为防止出现此问题而设计的UTF-8外,多字节编码还存在以下问题:字符中的任何后续字节都由多个字节可能匹配不同字符的一部分。

如果您在中搜索的字符串,并且您要搜索的字符串具有不同的字符编码,则始终需要进行转换。否则,您会发现对于在其他编码中表示不同的任何字符串,它将始终返回false。您应该对输入进行此类转换:决定应用程序将使用的字符编码,并在应用程序中保持一致。只要您以不同的编码接收输入,就可以进行转换。

答案 2 :(得分:2)

如果您在任何地方使用相同的编码,通常不会有问题。我在所有页面上使用UTF-8,从未真正遇到过这个问题。最后,它真正归结为为页面和数据库指定相同的编码。

例如:

header('Content-type: text/html;charset=utf-8');
mysql_query('SET NAMES utf8');

在大多数情况下,这意味着应用程序的所有数据源都将以相同的编码提供数据,因此您将避免此类问题。

随着PHP 6的出现,这将会更好,顺便说一句,因为它将包括完整的unicode支持。

答案 3 :(得分:1)

您不一定要使用mb_strpos,但您需要确保应用中的所有数据都相同:mb_string或一个特定编码中的普通字符串。 (通常是UTF-8。)

如果您确保您的页面是UTF-8,并且您的表单提交被解释为UTF-8,并且您的数据库存储了UTF-8,那么您通常会没问题。索引字符串操作(特别是截断)可以破坏UTF-8序列,这很烦人但通常不是灾难性的。如果您确实需要这种级别的支持,mb_strings是您唯一的选择(当然,您必须确保应用程序和库的所有部分以及PHP版本都能正确处理它们。)

开发在PHP中正确处理Unicode的网站现在并不是太有趣:与Python和.NET等语言相比,它的Unicode支持非常差。希望PHP6能够改善问题。

答案 4 :(得分:0)

我建议使用以下PHP UTF-8库:

http://sourceforge.net/projects/phputf8

将它与您的应用程序捆绑在一起不需要mbstring扩展,从而放松了应用程序的要求,但仍然可以获得UTF-8字符串函数。