12

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)

?>

是否定义了这种行为?

或者这是一个 PHP 错误?

4

2 回答 2

5

string最大可达 2GB。

看起来实际上是(2GB - 1)。这在我的 x64 盒子上运行良好:

$str = str_repeat('a', 2 * 1024 * 1024 * 1024 -1);
echo $str[0];

...虽然这打破了:

$str = str_repeat('a', 2 * 1024 * 1024 * 1024);
echo $str[0];

您所做的只是undefined,应该更正手册。我也期待一个警告。

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

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


更新:

错误报告已被处理。php.net 上的文档已修复,现在写入“最大 2147483647 字节”。

于 2013-07-10T16:59:47.877 回答
2

我想你只是用你的大字符串溢出了一个 int 。从手册:

整数的大小取决于平台,尽管通常值约为 20 亿的最大值(即 32 位有符号)。PHP 不支持无符号整数。自 PHP 4.4.0 和 PHP 5.0.5 起,可以使用常量 PHP_INT_SIZE 确定整数大小,使用常量 PHP_INT_MAX 确定最大值。

所以如果你的字符串大小可以适合 int 应该没问题。

于 2013-07-10T16:29:56.610 回答