# php.ini wyjaśniony: budowa, poziomy i pierwszeństwo

> php.ini wyjaśniony: gdzie PHP szuka konfiguracji, jakie są poziomy, co znaczą INI_SYSTEM i INI_PERDIR oraz która wartość obowiązuje na końcu.

Źródło: https://phpsos.de/pl/php/php-ini-erklaert/  
Stan: 25.10.2026  
Dostawca: PHP SOS, Pomoc awaryjna PHP i bezpieczeństwo serwerów. Natychmiastowa pomoc przez WhatsApp: https://wa.me/491736494914?text=Dzie%C5%84%20dobry%2C%20PHP%20SOS%2C%20potrzebujemy%20pomocy%20z%20naszym%20serwerem%20PHP.%20Firma%3A%20%E2%80%A6%20Strona%20internetowa%3A%20%E2%80%A6

**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ą:

```ini
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()`.

```bash
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](https://phpsos.de/pl/php/sapi-erklaert/).

## 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](https://phpsos.de/pl/blog/php-admin-value-sperren/).

## 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ć](https://phpsos.de/pl/php2shell/sofortmassnahmen-ohne-patch/).

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](https://phpsos.de/pl/blog/memory-limit-richtig-setzen/).

> **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](https://phpsos.de/pl/leistungen/server-haertung/) 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

- [Podręcznik PHP: plik konfiguracyjny](https://www.php.net/manual/en/configuration.file.php)
- [Podręcznik PHP: tryby zmiany ustawień INI](https://www.php.net/manual/en/configuration.changes.modes.php)
- [Podręcznik PHP: pliki .user.ini](https://www.php.net/manual/en/configuration.file.per-user.php)
- [Podręcznik PHP: ustawienia rdzenia](https://www.php.net/manual/en/ini.core.php)
