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

时间:2013-07-10 16:23:43

标签: 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)

?>

是否定义了此行为?

或者这是一个PHP错误吗?

2 个答案:

答案 0 :(得分:5)

  

string can be as large as 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

<小时/>

<强>更新

bug report已被关注。 php.net上的文档已修复,现在写入“最大2147483647字节”。

答案 1 :(得分:2)

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

  

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

如果您的字符串大小适合int。

,那么应该没问题