Führt PHP eine Analyse der Datei php.ini durch?

24

Ausführen von PHP Version 7.1.30 unter RHEL 7.7.

Ich möchte memory_limit erhöhen, war mir aber nicht sicher, ob ich die richtige Syntax hatte (dh 256 MB oder 256 MB). Zu Beginn habe ich einen schlechten Wert "Hugo" als memory_limit-Einstellung eingegeben. Das Problem dabei ist das Ergebnis von phpinfo () (ausgeführt unter httpd), das buchstäblich die Zeichenfolge "Hugo" enthält, dh:

Geben Sie hier die Bildbeschreibung ein

Das hat mich etwas beunruhigt, dass PHP tatsächlich keine Überprüfung der Gesundheit der Werte durchführt. (Wenn der angegebene Wert schlecht wäre, würde ich erwarten, dass er auf einen Standardwert zurückgesetzt wird, z.)

Kann jemand dies kommentieren - insbesondere, woher wissen Sie, ob PHP Dinge erzwingen wird (wenn eine willkürliche Zeichenfolge bereitgestellt werden kann).

Patrick Rynhart
quelle
4
Ausgezeichnete Frage.
Tink
3
Aus diesem Grund : php.net/manual/en/faq.using.php#faq.using.shorthandbytes Ich würde annehmen, dass es dasselbe ist wie (int) 'HUGO'; // => 0. Was auf meinem Computer bei 2 MB verwendetem Speicher zu versagen beginnt.
Yoshi
Für den Datensatz lautetmemory_limit 256M die korrekte Syntax .
Tigger
@ Yoshi Ich denke, Sie sollten Ihre Antwort veröffentlichen. Es ist eine gute Erklärung
Maksym Fedorov
@MaksymFedorov Ich zögere, da ich keine wirkliche Referenz für meine Annahme habe. Im Moment ist es nur eine Beobachtung.
Yoshi

Antworten:

19

Das Verwirrende dabei ist, dass die Einstellung wie eine Ganzzahl mit einer speziellen Syntax aussieht, aber intern als Zeichenfolge definiert ist. Die Zeichenfolge wird dann bei jeder Änderung des Werts in eine separate globale Variable analysiert . Entscheidend ist, dass das Ergebnis des Parsens der Zeichenfolge in eine Ganzzahl nicht in der Einstellungstabelle gespeichert wird. Wenn Sie also aufrufen phpinfo(), sehen Sie die ursprüngliche Eingabe und nicht den analysierten Wert.

Sie können dies in der Quelle sehen:

Die unterstützte Syntax wird letztendlich definiert in zend_atol:

  1. analysiert die Zeichenfolge nach einem numerischen Wert und ignoriert jeden zusätzlichen Text
  2. Blicke auf dem letzten Zeichen der Zeichenfolge und multipliziert , wenn der vorhergehende Wert ist g, G, m, M, k, oderK

Ein Wert ohne Ziffern am Start wird als Null analysiert. Wenn Sie die globale Variable festlegen, wird das Speicherlimit basierend auf der Konstante auf das zulässige Minimum festgelegt ZEND_MM_CHUNK_SIZE.

Sie können den Effekt sehen, indem Sie das Speicherlimit festlegen, dann eine Schleife ausführen, die schnell eine große Menge an Speicher zuweist, und sehen, was in der Fehlermeldung angezeigt wird. Zum Beispiel:

# Invalid string; sets to compiled minimum
php -r 'ini_set("memory_limit", "HUGO"); while(true) $a[]=$a;'
# -> PHP Fatal error:  Allowed memory size of 2097152 bytes exhausted

# Number followed by a string; takes the number
php -r 'ini_set("memory_limit", "4000000 HUGO"); while(true) $a[]=$a;'
# -> PHP Fatal error:  Allowed memory size of 4000000 bytes exhausted

# Number followed by a string, but ending in one of the recognised suffixes
# This finds both the number and the suffix, so is equivalent to "4M", i.e. 4MiB
php -r 'ini_set("memory_limit", "4 HUGO M"); while(true) $a[]=$a;'
# -> PHP Fatal error:  Allowed memory size of 4194304 bytes exhausted
IMSoP
quelle
Vielen Dank an @IMSoP für diese großartige Bewertung. Sollte man so etwas in einem Bugtracker melden? Ich finde die Antwort, die phpinfo () generiert, sehr kontraintuitiv. Und einige Debug-Ausgaben für das, was PHP macht, wenn es auf unerwartete Werte stößt, würden auch nicht schaden.
Tink
1
@tink Ich denke, Sie könnten eine Feature-Anfrage auf bugs.php.net stellen oder eine Nachricht an die Internals-Mailingliste senden, wo die meiste Koordination stattfindet. Ich habe eine ähnliche Anfrage von vor einigen Jahren gefunden , aber es scheint keine Antwort gegeben zu haben.
IMSoP
Nochmals vielen Dank, werde das untersuchen! :)
tink
0

Zuerst müssen wir verstehen, wie PHP.ini im Interpretationsworkflow funktioniert. memory_limit ist Direktiven für PHP.

Wenn Sie mit der PHP-Funktion arbeiten, müssen Sie so etwas tun ini_set(‘memory_limit’,’256MB’). Diese Funktion setzt Ihren Wert also vorübergehend auf die Interpretervariable. Wenn Sie näher sehen, können Sie die beiden Spalten erhalten. Eine ist für die lokale und eine für die globale. Das zeigt die Fähigkeit der Werte für den Einzelnen.

Wenn Sie jedoch für global definiert haben, müssen Sie ein Suffix mit K, M bzw. G festlegen. Wenn wir diesen Wert mit apache .htaccess überschreiten, ist dasselbe für PHP fpm erforderlich.

Pranav Bhatt
quelle
3
Ich möchte freundlich darauf hinweisen, dass das OP nicht fragt, wie das Speicherlimit festgelegt werden soll :)
Karolis