Gibt es eine maximale Anzahl von Iterationen, die PHP durchlaufen kann?

8

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.

    
Robert Wade 27.11.2017, 13:45
quelle

3 Antworten

5

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

    
omerowitz 27.11.2017, 13:52
quelle
5

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.

    
MonkeyZeus 27.11.2017 14:07
quelle
5

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:

%Vor%

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 : Auf einem 64-Bit-Build von PHP ist die maximal sichere Zahl, die dargestellt werden kann, 9223372036854775807 . Mit anderen Worten:

%Vor%

Ausgaben bool(true)

Versuchen Sie es online .

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:

wechselt %Vor%

Ausgaben

%Vor%

Versuchen Sie es online .

Inzwischen wird der 32-Bit-Build einen 32-Bit-Intger bis zu 2147483647 verwenden und dann den Switch verwenden, um ihn zu verdoppeln.

    
Theraot 27.11.2017 14:29
quelle

Tags und Links