# Päringu elutsükkel: käivitus, täitmine, lõpetamine

> PHP Request Lifecycle selgitatud: MINIT, RINIT, RSHUTDOWN, MSHUTDOWN, workerite taaskasutus ja miks CVE-2026-109619 just siin rünnakut alustab.

Allikas: https://phpsos.de/et/php/request-lebenszyklus/  
Seis: 25.10.2026  
Pakkuja: PHP SOS, PHP hädaabi ja serveri turvalisus. Kohene abi WhatsAppis: https://wa.me/491736494914?text=Tere%2C%20PHP%20SOS%2C%20vajame%20abi%20oma%20PHP-serveriga.%20Ettev%C3%B5te%3A%20%E2%80%A6%20Veebisait%3A%20%E2%80%A6

**Lühidalt:** PHP Request Lifecycle'il on kaks taset. Üks kord protsessi kohta laeb PHP oma laiendused (faas MINIT) ja lammutab need lõpus uuesti (MSHUTDOWN). Iga üksiku päringu jaoks on oma käivitus- ja koristusfaas (RINIT ja RSHUTDOWN). Veebitöös töötleb worker paljusid päringuid järjest, seetõttu peab PHP kahe päringu vahel kogu päringu seisundi usaldusväärselt lähtestama. Just sellel piiril asus CVE-2026-109619, teine PHP2Shelli turvaauk.

## Kaks taset: protsess ja päring

Mitte-tehnikule aitab pilt: PHP worker on nagu ametiasutuse teenindusaken. Aken seatakse hommikul ühe korra sisse, vormide, templite ja arvutiga. Seejärel tulevad järjest paljud külastajad. Pärast iga külastajat peab laud olema tühi, et järgmine ei näeks võõraid dokumente.

PHP töötab samamoodi. Protsessi käivitamisel laeb see laiendused ja sätted, mis on kõigi päringute jaoks samad. Iga päring saab seejärel oma mälu, oma muutujad ja oma päringuandmed, nagu `$_GET`, `$_POST` või `$_FILES`. Päringu lõpus vabastab PHP selle mälu. PHP Internals Book võtab selle lühidalt kokku: PHP unustab päringu mälu iga päringu lõpus.

## PHP Request Lifecycle'i faasid ülevaatlikult

Nimed pärinevad PHP sisemusest; iga laiendus võib end nendesse faasidesse haakida.

| Faas | Millal käivitub | Kui tihti | Tüüpiline ülesanne |
|---|---|---|---|
| MINIT (Module Init) | protsessi käivitamisel | üks kord protsessi kohta | laiendite registreerimine, ini-kirjete loomine, püsivad andmed |
| GINIT | globaalide loomisel | protsessi kohta, lõimede puhul lõime kohta | laiendi globaalsete muutujate ettevalmistamine |
| RINIT (Request Init) | iga päringu alguses | päringu kohta | päringu mälu ja seisundi ettevalmistamine |
| Täitmine | vahepeal | päringu kohta | teie PHP kood töötab |
| RSHUTDOWN | iga päringu lõpus | päringu kohta | päringu ressursside vabastamine |
| PRSHUTDOWN | pärast RSHUTDOWN-i | päringu kohta, harva kasutatud | viimased koristustööd |
| MSHUTDOWN | protsessi lõpetamisel | üks kord protsessi kohta | püsivate andmete vabastamine |

Oluline lause PHP Internals Book'ist laiendite arendajatele: globaale ei tühjendata pärast iga päringut automaatselt. Mis peab päringu kohta värske olema, tuleb RINIT-is lähtestada. See reegel näitab, miks piir kahe päringu vahel on turvakriitiline koht.

Ka päringu lõpus on järjekord fikseeritud: kõigepealt käivituvad shutdown-funktsioonid, mille olete registreerinud käsuga `register_shutdown_function()`, siis destruktorid, seejärel tühjendatakse väljundipuhver. Alles pärast seda järgneb RSHUTDOWN.

## Miks workereid taaskasutatakse

Käsureal töötleb protsess täpselt ühe päringu ja lõpeb. Veebitöös oleks see liiga aeglane. PHP-FPM, Apache koos mod_php-ga, LiteSpeed ja FrankenPHP hoiavad seetõttu valmis workereid, mis teenindavad palju päringuid järjest. MINIT käivitub siis ühe korra, RINIT ja RSHUTDOWN tuhandeid kordi. Kuidas FPM oma workereid juhib, selgitab [PHP-FPM selgitus](https://phpsos.de/et/php/php-fpm-erklaert/).

PHP-FPM-is määrab `pm.max_requests`, mitme päringu järel worker uuesti käivitub. Vaikeväärtus on `0`, ehk piiramatu. Käsiraamat nimetab säte vahendina kolmandate osapoolte teekide mälulekete vastu:

```ini
; FPM-pool: worker uuesti käivitada 500 päringu järel (mälulekete vastu)
pm = dynamic
pm.max_children = 20
pm.max_requests = 500
```

Veelgi kaugemale läheb FrankenPHP worker-režiim: seal käivitub kogu rakendus ühe korra ja jääb mällu. Rakenduse seisund jääb siis püsima ka PHP tasemel. Näide näitab vahet:

```php
<?php
function anfrageZaehler(): int
{
    static $zaehler = 0;   // klassikalises FPM töös on päringu kohta jälle 0
    return ++$zaehler;     // worker-režiimis loeb väärtus päringute üle edasi
}
echo anfrageZaehler();
```

Klassikalises töös väljastab väljakutse alati 1, sest PHP viskab päringu mälu minema. Worker-režiimis väärtus kasvab seni, kuni worker elab. FrankenPHP dokumentatsioon soovitab seetõttu päringuga seotud seisund päringute vahel teadlikult lähtestada.

## Kus CVE-2026-109619 rünnakut alustab

CVE-2026-109619 ei puuduta teie rakenduse koodi, vaid PHP-d ennast. php.net andmetel võis päringuga seotud sisemine seisund oma mälu vabastamise üle elada. Hilisem päring samas workeris võis seda kasutada, enne kui lähtestamine selle tagasi seadis. Pildis: teenindusakna lauale jäi paber, mis oleks pidanud juba ära koristatud olema. Ekspluateerimise üksikasju me teadlikult ei avalda; turvaaugu paigutust käsitleb [CVE-2026-109619](https://phpsos.de/et/php2shell/cve-2026-109619/).

php.net ajutised meetmed selle turvaaugu vastu lähtuvad kinnitatud teedest, need ei ole täielik kaitse:

1. `session.upload_progress.enabled=0` php.ini-s, FPM-poolis või serveri seadistuses, seejärel kõik workerid uuesti käivitada; mitte kaudu `ini_set()` või `.user.ini`.
2. PHP 8.5 puhul lisaks `fatal_error_backtraces=0` ja taaskäivitus.
3. Eemaldada päringu kohta kehtetud või iganenud sätted, mis tekitavad teateid enne lähtestamist. Teateid üksnes peitmine ei aita php.net järgi.
4. Kõrvaldada rakenduses väljastpoolt esilekutsutavad fataalsed vead ja ajaületused, ka callback'ides ning üleslaadimise ja impordi töötluses.

Tegelik lahendus on uuendus versioonile PHP 8.5.12, 8.4.27, 8.3.36 või 8.2.35. Kuna viga on töötavas workeris, mõjub see alles kõigi protsesside taaskäivitusel; sammud on lehel [PHP-FPM-i ja kõigi workerite taaskäivitamine](https://phpsos.de/et/php2shell/php-fpm-neustart/).

> **Näpunäide:**
> Kontrollige pärast taaskäivitust käsuga `ps -eo pid,lstart,cmd | grep php`, kas kõik PHP protsessid on käivitatud pärast uuenduse ajahetke.

## Mida elutsükkel tähendab töö ja arenduse jaoks

Mudelist saab tuletada selged reeglid. Adminnidele: uuendus on mõjus alles siis, kui ükski vana koodiga protsess enam ei tööta. Iga pikaealiste workeritega töörežiim vajab dokumenteeritud taaskäivitust. Arendajatele: worker-režiimides töötav kood ei tohi jätta päringuga seotud seisundit staatilistesse muutujatesse ega singleton'idesse, näiteks kasutajaandmeid või õigusi. Mõlemale kehtib: säilitage logid alates 20.10.2026, et hiljem hinnata, kas enne paika midagi juhtus.

## Kuidas PHP SOS konkreetselt aitab?

[PHP paikamisteenusega](https://phpsos.de/et/leistungen/php-patch-service/) viime mudeli praktikas ellu:

- **Töörežiimi tuvastamine:** Selgitame välja, kas töötab PHP-FPM, mod_php, LiteSpeed, FrankenPHP või php-cgi ja kuidas workereid hallatakse.
- **Uuendus ja taaskäivitus:** Paigaldame parandatud versiooni ja käivitame iga workeri kontrollitult uuesti.
- **Protsesside kontroll:** Tõendame käivitusaegade ja versioonide põhjal, et ühtegi vana protsessi ei ole alles.
- **Worker-režiimide kontroll:** Pikaealiste rakenduste puhul vaatame, kas päringuga seotud seisund lähtestatakse puhtalt.


## Korduma kippuvad küsimused

**Kas PHP käivitab iga päringu jaoks uue protsessi?**  
Käsureal jah, veebitöös enamasti mitte. PHP-FPM, Apache koos mod_php-ga, LiteSpeed või FrankenPHP laseb ühel protsessil töödelda paljusid päringuid järjest. Päringute vahel koristab PHP päringu seisundi.

**Mis vahe on MINIT-il ja RINIT-il?**  
MINIT käivitub ühe korra, kui PHP protsess käivitub, ja loob püsivad struktuurid. RINIT käivitub iga üksiku päringu alguses ja valmistab ette selle, mida vajab ainult see päring.

**Kas pm.max_requests aitab CVE-2026-109619 vastu?**  
php.net ei nimeta sagedasemaid workerite taaskäivitusi ajutise meetmena. Säte piirab ainult seda, mitu päringut worker töötleb, enne kui ta uuesti käivitub. Turvaaugu vastu aitab uuendus koos kõigi workerite järgneva taaskäivitusega.

**Mis on FrankenPHP worker-režiim?**  
Worker-režiimis käivitub rakendus ühe korra ja jääb mällu. See säästab aega, kuid staatilised muutujad, globaalid ja vahemälud säilivad päringute vahel. FrankenPHP dokumentatsiooni järgi tuleb päringuga seotud seisund seetõttu teadlikult lähtestada.

## Allikad

- [php.net: turvateade 21.10.2026](https://www.php.net/)
- [PHP käsiraamat: FPM-i seadistus](https://www.php.net/manual/en/install.fpm.configuration.php)
- [PHP Internals Book: PHP elutsükkel](https://www.phpinternalsbook.com/)
