In breve: il php.ini è il file di configurazione centrale di PHP. PHP lo legge all'avvio, con i moduli del server una volta, con CGI e CLI a ogni chiamata. A questo si aggiungono file supplementari da una directory di scansione, impostazioni nel pool FPM o in Apache, .htaccess o .user.ini e ini_set() nel codice. Quale livello possa modificare un valore lo stabilisce la sua modalità di modifica, ad esempio INI_SYSTEM o INI_PERDIR. I valori impostati con php_admin_value l'applicazione non può più sovrascriverli.
Che cos'è il php.ini?
Il php.ini è un file di testo con voci secondo lo schema name = wert. Stabilisce come si comporta PHP: quanta memoria può usare uno script, se gli errori compaiono nel browser, come lavorano le sessioni e quali estensioni vengono caricate. I commenti iniziano con un punto e virgola.
Secondo il manuale PHP il file viene letto all'avvio di PHP. Con i moduli del server come mod_php ciò avviene una sola volta, all'avvio del server web, con CGI e CLI a ogni chiamata. PHP-FPM legge la sua configurazione all'avvio e al ricaricamento del servizio. Una modifica senza riavvio o reload perciò di solito non ha effetto.
Da PHP 8.3, secondo il manuale, una voce può rimandare a una variabile d'ambiente con un valore sostitutivo:
memory_limit = ${PHP_MEMORY_LIMIT}
max_execution_time = ${PHP_MAX_EXECUTION_TIME:-30}
Dove cerca PHP il php.ini?
Il manuale descrive un ordine fisso. Per prima vale un percorso impostato espressamente, ad esempio PHPIniDir in Apache o l'opzione -c con CGI e CLI. Altrimenti PHP costruisce un percorso di ricerca da:
- la variabile d'ambiente
PHPRC, - su Windows la voce di registro
IniFilePath, - la directory di lavoro corrente, tranne che per le SAPI che lo disattivano, ad esempio la CLI,
- la directory del binario PHP o del modulo,
- il percorso impostato in compilazione
--with-config-file-path.
In questo percorso di ricerca PHP cerca prima un file php-SAPI.ini, ad esempio php-cli.ini, e solo dopo php.ini. Poi PHP legge in ordine alfabetico tutti i file .ini della directory di scansione, definita tramite PHP_INI_SCAN_DIR o, in compilazione, tramite --with-config-file-scan-dir. Quali file siano stati caricati lo mostrano php --ini o la funzione php_ini_scanned_files().
php --ini
php -r 'var_dump(php_ini_loaded_file(), php_ini_scanned_files());'
Entrambi i comandi mostrano lo stato della riga di comando. Per il sito web può valere un altro file, perché ogni SAPI può avere la propria configurazione; maggiori dettagli in SAPI spiegata.
Modalità di modifica: chi può impostare quale valore?
Non ogni impostazione può essere definita ovunque. Il manuale assegna a ogni direttiva una modalità di modifica:
| Modalità | Dove si può impostare il valore |
|---|---|
INI_USER |
negli script con ini_set(), nel registro di Windows e in .user.ini |
INI_PERDIR |
in php.ini, .htaccess, httpd.conf o .user.ini |
INI_SYSTEM |
solo in php.ini o httpd.conf |
INI_ALL |
ovunque |
Esempi dal manuale: memory_limit ha la modalità INI_ALL e il valore predefinito 128M, post_max_size ha INI_PERDIR e il valore predefinito 8M, upload_max_filesize ha INI_PERDIR e il valore predefinito 2M. expose_php può stare solo nel php.ini.
I file .user.ini, secondo il manuale, vengono letti solo dalle SAPI CGI e FastCGI, quindi anche da PHP-FPM. PHP li cerca dalla directory dello script verso l'alto fino al document root e li rilegge per impostazione predefinita al massimo ogni 300 secondi (user_ini.cache_ttl). Con mod_php questo ruolo è svolto da .htaccess.
Quale valore vale alla fine? I livelli in ordine di precedenza
In modo semplificato: più tardi interviene un livello, più facilmente il suo valore prevale, purché la modalità di modifica lo consenta.
- php.ini della rispettiva SAPI
- File supplementari dalla directory di scansione, in ordine alfabetico
- Configurazione del server: pool FPM con
php_valueophp_admin_value, VirtualHost di Apache - Livello di directory:
.htaccesscon mod_php,.user.inicon FPM e CGI - Runtime:
ini_set()nel codice dell'applicazione
L'eccezione è decisiva: i valori impostati con php_admin_value o php_admin_flag non possono, secondo il manuale, essere sovrascritti con ini_set(). Così gli amministratori bloccano le impostazioni rilevanti per la sicurezza contro l'applicazione. La descrizione dettagliata è in php_admin_value: bloccare le impostazioni contro la sovrascrittura.
Il php.ini dopo PHP2Shell: che cosa è cambiato
Le misure transitorie di php.net contro PHP2Shell sono quasi tutte impostazioni INI: memory_limit=-1 bloccato contro la sovrascrittura, post_max_size limitato, session.upload_progress.enabled=0 e, su PHP 8.5, fatal_error_backtraces=0. php.net sottolinea che session.upload_progress.enabled non deve essere impostato tramite ini_set() o .user.ini, ma in php.ini, nel pool FPM o nella configurazione del server, con successivo riavvio di tutti i worker. L'elenco completo è in Misure immediate se non potete ancora aggiornare.
Con le versioni corrette 8.5.12, 8.4.27, 8.3.36 e 8.2.35 è cambiato, secondo il manuale, anche memory_limit: ora è un limite morbido. La nuova impostazione memory_hard_limit_percent stabilisce un limite rigido. Senza valore proprio è il doppio di memory_limit, per valori superiori a 1G il valore più 1G. Se viene superato, il processo termina subito con stato di uscita 137. Come scegliere in modo sensato i due limiti lo spiega Impostare correttamente memory_limit.
Secondo il manuale vale: se una versione di PHP non riconosce memory_hard_limit_percent, è interessata da CVE-2026-109618 e CVE-2026-109619. Per le distribuzioni con backport lo stato lo documenta inoltre il changelog del pacchetto.
Come aiuta concretamente PHP SOS?
- Accertare i valori effettivi: leggiamo per ogni SAPI quali file vengono caricati e quale valore vale alla fine.
- Riordinare i livelli: rimuoviamo le voci contraddittorie da pannelli, pool,
.htaccesse.user.ini. - Impostare i blocchi: nell'ambito dell'hardening del server fissiamo i valori rilevanti per la sicurezza con
php_admin_value. - Documentare: registriamo impostazioni e riavvio, perché lo stato sia in seguito dimostrabile.
Domande frequenti
Dov'è il php.ini?
Dipende da sistema operativo, pacchetto e SAPI. Su Debian e Ubuntu esistono cartelle proprie per ogni versione e SAPI, ad esempio /etc/php/8.3/fpm/php.ini e /etc/php/8.3/cli/php.ini. Da riga di comando php --ini mostra i file caricati, per il sito web aiuta php_ini_loaded_file() in un file di verifica temporaneo.
In che ordine vengono letti i file nella cartella conf.d?
Secondo il manuale PHP, PHP legge in ordine alfabetico tutti i file con estensione .ini nella directory di scansione. I file successivi sovrascrivono i valori di quelli precedenti. Per questo molti file hanno nel nome numeri come 20- o 99-.
Perché la mia modifica al php.ini non ha effetto?
Motivi frequenti: è stato modificato il file di un'altra SAPI, il servizio non è stato riavviato, un valore nel pool FPM, nella configurazione di Apache o in un .user.ini lo sovrascrive, oppure un pannello di hosting riscrive il file al salvataggio successivo.
Che cos'è memory_hard_limit_percent?
Una nuova impostazione introdotta, secondo il manuale PHP, con le release di sicurezza del 21/10/2026. Stabilisce un limite di memoria rigido come percentuale di memory_limit. Il manuale avverte che una versione di PHP che non conosce questa impostazione è interessata dalle vulnerabilità di PHP2Shell.