# De php.ini uitgelegd: opbouw, niveaus en voorrang

> De php.ini uitgelegd: waar PHP zijn configuratie zoekt, welke niveaus er zijn, wat INI_SYSTEM en INI_PERDIR betekenen en welke waarde uiteindelijk geldt.

Bron: https://phpsos.de/nl/php/php-ini-erklaert/  
Stand: 25-10-2026  
Aanbieder: PHP SOS, PHP-noodhulp en serverbeveiliging. Directe hulp via WhatsApp: https://wa.me/491736494914?text=Hallo%20PHP%20SOS%2C%20wij%20hebben%20hulp%20nodig%20met%20onze%20PHP-server.%20Bedrijf%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**Kort gezegd:** De php.ini is het centrale configuratiebestand van PHP. PHP leest het bij het starten, bij servermodules eenmaal, bij CGI en CLI bij elke aanroep. Daarbij komen extra bestanden uit een scanmap, instellingen in de FPM-pool of in Apache, `.htaccess` of `.user.ini` en `ini_set()` in de code. Welk niveau een waarde mag wijzigen, bepaalt zijn wijzigingsmodus, bijvoorbeeld `INI_SYSTEM` of `INI_PERDIR`. Waarden via `php_admin_value` kan de toepassing niet meer overschrijven.

## Wat is de php.ini?

De php.ini is een tekstbestand met vermeldingen volgens het patroon `name = wert`. Het bepaalt hoe PHP zich gedraagt: hoeveel geheugen een script mag gebruiken, of fouten in de browser verschijnen, hoe sessies werken en welke extensies worden geladen. Commentaar begint met een puntkomma.

Volgens de PHP-handleiding wordt het bestand gelezen bij het starten van PHP. Bij servermodules als mod_php gebeurt dat maar één keer, bij het starten van de webserver, bij CGI en CLI bij elke aanroep. PHP-FPM leest zijn configuratie bij het starten en bij het herladen van de dienst. Een wijziging zonder herstart of reload werkt daarom meestal niet.

Sinds PHP 8.3 kan een vermelding volgens de handleiding naar een omgevingsvariabele met vervangende waarde verwijzen:

```ini
memory_limit = ${PHP_MEMORY_LIMIT}
max_execution_time = ${PHP_MAX_EXECUTION_TIME:-30}
```

## Waar zoekt PHP naar de php.ini?

De handleiding beschrijft een vaste volgorde. Eerst geldt een uitdrukkelijk ingesteld pad, bijvoorbeeld `PHPIniDir` in Apache of de optie `-c` bij CGI en CLI. Anders bouwt PHP een zoekpad op uit:

1. de omgevingsvariabele `PHPRC`,
2. onder Windows de registervermelding `IniFilePath`,
3. de huidige werkmap, behalve bij SAPI's die dat uitschakelen, zoals de CLI,
4. de map van het PHP-binaire bestand of van de module,
5. het bij het compileren ingestelde pad `--with-config-file-path`.

In dit zoekpad zoekt PHP eerst een bestand `php-SAPI.ini`, bijvoorbeeld `php-cli.ini`, en pas daarna `php.ini`. Vervolgens leest PHP alle `.ini`-bestanden uit de scanmap, die via `PHP_INI_SCAN_DIR` of bij het compileren via `--with-config-file-scan-dir` is vastgelegd, in alfabetische volgorde. Welke bestanden zijn geladen, toont `php --ini` of de functie `php_ini_scanned_files()`.

```bash
php --ini
php -r 'var_dump(php_ini_loaded_file(), php_ini_scanned_files());'
```

Beide opdrachten tonen de stand van de opdrachtregel. Voor de website kan een ander bestand gelden, omdat elke SAPI zijn eigen configuratie kan hebben; meer daarover onder [SAPI uitgelegd](https://phpsos.de/nl/php/sapi-erklaert/).

## Wijzigingsmodi: wie mag welke waarde instellen?

Niet elke instelling mag overal worden gezet. De handleiding wijst aan elke directive een wijzigingsmodus toe:

| Modus | Waar de waarde mag worden ingesteld |
|---|---|
| `INI_USER` | in scripts via `ini_set()`, in het Windows-register en in `.user.ini` |
| `INI_PERDIR` | in php.ini, `.htaccess`, `httpd.conf` of `.user.ini` |
| `INI_SYSTEM` | alleen in php.ini of `httpd.conf` |
| `INI_ALL` | overal |

Voorbeelden uit de handleiding: `memory_limit` heeft de modus `INI_ALL` en de standaardwaarde `128M`, `post_max_size` heeft `INI_PERDIR` en de standaardwaarde `8M`, `upload_max_filesize` heeft `INI_PERDIR` en de standaardwaarde `2M`. `expose_php` mag alleen in de php.ini staan.

`.user.ini`-bestanden worden volgens de handleiding alleen door CGI- en FastCGI-SAPI's gelezen, dus ook door PHP-FPM. PHP zoekt ze vanaf de map van het script omhoog tot de document root en leest ze standaard hoogstens elke 300 seconden opnieuw (`user_ini.cache_ttl`). Onder mod_php neemt `.htaccess` deze rol over.

## Welke waarde geldt uiteindelijk? De niveaus in voorrang

Vereenvoudigd geldt: hoe later een niveau ingrijpt, hoe eerder zijn waarde doorslaggevend is, voor zover de wijzigingsmodus dat toestaat.

1. **php.ini** van de betreffende SAPI
2. **Extra bestanden** uit de scanmap, alfabetisch
3. **Serverconfiguratie:** FPM-pool met `php_value` resp. `php_admin_value`, Apache-VirtualHost
4. **Mapniveau:** `.htaccess` bij mod_php, `.user.ini` bij FPM en CGI
5. **Uitvoeringstijd:** `ini_set()` in de toepassingscode

De uitzondering is beslissend: waarden via `php_admin_value` of `php_admin_flag` kunnen volgens de handleiding niet met `ini_set()` worden overschreven. Daarmee vergrendelen beheerders beveiligingsrelevante instellingen tegen de toepassing. Uitvoerig beschreven staat dat onder [php_admin_value: instellingen tegen overschrijven vergrendelen](https://phpsos.de/nl/blog/php-admin-value-sperren/).

## De php.ini na PHP2Shell: wat er is veranderd

De tussenmaatregelen van php.net voor PHP2Shell zijn bijna allemaal INI-instellingen: `memory_limit=-1` vergrendeld tegen overschrijven, een beperkte `post_max_size`, `session.upload_progress.enabled=0` en op PHP 8.5 `fatal_error_backtraces=0`. php.net benadrukt dat `session.upload_progress.enabled` niet via `ini_set()` of `.user.ini` moet worden ingesteld, maar in php.ini, FPM-pool of serverconfiguratie, met aansluitend een herstart van alle workers. De volledige lijst staat onder [Noodmaatregelen als u nog niet kunt patchen](https://phpsos.de/nl/php2shell/sofortmassnahmen-ohne-patch/).

Met de verholpen versies 8.5.12, 8.4.27, 8.3.36 en 8.2.35 is volgens de handleiding ook `memory_limit` gewijzigd: het is nu een zachte grens. De nieuwe instelling `memory_hard_limit_percent` legt een harde grens vast. Zonder eigen waarde bedraagt ze het dubbele van `memory_limit`, bij meer dan `1G` de waarde plus `1G`. Wordt ze overschreden, dan eindigt het proces direct met exitstatus 137. Hoe u beide grenzen zinvol kiest, legt [memory_limit juist instellen](https://phpsos.de/nl/blog/memory-limit-richtig-setzen/) uit.

> **Tip:**
> Volgens de handleiding geldt: herkent een PHP-versie `memory_hard_limit_percent` niet, dan is ze door CVE-2026-109618 en CVE-2026-109619 getroffen. Bij distributies met backports bewijst bovendien de changelog van het pakket de stand.

## Hoe helpt PHP SOS concreet?

- **Werkzame waarden vaststellen:** Wij lezen voor elke SAPI uit welke bestanden worden geladen en welke waarde uiteindelijk geldt.
- **Niveaus opruimen:** Wij verwijderen tegenstrijdige vermeldingen uit panelen, pools, `.htaccess` en `.user.ini`.
- **Vergrendelingen instellen:** In het kader van de [serverhardening](https://phpsos.de/nl/leistungen/server-haertung/) leggen wij beveiligingsrelevante waarden vast via `php_admin_value`.
- **Aantonen:** Wij documenteren instellingen en herstart, zodat de stand later aantoonbaar is.


## Veelgestelde vragen

**Waar staat de php.ini?**  
Dat hangt af van besturingssysteem, pakket en SAPI. Onder Debian en Ubuntu zijn er per versie en SAPI eigen mappen, bijvoorbeeld /etc/php/8.3/fpm/php.ini en /etc/php/8.3/cli/php.ini. Op de opdrachtregel toont php --ini de geladen bestanden, voor de website helpt php_ini_loaded_file() in een kortstondig testbestand.

**In welke volgorde worden de bestanden in de map conf.d gelezen?**  
Volgens de PHP-handleiding leest PHP alle bestanden met de extensie .ini in de scanmap in alfabetische volgorde. Latere bestanden overschrijven waarden van eerdere. Daarom hebben veel bestanden cijfers als 20- of 99- in de naam.

**Waarom werkt mijn wijziging in de php.ini niet?**  
Veelvoorkomende redenen: het bestand van een andere SAPI is gewijzigd, de dienst is niet opnieuw gestart, een waarde in de FPM-pool, in de Apache-configuratie of in een .user.ini overschrijft hem, of een hostingpaneel schrijft het bestand bij de volgende opslag opnieuw.

**Wat is memory_hard_limit_percent?**  
Een nieuwe instelling die volgens de PHP-handleiding met de beveiligingsreleases van 21-10-2026 is ingevoerd. Ze legt een harde geheugengrens vast als percentage van memory_limit. De handleiding wijst erop dat een PHP-versie die deze instelling niet kent, door de PHP2Shell-lekken is getroffen.

## Bronnen

- [PHP-handleiding: het configuratiebestand](https://www.php.net/manual/en/configuration.file.php)
- [PHP-handleiding: INI-wijzigingsmodi](https://www.php.net/manual/en/configuration.changes.modes.php)
- [PHP-handleiding: .user.ini-bestanden](https://www.php.net/manual/en/configuration.file.per-user.php)
- [PHP-handleiding: kerninstellingen](https://www.php.net/manual/en/ini.core.php)
