Krótko: php.ini to centralny plik konfiguracyjny PHP. PHP czyta go przy starcie, w modułach serwera raz, w CGI i CLI przy każdym wywołaniu. Dochodzą pliki dodatkowe z katalogu skanowania, ustawienia w puli FPM lub w Apache, .htaccess albo .user.ini oraz ini_set() w kodzie. To, który poziom może zmienić wartość, określa jej tryb zmiany, na przykład INI_SYSTEM lub INI_PERDIR. Wartości ustawionych przez php_admin_value aplikacja nie może już nadpisać.
Czym jest php.ini?
php.ini to plik tekstowy z wpisami według wzoru name = wert. Określa, jak PHP się zachowuje: ile pamięci może użyć skrypt, czy błędy pojawiają się w przeglądarce, jak działają sesje i które rozszerzenia są ładowane. Komentarze zaczynają się od średnika.
Według podręcznika PHP plik jest czytany przy starcie PHP. W modułach serwera, takich jak mod_php, dzieje się to tylko raz, przy starcie serwera WWW, w CGI i CLI przy każdym wywołaniu. PHP-FPM czyta swoją konfigurację przy starcie i przy przeładowaniu usługi. Zmiana bez restartu lub przeładowania zwykle więc nie działa.
Od PHP 8.3 wpis może według podręcznika odwoływać się do zmiennej środowiskowej z wartością zastępczą:
memory_limit = ${PHP_MEMORY_LIMIT}
max_execution_time = ${PHP_MAX_EXECUTION_TIME:-30}
Gdzie PHP szuka php.ini?
Podręcznik opisuje stałą kolejność. Najpierw obowiązuje wyraźnie ustawiona ścieżka, na przykład PHPIniDir w Apache lub opcja -c w CGI i CLI. W przeciwnym razie PHP buduje ścieżkę wyszukiwania z:
- zmiennej środowiskowej
PHPRC, - w systemie Windows wpisu rejestru
IniFilePath, - bieżącego katalogu roboczego, z wyjątkiem SAPI, które to wyłączają, na przykład CLI,
- katalogu binarnego pliku PHP lub modułu,
- ścieżki ustawionej przy kompilacji
--with-config-file-path.
W tej ścieżce wyszukiwania PHP szuka najpierw pliku php-SAPI.ini, na przykład php-cli.ini, a dopiero potem php.ini. Następnie PHP czyta w kolejności alfabetycznej wszystkie pliki .ini z katalogu skanowania, ustalonego przez PHP_INI_SCAN_DIR lub przy kompilacji przez --with-config-file-scan-dir. Które pliki zostały załadowane, pokazuje php --ini lub funkcja php_ini_scanned_files().
php --ini
php -r 'var_dump(php_ini_loaded_file(), php_ini_scanned_files());'
Oba polecenia pokazują stan wiersza poleceń. Dla strony może obowiązywać inny plik, ponieważ każde SAPI może mieć własną konfigurację; więcej na stronie SAPI wyjaśnione.
Tryby zmiany: kto może ustawić jaką wartość?
Nie każde ustawienie wolno zadawać wszędzie. Podręcznik przypisuje każdej dyrektywie tryb zmiany:
| Tryb | Gdzie wartość wolno ustawić |
|---|---|
INI_USER |
w skryptach przez ini_set(), w rejestrze Windows i w .user.ini |
INI_PERDIR |
w php.ini, .htaccess, httpd.conf lub .user.ini |
INI_SYSTEM |
tylko w php.ini lub httpd.conf |
INI_ALL |
wszędzie |
Przykłady z podręcznika: memory_limit ma tryb INI_ALL i domyślną wartość 128M, post_max_size ma INI_PERDIR i domyślnie 8M, upload_max_filesize ma INI_PERDIR i domyślnie 2M. expose_php może znajdować się tylko w php.ini.
Pliki .user.ini są według podręcznika czytane tylko przez SAPI CGI i FastCGI, a więc także przez PHP-FPM. PHP szuka ich od katalogu skryptu w górę aż do Document Root i domyślnie czyta je od nowa co najwyżej co 300 sekund (user_ini.cache_ttl). W mod_php tę rolę przejmuje .htaccess.
Która wartość obowiązuje na końcu? Poziomy i pierwszeństwo
W uproszczeniu: im później poziom działa, tym chętniej jego wartość się przebija, o ile pozwala na to tryb zmiany.
- php.ini danego SAPI
- Pliki dodatkowe z katalogu skanowania, alfabetycznie
- Konfiguracja serwera: pula FPM z
php_valuelubphp_admin_value, VirtualHost Apache - Poziom katalogu:
.htaccessw mod_php,.user.iniw FPM i CGI - Czas działania:
ini_set()w kodzie aplikacji
Wyjątek jest rozstrzygający: wartości ustawionych przez php_admin_value lub php_admin_flag nie można według podręcznika nadpisać przez ini_set(). Administratorzy blokują w ten sposób istotne dla bezpieczeństwa ustawienia przed aplikacją. Szczegółowo opisuje to artykuł php_admin_value: blokowanie ustawień przed nadpisaniem.
php.ini po PHP2Shell: co się zmieniło
Środki przejściowe z php.net dotyczące PHP2Shell to prawie wszystkie ustawienia INI: memory_limit=-1 zablokowane przed nadpisaniem, ograniczone post_max_size, session.upload_progress.enabled=0 oraz w PHP 8.5 fatal_error_backtraces=0. php.net podkreśla, że session.upload_progress.enabled nie powinno być ustawiane przez ini_set() ani .user.ini, lecz w php.ini, puli FPM lub konfiguracji serwera, z następującym po tym restartem wszystkich workerów. Pełną listę podajemy na stronie Środki natychmiastowe, gdy nie można jeszcze załatać.
Wraz z poprawionymi wersjami 8.5.12, 8.4.27, 8.3.36 i 8.2.35 zmienił się według podręcznika także memory_limit: jest teraz limitem miękkim. Nowe ustawienie memory_hard_limit_percent określa limit twardy. Bez własnej wartości wynosi dwukrotność memory_limit, przy więcej niż 1G wartość plus 1G. Po jego przekroczeniu proces kończy się natychmiast ze statusem wyjścia 137. Jak sensownie dobrać oba limity, wyjaśnia artykuł Prawidłowe ustawienie memory_limit.
Według podręcznika obowiązuje: jeśli wersja PHP nie zna memory_hard_limit_percent, jest dotknięta przez CVE-2026-109618 i CVE-2026-109619. W dystrybucjach z backportami stan dodatkowo potwierdza changelog pakietu.
Jak konkretnie pomaga PHP SOS?
- Ustalenie obowiązujących wartości: Odczytujemy dla każdego SAPI, które pliki są ładowane i jaka wartość obowiązuje na końcu.
- Porządkowanie poziomów: Usuwamy sprzeczne wpisy z paneli, pul,
.htaccessi.user.ini. - Ustawianie blokad: W ramach utwardzania serwera ustalamy istotne dla bezpieczeństwa wartości przez
php_admin_value. - Dokumentowanie: Dokumentujemy ustawienia i restart, aby stan można było później udowodnić.
Częste pytania
Gdzie leży php.ini?
Zależy to od systemu operacyjnego, pakietu i SAPI. W Debianie i Ubuntu dla każdej wersji i SAPI istnieją osobne katalogi, na przykład /etc/php/8.3/fpm/php.ini i /etc/php/8.3/cli/php.ini. W wierszu poleceń php --ini pokazuje załadowane pliki, a dla strony pomaga php_ini_loaded_file() w krótko umieszczonym pliku kontrolnym.
W jakiej kolejności czytane są pliki w katalogu conf.d?
Według podręcznika PHP czyta wszystkie pliki z rozszerzeniem .ini w katalogu skanowania w kolejności alfabetycznej. Późniejsze pliki nadpisują wartości wcześniejszych. Dlatego wiele plików ma w nazwie liczby, takie jak 20- czy 99-.
Dlaczego moja zmiana w php.ini nie działa?
Częste powody: zmieniono plik innego SAPI, usługa nie została zrestartowana, wartość w puli FPM, w konfiguracji Apache albo w pliku .user.ini ją nadpisuje, lub panel hostingowy przy następnym zapisie tworzy plik od nowa.
Czym jest memory_hard_limit_percent?
To nowe ustawienie, wprowadzone według podręcznika PHP wraz z wydaniami bezpieczeństwa z 21.10.2026. Określa twardy limit pamięci jako procent memory_limit. Podręcznik zwraca uwagę, że wersja PHP, która nie zna tego ustawienia, jest dotknięta lukami PHP2Shell.