I am having a for loop which is iterating through a large array $result
. Every array item $row
is used to generate a new line of string $line
. This string is concatenated into $str
. To preserve memory, I am using unset($result[$i])
to clear every array item that has been processed in the original array. This looks like this:
$resultcount = count($result);
for($i=0; $i<$resultcount; ++$i){
$row = $result[$i];
$line = do_something($row);
$str.= '<tr><td>'.$line.'</td></tr>';
unset($result[$i]);
}
return $str;
This (more or less exotic piece of code) works unless the string exceeds a length of approx. 1'000'000 characters. In this case the return value is just empty. This is highly irritating because:
do_something()
) is not a problem. By using echo count($result).' - '.strlen($str)."\n"
I can see that the loop finishes properly. There is no web server or php error shown.memory_limit
is also not a problem. I am working with more data on other parts of the application.It appears that the problem lies in return $str
itself. If I am using return substr($str, 0, 980000)
then it just works fine. Further debugging shows that the string gets tainted as soon as it reaches the length of 999'775 bytes.
I can't put longer return value string into another string variable. But I am able to do a strlen()
to get a proper result (1310307). So the return value string has a total length of 1'310'307 bytes. But I can't use them properly as a string.
Where does this limitation come from and how may I circumvent it?
Well, it took me two and a half year to figure this out ;(
Rarst was right: It was not a problem of the function compiling and delivering the string. Later in the process I was using preg_replace()
to do some further replacements. This function is not able to handle long strings. This could be fixed by using ini_set('pcre.backtrack_limit', 99999999999)
beforehand as mentioned in How to do preg_replace on a long string