4

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

现在我注意到使用该mb_strpos功能解决了我的问题。

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

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

4

5 回答 5

4

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

于 2009-03-19T11:33:46.613 回答
4

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

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

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

于 2009-03-19T11:37:54.433 回答
2

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

例如:

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

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

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

于 2009-03-19T11:36:37.590 回答
1

您不一定必须使用 mb_strpos,但您确实需要确保应用程序中的所有数据都是相同的:要么是 mb_string,要么是一种特定编码的纯字符串。(通常是 UTF-8。)

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

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

于 2009-03-19T11:35:25.597 回答
0

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

http://sourceforge.net/projects/phputf8

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

于 2009-03-19T22:18:35.977 回答