Angesichts der richtigen Konfiguration, eines sehr einfachen Prozesses und ausreichend Speicherplatzes hat PHP eine Obergrenze für die Anzahl der Iterationen in Schleifen oder würde es einfach so lange weiterlaufen, bis entweder der Speicher erschöpft, die maximale Ausführungszeit erreicht oder ein Fehler aufgetreten ist auf eine andere Weise?
Wenn ja, ist es für die verschiedenen Arten von Schleifen unterschiedlich? während, tue ... während, für, foreach?
Zum Beispiel:
%Vor%Mir ist klar, dass das ein wenig absurd ist, aber es ist hauptsächlich eine Kuriosität von mir bezüglich der PHP-Einschränkungen. Ich konnte nichts in den Dokumenten oder in dieser spezifischen Frage finden, die hier auf SO besprochen wurde.
Ich habe dieses Skript in einer lokalen Entwicklungsumgebung ausgeführt, in der PHP 7.1 auf einem 3,1 GHz Intel Core i7 MacBook Pro mit 16 GB RAM mit einem max_execution_time
von Null ausgeführt wurde. Nach etwa 720.000 würde der Browser selbst seine eigenen Grenzen erreichen und einfrieren. Ich habe diesen Test über die CLI ausgeführt und obwohl es sehr lange gedauert hat, wurde es ausgeführt und ausgeführt, aber ich habe es schließlich manuell gestoppt.
Der Browser würde einfrieren, da er keine Antwort erhält, es sei denn, es wird ein 500
oder irgendein anderer Fehlerstatus / Antwort erhalten. PHP könnte theoretisch unbestimmt laufen.
Zum Beispiel verwende ich so etwas, um einige "Jobs" im Hintergrund zu bearbeiten:
%Vor% Wenn es zu Ihrem Browser kommt, ja - es wird einfrieren, während Sie auf den Code 200 OK
warten, der definitiv nicht ankommt, weil der Webserver TimeOut
configuration, PHP max_execution_time
setting (und andere) ... und viele andere Faktoren, nicht die Größe der Daten in Ihrem Browser übertragen, die den tatsächlichen "Absturz" Ihres Browsers in einem Fall tun, in dem Sie jede Zahl von 0
bis 999999999999999999
iterieren und echo.
Ihre for
Schleife erreicht ihr Ziel 999999999999999999
(wahrscheinlich nicht in Ihrem Browser, aber definitiv im Terminal), außer wenn etwas anderes sie stoppt oder bricht (zB STRG + C, Bedingung, max_execution_time
usw.).
tl; dr
PHP wird gerne für immer endlos laufen, vorausgesetzt, es hat genug Ressourcen und der Prozess wird nicht vom Betriebssystem, Apache, Benutzer usw. beendet.
Sie verwechseln ein Browserproblem mit PHP. Der Browser kann nicht mit so vielen echo "$i<br/>";
umgehen, dass er abstürzt oder einfriert oder was auch immer. Es ist auch möglich, dass PHP nicht mehr genügend Arbeitsspeicher zur Verfügung hat, indem Sie so viele $i
in den Ausgabepuffer setzen, bevor er an den Browser gesendet wird.
Versuchen Sie, den Code korrekt zu bewerten, und Sie erhalten schnell Ihre Antwort:
%Vor%Unter der Annahme, dass Apache / PHP / Ihr Browser keine Zeitüberschreitung hat, sollten Sie ein Ergebnis sehen; Wenn nicht, dann gehe zur Befehlszeile.
999999999999999999
liegt außerhalb der maximalen sicheren Ganzzahl, die dargestellt werden kann. Wenn Sie PHP fragen, wie viel 9007199254740992 + 1
ist, wird es Ihnen sagen, dass es 9007199254740992
ist. Mit anderen Worten:
Ausgaben bool(true)
.
Dies ist eine Einschränkung der Gleitkommazahlen. Aus diesem Grund wird Ihre Iterationsvariable $i
nicht 999999999999999999
erreichen. Sie haben effektiv eine Endlosschleife erstellt.
Sie können 9007199254740992
als Grenzwert betrachten. Das liegt natürlich am Datentyp, den PHP für die Variable verwendet ( double, aka IEEE 754 binary64 ) ).
Sie haben das gleiche Problem, wenn Sie eine Endlosschleife verwenden und versuchen, die Anzahl der Iterationen zu zählen. Sie können theoretisch eine Bibliothek verwenden, die beliebige große ganze Zahlen verarbeiten kann ... Aber es gibt keinen Grund, warum PHP sowieso aufhören würde, zumindest nicht bevor die Hardware zu versagen beginnt.
Trivia : 999999999999999999 flop
ausgeführt bei 100 gigaflop/second
würde 115 days 17 hours 46 minutes 40 seconds
zum Ausführen benötigen.
Errata strong>: Auf einem 64-Bit-Build von PHP ist die maximal sichere Zahl, die dargestellt werden kann, 9223372036854775807
. Mit anderen Worten:
Ausgaben bool(true)
9223372036854775808
ist ungefähr eine Größenordnung größer als 999999999999999999
, daher ist diese Schleife in einem 64-Bit-Build von PHP nicht unendlich. Dies ist keine Quad-Präzision . Bei weiteren Tests stellt sich heraus, dass PHP eine 64-Bit-Ganzzahl bis zu 9223372036854775807
verwendet und dann zu double:
Ausgaben
%Vor% Inzwischen wird der 32-Bit-Build einen 32-Bit-Intger bis zu 2147483647
verwenden und dann den Switch verwenden, um ihn zu verdoppeln.