7

我正在 PHP 5.2.10 上编写一个简单的网站解析器。
当使用默认的内部编码(即 ISO-8859-1)时,我总是在同一个函数调用中得到一个错误:

$start = mb_strpos($index, '<a name=gr1>');

致命错误:允许的内存大小为 50331648 字节已用尽(尝试分配 11924760 字节)

在这种情况下,字符串 $index 的长度是 2981190 字节——正好是 PHP 尝试分配的 4 倍。

现在,如果我使用

mb_internal_encoding('UTF-8')

错误消失。这是否意味着 PHP 为单字节字符串使用更多内存而不是多字节字符串?这怎么可能?有任何想法吗?

UPD:内存使用似乎不依赖于编码:平均 memory_get_usage() 使用 UTF-8 和 ISO-8859-1 几乎相同。我认为问题可能出在 mb_strpos 中。事实上,字符串 $index 具有 Windows-1251 编码(西里尔文),因此它包含对 UTF-8 无效的符号。这可能会导致 mb_strpos 以某种方式尝试转换或仅将额外的内存用于某些需要。将尝试在 mb_strpos 的来源中找到答案。

4

1 回答 1

3

抱歉,如果您已经考虑过这些潜在问题。

多字节字符串函数将检查 UTF-8 编码是否有错误,如果有无效字符,则返回空字符串或 false(如 mb_strpos() 的情况: http://www.serverphorums.com/read.php? 7,552099

您是否正在使用===运算符检查您获得的结果以确保您没有收到false而不是0

mb_strpos()函数使用mbfl_strpos(),它在必须执行转换时复制字符串(针,干草堆)(导致内存增加,正如您所观察到的): https ://github.com/php/php-src/blob/master /ext/mbstring/libmbfl/mbfl/mbfilter.c#L811

所以,我想知道是否使用默认的内部编码(ISO-8859-1)让一切都通过,并且内存限制被击中,而 utf-8 编码由于非法字符而短路并返回 false(如果您正在使用 进行测试==,这会使函数看起来只是没有找到匹配项。)

值得一试 :)

于 2012-08-29T05:41:45.117 回答