# php.ini selitettynä: rakenne, tasot ja etusija

> php.ini selitettynä: mistä PHP etsii konfiguraationsa, mitä tasoja on, mitä INI_SYSTEM ja INI_PERDIR tarkoittavat ja mikä arvo lopulta on voimassa.

Lähde: https://phpsos.de/fi/php/php-ini-erklaert/  
Tilanne: 25.10.2026  
Palveluntarjoaja: PHP SOS, PHP-hätäapu ja palvelimen tietoturva. Pikaapu WhatsAppilla: https://wa.me/491736494914?text=Hei%20PHP%20SOS%2C%20tarvitsemme%20apua%20PHP-palvelimemme%20kanssa.%20Yritys%3A%20%E2%80%A6%20Verkkosivusto%3A%20%E2%80%A6

**Lyhyesti:** php.ini on PHP:n keskeinen konfiguraatiotiedosto. PHP lukee sen käynnistyessään, palvelinmoduuleissa kerran, CGI:ssä ja CLI:ssä jokaisella kutsulla. Lisäksi tulevat hakuhakemiston lisätiedostot, asetukset FPM-poolissa tai Apachessa, `.htaccess` tai `.user.ini` sekä `ini_set()` koodissa. Mikä taso saa muuttaa arvoa, määrää arvon muutostila, esimerkiksi `INI_SYSTEM` tai `INI_PERDIR`. Arvoja, jotka on asetettu `php_admin_value`-direktiivillä, sovellus ei enää voi ohittaa.

## Mikä php.ini on?

php.ini on tekstitiedosto, jonka merkinnät noudattavat mallia `name = wert`. Se määrää, miten PHP käyttäytyy: kuinka paljon muistia komentosarja saa käyttää, näkyvätkö virheet selaimessa, miten istunnot toimivat ja mitkä laajennukset ladataan. Kommentit alkavat puolipisteellä.

PHP-käsikirjan mukaan tiedosto luetaan PHP:n käynnistyessä. Palvelinmoduuleissa kuten mod_php se tapahtuu vain kerran, verkkopalvelimen käynnistyessä, CGI:ssä ja CLI:ssä jokaisella kutsulla. PHP-FPM lukee konfiguraationsa käynnistyessään ja palvelun uudelleenlatauksessa. Muutos ilman uudelleenkäynnistystä tai reloadia ei siksi yleensä tule voimaan.

PHP 8.3:sta lähtien merkintä voi käsikirjan mukaan viitata ympäristömuuttujaan, jolla on varaarvo:

```ini
memory_limit = ${PHP_MEMORY_LIMIT}
max_execution_time = ${PHP_MAX_EXECUTION_TIME:-30}
```

## Mistä PHP etsii php.ini-tiedostoa?

Käsikirja kuvaa kiinteän järjestyksen. Ensin pätee nimenomaisesti asetettu polku, esimerkiksi `PHPIniDir` Apachessa tai valinta `-c` CGI:ssä ja CLI:ssä. Muuten PHP rakentaa hakupolun seuraavista:

1. ympäristömuuttuja `PHPRC`,
2. Windowsissa rekisterimerkintä `IniFilePath`,
3. nykyinen työhakemisto, paitsi SAPI:illa, jotka kytkevät sen pois, kuten CLI,
4. PHP-binaarin tai moduulin hakemisto,
5. käännösvaiheessa asetettu polku `--with-config-file-path`.

Tältä hakupolulta PHP etsii ensin tiedostoa `php-SAPI.ini`, esimerkiksi `php-cli.ini`, ja vasta sen jälkeen tiedostoa `php.ini`. Sen jälkeen PHP lukee aakkosjärjestyksessä kaikki `.ini`-tiedostot hakuhakemistosta, joka on määritetty `PHP_INI_SCAN_DIR`-muuttujalla tai käännösvaiheessa `--with-config-file-scan-dir`-valinnalla. Mitkä tiedostot on ladattu, näyttää `php --ini` tai funktio `php_ini_scanned_files()`.

```bash
php --ini
php -r 'var_dump(php_ini_loaded_file(), php_ini_scanned_files());'
```

Molemmat komennot näyttävät komentorivin tilan. Verkkosivustolle voi päteä toinen tiedosto, koska jokaisella SAPI:lla voi olla oma konfiguraationsa; lisää sivulla [SAPI selitettynä](https://phpsos.de/fi/php/sapi-erklaert/).

## Muutostilat: kuka saa asettaa minkäkin arvon?

Kaikkia asetuksia ei saa asettaa kaikkialla. Käsikirja antaa jokaiselle direktiiville muutostilan:

| Tila | Missä arvon saa asettaa |
|---|---|
| `INI_USER` | komentosarjoissa `ini_set()`-funktiolla, Windowsin rekisterissä ja `.user.ini`-tiedostossa |
| `INI_PERDIR` | php.ini-tiedostossa, `.htaccess`-tiedostossa, `httpd.conf`-tiedostossa tai `.user.ini`-tiedostossa |
| `INI_SYSTEM` | vain php.ini-tiedostossa tai `httpd.conf`-tiedostossa |
| `INI_ALL` | kaikkialla |

Esimerkkejä käsikirjasta: `memory_limit`-asetuksen tila on `INI_ALL` ja oletus `128M`, `post_max_size`-asetuksen tila on `INI_PERDIR` ja oletus `8M`, `upload_max_filesize`-asetuksen tila on `INI_PERDIR` ja oletus `2M`. `expose_php` saa olla vain php.ini-tiedostossa.

Käsikirjan mukaan `.user.ini`-tiedostoja lukevat vain CGI- ja FastCGI-SAPI:t, siis myös PHP-FPM. PHP etsii niitä komentosarjan hakemistosta ylöspäin aina Document Rootiin asti ja lukee ne oletuksena uudelleen enintään 300 sekunnin välein (`user_ini.cache_ttl`). mod_php:ssä tämän roolin hoitaa `.htaccess`.

## Mikä arvo on lopulta voimassa? Tasot etusijajärjestyksessä

Yksinkertaistettuna: mitä myöhemmin taso tulee voimaan, sitä todennäköisemmin sen arvo pätee, jos muutostila sen sallii.

1. kyseisen SAPI:n **php.ini**
2. **lisätiedostot** hakuhakemistosta, aakkosjärjestyksessä
3. **palvelinkonfiguraatio:** FPM-pooli direktiiveillä `php_value` tai `php_admin_value`, Apachen VirtualHost
4. **hakemistotaso:** `.htaccess` mod_php:ssä, `.user.ini` FPM:ssä ja CGI:ssä
5. **ajonaikainen:** `ini_set()` sovelluskoodissa

Poikkeus on ratkaiseva: käsikirjan mukaan `php_admin_value`- tai `php_admin_flag`-direktiivillä asetettuja arvoja ei voi ohittaa `ini_set()`-funktiolla. Näin ylläpitäjät lukitsevat tietoturvan kannalta olennaiset asetukset sovellukselta. Tämä on kuvattu tarkemmin artikkelissa [php_admin_value: asetusten lukitseminen ohittamista vastaan](https://phpsos.de/fi/blog/php-admin-value-sperren/).

## php.ini PHP2Shellin jälkeen: mikä on muuttunut

Php.netin PHP2Shell-väliaikaistoimet ovat lähes kaikki INI-asetuksia: `memory_limit=-1` lukittuna ohittamista vastaan, rajattu `post_max_size`, `session.upload_progress.enabled=0` ja PHP 8.5:ssä `fatal_error_backtraces=0`. Php.net korostaa, ettei `session.upload_progress.enabled`-asetusta pidä asettaa `ini_set()`-funktiolla tai `.user.ini`-tiedostolla, vaan php.ini-tiedostossa, FPM-poolissa tai palvelinkonfiguraatiossa, ja sen jälkeen kaikki workerit käynnistetään uudelleen. Täydellinen luettelo on sivulla [Pikatoimet, jos ette voi vielä päivittää](https://phpsos.de/fi/php2shell/sofortmassnahmen-ohne-patch/).

Korjattujen versioiden 8.5.12, 8.4.27, 8.3.36 ja 8.2.35 myötä myös `memory_limit` on käsikirjan mukaan muuttunut: se on nyt pehmeä raja. Uusi asetus `memory_hard_limit_percent` määrittää kovan rajan. Ilman omaa arvoa se on kaksinkertainen `memory_limit`-arvoon nähden, yli `1G`-arvoilla arvo plus `1G`. Jos raja ylittyy, prosessi päättyy heti poistumistilaan 137. Miten molemmat rajat valitaan järkevästi, selittää [memory_limit oikein](https://phpsos.de/fi/blog/memory-limit-richtig-setzen/).

> **Vinkki:**
> Käsikirjan mukaan pätee: jos PHP-versio ei tunne asetusta `memory_hard_limit_percent`, se on haavoittuvuuksien CVE-2026-109618 ja CVE-2026-109619 piirissä. Backportteja käyttävissä jakeluissa tilan osoittaa lisäksi paketin muutosloki.

## Miten PHP SOS auttaa konkreettisesti?

- **Voimassa olevien arvojen selvitys:** Luemme jokaiselle SAPI:lle, mitkä tiedostot ladataan ja mikä arvo on lopulta voimassa.
- **Tasojen siivous:** Poistamme ristiriitaiset merkinnät paneeleista, pooleista, `.htaccess`- ja `.user.ini`-tiedostoista.
- **Lukitusten asettaminen:** [Palvelimen koventamisen](https://phpsos.de/fi/leistungen/server-haertung/) puitteissa määritämme tietoturvan kannalta olennaiset arvot `php_admin_value`-direktiivillä.
- **Todentaminen:** Dokumentoimme asetukset ja uudelleenkäynnistyksen, jotta tila voidaan myöhemmin osoittaa.


## Usein kysytyt kysymykset

**Missä php.ini sijaitsee?**  
Se riippuu käyttöjärjestelmästä, paketista ja SAPI:sta. Debianissa ja Ubuntussa jokaista versiota ja SAPI:a varten on omat kansionsa, esimerkiksi /etc/php/8.3/fpm/php.ini ja /etc/php/8.3/cli/php.ini. Komentorivillä php --ini näyttää ladatut tiedostot, verkkosivustolle auttaa php_ini_loaded_file() tilapäisessä tarkistustiedostossa.

**Missä järjestyksessä conf.d-kansion tiedostot luetaan?**  
PHP-käsikirjan mukaan PHP lukee kaikki .ini-päätteiset tiedostot hakuhakemistosta aakkosjärjestyksessä. Myöhemmät tiedostot ohittavat aiempien arvot. Siksi monien tiedostojen nimessä on numeroita kuten 20- tai 99-.

**Miksi php.ini-muutokseni ei tehoa?**  
Yleisiä syitä: muutettiin toisen SAPI:n tiedostoa, palvelua ei käynnistetty uudelleen, arvo FPM-poolissa, Apachen konfiguraatiossa tai .user.ini-tiedostossa ohittaa sen, tai hosting-paneeli kirjoittaa tiedoston uudelleen seuraavalla tallennuksella.

**Mikä on memory_hard_limit_percent?**  
Uusi asetus, joka otettiin PHP-käsikirjan mukaan käyttöön 21.10.2026 julkaistuissa tietoturvajulkaisuissa. Se määrittää kovan muistirajan prosenttiosuutena memory_limit-arvosta. Käsikirja huomauttaa, että PHP-versio, joka ei tunne tätä asetusta, on PHP2Shell-haavoittuvuuksien piirissä.

## Lähteet

- [PHP-käsikirja: konfiguraatiotiedosto](https://www.php.net/manual/en/configuration.file.php)
- [PHP-käsikirja: INI-muutostilat](https://www.php.net/manual/en/configuration.changes.modes.php)
- [PHP-käsikirja: .user.ini-tiedostot](https://www.php.net/manual/en/configuration.file.per-user.php)
- [PHP-käsikirja: ydinasetukset](https://www.php.net/manual/en/ini.core.php)
