Robert Wade
Robert Wade

Reputation: 5003

Is there a maximum amount of iterations PHP can loop?

Given the right configuration, a very simple process and enough memory, does PHP have a ceiling on number of iterations in loops, or would it just continue to execute until you either exhausted the memory, hit the max execution time, or faulted in some other way?

If so, is it different for the various types of loops? while, do...while, for, foreach?

For instance:

<?php 
for ($i=0; $i<999999999999999999; $i++) {
  echo "$i<br/>";
};

I realize this is a little absurd, but it's mostly a curiosity of mine about PHP limitations. I couldn't find anything in the docs or this specific question discussed here on SO.

I did run this script in a local development environment running PHP 7.1 built in server on a 3.1GHz Intel Core i7 MacBook Pro with 16GB RAM, with a max_execution_time of zero. After about 720,000 the browser itself would reach it's own limitations and freeze up. I did run this same test via the CLI and while it took a really long time, it did execute and ran but I eventually manually stopped it.

Upvotes: 10

Views: 6677

Answers (3)

Theraot
Theraot

Reputation: 40200

999999999999999999 is beyond the maximum safe integer that can be represented. If you ask PHP how much is 9007199254740992 + 1 it will tell you it is 9007199254740992. In other words:

<?php var_dump ((9007199254740992 + 1) === 9007199254740992);

Outputs bool(true).

This is a limitation of floating point numbers. Because of it, your iteration variable $i will not reach 999999999999999999. You have effectively created an infinite loop.

You may consider 9007199254740992 the limit. Of couse, this is because of the data type PHP uses for the variable (double, a.k.a IEEE 754 binary64).


You will have the same problem if you use an infinite loop and try to count the number of iterations. You may in theory use a library that can handle arbitrary large integers... But there is no reason why PHP would stop anyway, at least not before the hardware begin to fail.

Trivia: 999999999999999999 flop executed at 100 gigaflop/second would take 115 days 17 hours 46 minutes 40 seconds to run.


Errata: On a 64 bits build of PHP the maximun safe integer that can be represented is 9223372036854775807. In other words:

<?php var_dump ((9223372036854775808 + 1) === 9223372036854775808);

Outputs bool(true)

Try online.

9223372036854775808 is about one order of magnitud greater than 999999999999999999, thus this loop is not infinite in a 64 bit build of PHP. This is not quad precision. Upon futher testing, turns out PHP is using a 64 bit integer up to 9223372036854775807 and then switch to double:

<?php
var_dump (serialize(9223372036854775807));
var_dump (serialize(9223372036854775808));

Outputs

string(22) "i:9223372036854775807;"
string(25) "d:9.2233720368547758E+18;"

Try online.

Meanwhile the 32 bits build will use a 32 bit intger up to 2147483647 and then use switch to double.

Upvotes: 5

MonkeyZeus
MonkeyZeus

Reputation: 20737

tl;dr

PHP will gladly loop forever assuming it has enough resources and that the process isn't terminated by the operating system, Apache, user, etc...


You are confusing a browser issue with PHP. The browser cannot handle the rendering of so many echo "$i<br/>"; so it crashes or freezes or whatever. It's also possible that PHP is running out of memory by placing so many $i into the output buffer before it sends it to the browser.

Try benchmarking the code properly and you will quickly get your answer:

// Let's set the start timer
$start = microtime(true);

// Add or remove 9's as you please
for($i=0; $i<999999999999999999; ++$i){}

// How many seconds did this take to complete?
echo (microtime(true) - $start).' seconds<br/>';

// What was the peak memory usage during this code execution?
echo memory_get_peak_usage(true).' bytes used';

Assuming Apache/PHP/your browser does not time out then you should see a result; if not then go command-line.

Upvotes: 5

Zlatan Omerovic
Zlatan Omerovic

Reputation: 4097

The browser would freeze since it won't get a response, unless it get's a 500 or any other error status/response. PHP, in theory, could run indefinitelly.

For example, I use something like this to handle some "jobs" in the background:

while(true) {
    // and I do some wonders here
    // if some conditions are met
}

When it comes to your browser, yes - it will freeze whilst awaiting the 200 OK response code which will definitelly not arrive because of the web server TimeOut configuration, PHP's max_execution_time setting (and others) ... and many other factors, not mentioning the size of the data transmitted into your browser, which will do the actual "crash" of your browser in a case where you iterate and echo each number from 0 to 999999999999999999.

Your for loop will reach it's destination of 999999999999999999 (probably not in your Browser, but definitelly in the terminal), unless something else stops it or breaks it (ie. CTRL+C, condition, max_execution_time, etc).

Upvotes: 5

Related Questions