Reputation: 5003
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
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)
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;"
Meanwhile the 32 bits build will use a 32 bit intger up to 2147483647
and then use switch to double.
Upvotes: 5
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
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