为什么PHP strlen()返回负长度?

Pac*_*ier 12 php string debugging

strlen($str)返回使用str_repeat以下内容创建的"巨大字符串"的负值:

<?php

error_reporting(E_STRICT|E_ALL);
echo phpversion(); // 5.3.26
echo PHP_INT_MAX; // 9223372036854775807
ini_set('memory_limit', '-1');
ini_set('max_execution_time', 0);

$gb = 1024 * 1024 * 1024;
$str = str_repeat('a', 2 * $gb);
echo strlen($str); // gives int(-2147483648)
echo $str[0]; // Notice: Uninitialized string offset: 0

$str2 = str_repeat('a', 4 * $gb);
echo strlen($str2); // gives int(0)

$str3 = str_repeat('a', 123 + 4 * $gb);
echo strlen($str3); // gives int(123)

$str4 = str_repeat('a', 6 * $gb); // starts to wrap again...
echo strlen($str4); // gives int(-2147483648)
echo $str4[0]; // Notice: Uninitialized string offset: 0

$str5 = str_repeat('a', 123 + 8 * $gb);
echo strlen($str5); // gives int(123)

?>
Run Code Online (Sandbox Code Playgroud)

是否定义了此行为?

或者这是一个PHP错误?

Ran*_*eed 5

string 可以大到2GB.

看起来它实际上是(2GB - 1).这在我的x64盒子上工作正常:

$str = str_repeat('a', 2 * 1024 * 1024 * 1024 -1);
echo $str[0];
Run Code Online (Sandbox Code Playgroud)

......虽然这打破了:

$str = str_repeat('a', 2 * 1024 * 1024 * 1024);
echo $str[0];
Run Code Online (Sandbox Code Playgroud)

您正在做的事情是未定义的,应该更正手册.我本来也期待一个警告.

有趣的是,这引发了一个致命的错误:

$str = str_repeat('a', 2 * 1024 * 1024 * 1024 -2); // 2GB - 2 bytes
$str .= 'b'; // ok
$str .= 'c'; // PHP Fatal error:  String size overflow
Run Code Online (Sandbox Code Playgroud)


更新:

错误报告已参加的.php.net上的文档已修复,现在写入"最大2147483647字节".