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?
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.