Aktualna sytuacja: PHP2Shell. Dwie krytyczne luki w PHP (CVSS 9,2) umożliwiają wykonanie złośliwego kodu bez logowania. Poprawki od 21.10.2026.Co należy teraz zrobić →

php.ini wyjaśniony: budowa, poziomy i pierwszeństwo

Gdzie PHP znajduje swoje ustawienia, w jakiej kolejności obowiązują i kto może je nadpisać. Podstawa każdego utwardzania i środków przejściowych dla PHP2Shell.

Stan 4 min czytaniaWiedza o PHP

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:

  1. zmiennej środowiskowej PHPRC,
  2. w systemie Windows wpisu rejestru IniFilePath,
  3. bieżącego katalogu roboczego, z wyjątkiem SAPI, które to wyłączają, na przykład CLI,
  4. katalogu binarnego pliku PHP lub modułu,
  5. ś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.

  1. php.ini danego SAPI
  2. Pliki dodatkowe z katalogu skanowania, alfabetycznie
  3. Konfiguracja serwera: pula FPM z php_value lub php_admin_value, VirtualHost Apache
  4. Poziom katalogu: .htaccess w mod_php, .user.ini w FPM i CGI
  5. 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.

Wskazówka

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, .htaccess i .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.

Źródła

Kontakt natychmiast

Liczy się każda godzina. Proszę napisać do nas teraz.

Proszę krótko opisać system, wersję PHP i obserwacje. Skontaktujemy się z Państwem, ustalimy sytuację i będziemy pracować zdalnie, aż incydent zostanie zamknięty i udokumentowany.

Natychmiastowa pomoc