PHP中字符串的内部表示

PHP中字符串的内部表示,php,string,memory,Php,String,Memory,我正在PHP5.2.10上编写一个简单的网站解析器。 当使用默认内部编码(ISO-8859-1)时,我总是在同一个函数调用中得到一个错误: $start = mb_strpos($index, '<a name=gr1>'); 错误消失了。这是否意味着PHP对单字节字符串使用的内存比对多字节字符串使用的内存更多?怎么可能呢?有什么想法吗 UPD:内存使用率似乎不依赖于编码:使用UTF-8和ISO-8859-1时,平均内存使用率几乎相同。我认为问题可能出在mb_strpos中。 事实

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

$start = mb_strpos($index, '<a name=gr1>');
错误消失了。这是否意味着PHP对单字节字符串使用的内存比对多字节字符串使用的内存更多?怎么可能呢?有什么想法吗

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

如果您已经想到了这些潜在问题,请原谅

多字节字符串函数将检查UTF-8编码是否存在错误,如果存在无效字符,则返回空字符串或false(与mb_strps()的情况相同):

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

mb_strops()
函数使用
mbfl_strops()
,当它必须执行转换时(如您所观察到的,导致内存增加),它会复制字符串(指针、草堆):

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


值得一试:)

可能有用吗?你考虑过升级你的PHP吗?首先是因为5.2不再受支持,其次是因为5.3和5.4版本都有显著的内存使用改进(特别是5.3)。不确定这些改进是否包括
mb\u strpos()
,但无论如何升级都是值得的。认为您的更新是正确的。许多事情可能会影响。。。mb_detect_顺序,使用“auto”或“pass”等等。使用
iconv
可以很好地确保字符串“正常”,并匹配检测到的/设置的编码。希望配置文件并查看它对1252控制代码所做的操作。哦,邪恶的m-dash。我已经更新到5.3,这个问题并没有消失。我已经通过使用iconv将字符串转换为UTF-8并将其设置为内部编码暂时解决了这个问题。稍后将分析PHP源代码。一个不错的镜头!为了检查结果是
false
还是
0
我已经编写了一个类似于
assert()
的函数,严格执行检查(==)。但现在我不明白为什么PHP需要4倍的strlen内存——事实上,它将两个参数都转换为UTF-8(而不是
mb\u internal\u encoding()
)。感谢您的研究和所附的资料来源!;)
mb_internal_encoding('UTF-8')