Почему PHP strlen () возвращает отрицательную длину?

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?

Related of "Почему PHP strlen () возвращает отрицательную длину?"

string может достигать 2 ГБ.

Похоже, что это на самом деле (2 ГБ – 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]; 

То, что вы делаете, просто не определено , и руководство должно быть исправлено. Я бы тоже ожидал предупреждения.

Интересно, что это приводит к фатальной ошибке:

 $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 байт».

Я полагаю, вы просто переполняете int своей большой строкой. Из руководства:

Размер целого зависит от платформы, хотя максимальное значение около двух миллиардов – это обычное значение (это 32 бита). PHP не поддерживает целые числа без знака. Целочисленный размер может быть определен с использованием константы PHP_INT_SIZE и максимального значения с использованием константы PHP_INT_MAX с PHP 4.4.0 и PHP 5.0.5.

Так что это должно быть ОК, если ваш размер строки может поместиться в int.