PHP esegue qualche analisi sul file php.ini?


24

Esecuzione della versione 7.1.30 di PHP in RHEL 7.7.

Voglio eliminare memory_limit, ma non ero sicuro di avere la sintassi corretta (ovvero 256 MB o 256 MB). Quindi, per cominciare, ho inserito un valore errato "Hugo" come impostazione memory_limit. Il problema è che phpinfo () (eseguito sotto httpd) ha letteralmente la stringa "Hugo", ovvero:

inserisci qui la descrizione dell'immagine

Quindi questo mi preoccupa un po 'che PHP in realtà non esegua alcun controllo di integrità per i valori. (Se il valore fornito fosse scadente, mi aspetterei di ripristinare un valore predefinito, ad es.)

Qualcuno può commentare questo, in particolare, come fai a sapere se PHP applicherà le cose (se può essere fornita una stringa arbitraria).


4
Ottima domanda
tink

3
Da questo: php.net/manual/en/faq.using.php#faq.using.shorthandbytes suppongo che sia lo stesso (int) 'HUGO'; // => 0. Che inizia a fallire sulla mia macchina a 2 MB di memoria utilizzata.
Yoshi,


@Yoshi Penso che dovresti pubblicare la tua risposta. È una buona spiegazione
Maksym Fedorov il

@MaksymFedorov Sono titubante in quanto non ho alcun riferimento reale per la mia ipotesi. Per ora è solo un'osservazione.
Yoshi,

Risposte:


19

La cosa confusa qui è che l'impostazione sembra un numero intero con una sintassi speciale, ma è internamente definita come una stringa. La stringa viene quindi analizzata in una variabile globale separata ogni volta che il valore viene modificato. Fondamentalmente, il risultato dell'analisi della stringa in un numero intero non viene salvato nella tabella delle impostazioni, quindi quando chiami phpinfo(), vedi l'input originale, non il valore analizzato.

Puoi vederlo nella fonte:

La sintassi supportata è in definitiva definita in zend_atol, che:

  1. analizza la stringa per un valore numerico, ignorando qualsiasi testo aggiuntivo
  2. guarda l'ultimo carattere della stringa, e si moltiplica il valore precedente, qualora si g, G, m, M, k, oK

Un valore senza cifre all'inizio verrà analizzato come zero. Quando si imposta la variabile globale, questo imposterà il limite di memoria al minimo consentito, in base alla costante ZEND_MM_CHUNK_SIZE.

Puoi vedere l'effetto impostando il limite di memoria, quindi eseguendo un ciclo che alloca rapidamente una grande quantità di memoria e vedi cosa viene visualizzato nel messaggio di errore. Per esempio:

# 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

Grazie @IMSoP per l'ottima valutazione. Si dovrebbe segnalare questo genere di cose in qualsiasi tipo di bugtracker? Trovo la risposta che phpinfo () genera altamente contro-intuitiva. E alcuni output di debug per ciò che fa php quando incontra valori imprevisti, non andrebbero male.
tink

1
@tink Immagino che potresti inoltrare una richiesta di funzionalità su bugs.php.net o inviare un messaggio alla mailing list di Internals dove si trova la maggior parte del coordinamento. Ho trovato una richiesta simile da diversi anni fa , ma non sembra aver avuto alcuna risposta.
IMSoP

Grazie ancora, lo esaminerò! :)
tink

0

Prima di tutto, dobbiamo prima capire come PHP.ini funziona nel modo di interpretare il flusso di lavoro. memory_limit è direttive per PHP.

quando usi con la funzione PHP devi fare qualcosa del genere ini_set(‘memory_limit’,’256MB’). Quindi, questa funzione imposterà temporaneamente il tuo valore sulla variabile interprete. Se vedi più vicino, puoi ottenere le due colonne Una è per il locale e una per il globale. Ciò mostra rispettivamente la capacità dei valori per l'individuo.

Ma, quando hai definito globale, devi impostare come suffisso rispettivamente con K, M, G. Se superiamo questo valore usando apache .htaccess, questo richiede lo stesso per il fpm PHP.


3
Vorrei sottolineare che l'OP non chiede come impostare il limite di memoria :)
Karolis,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.