Lyhyesti: Kun selain pyytää PHP-sivua, verkkopalvelin ottaa pyynnön vastaan ja välittää sen rajapinnan (SAPI) kautta PHP:lle. PHP kääntää komentosarjan tavukoodiksi, suorittaa sen Zend Enginessä ja palauttaa tuloksen, yleensä HTML:ää, verkkopalvelimelle. Sen jälkeen pyynnön tila siivotaan, jotta seuraava alkaa puhtaalta pöydältä.
Mitä tapahtuu, kun joku avaa verkkosivustonne?
Kävijälle se on yksi klikkaus. Palvelimella monta vaihetta etenee millisekunneissa. Kun tuntee tämän kulun, ymmärtää paremmin, miksi päivitykset, uudelleenkäynnistykset ja konfiguraatio ovat niin tärkeitä ja miksi aukko itse PHP:ssä painaa enemmän kuin aukko lisäosassa.
PHP-käsikirja mainitsee kolme osaa, joita PHP-verkkosivusto tarvitsee: PHP-tulkki (CGI:nä tai palvelinmoduulina), verkkopalvelin ja selain. Tulkki on ohjelma, joka lukee ja suorittaa PHP-koodin. Se, miten tulkki on yhdistetty verkkopalvelimeen, määrittää ajotavan.
Miten PHP toimii? Pyynnön seitsemän vaihetta
- Pyyntö: Selain lähettää palvelimelle HTTP-pyynnön, esimerkiksi
GET /kontakt.php. - Verkkopalvelin: Apache, Nginx tai LiteSpeed ottaa pyynnön vastaan. Staattiset tiedostot, kuten kuvat, se toimittaa itse.
.php-tiedostoille se kutsuu PHP:tä. - Luovutus SAPI:n kautta: Palvelinrajapinta (SAPI) välittää pyyntötiedot, kuten otsakkeet, parametrit ja lomaketiedot, PHP:lle. PHP-FPM:ssä se tapahtuu FastCGI-protokollalla, mod_php:ssä suoraan Apache-prosessissa. Lisätietoja sivulla SAPI selitettynä.
- Pyynnön valmistelu: PHP tallentaa pyyntötiedot muuttujiin, kuten
$_GET,$_POST,$_COOKIEja$_FILES, ja varaa pyynnölle muistia. - Kääntäminen: Komentosarja pilkotaan osiin (token), niistä syntyy abstrakti syntaksipuu (AST) ja siitä opcode-käskyjä, eräänlaista PHP:n konekieltä. Jos OPcache on aktiivinen, tämä vaihe ohitetaan, kun komentosarja on jo välimuistissa.
- Suoritus: Zend Enginen virtuaalikone käy opcodet läpi, kysyy tietokannoilta, lukee tiedostoja ja tuottaa tulosteen.
- Vastaus ja siivous: Tuloste palaa SAPI:n kautta verkkopalvelimelle ja sieltä selaimelle. Sen jälkeen PHP vapauttaa pyynnön muistin ja nollaa tilan.
AST on ollut olemassa PHP 7:stä lähtien. Siihen liittyvän RFC:n mukaan jäsennin tuotti sitä ennen opcodet suoraan lukemisen aikana; jako kolmeen vaiheeseen teki kääntäjästä helpommin ylläpidettävän.
Esimerkki: mitä komentosarja näkee pyynnöstä
Seuraava harmiton komentosarja näyttää, mitä tietoja PHP saa pyynnöstä ja missä ajotavassa se toimii:
<?php
header('Content-Type: text/plain; charset=utf-8');
echo 'Betriebsart (SAPI): ' . PHP_SAPI . "\n";
echo 'PHP-Version: ' . PHP_VERSION . "\n";
echo 'Methode: ' . ($_SERVER['REQUEST_METHOD'] ?? '-') . "\n";
echo 'Speicher in dieser Anfrage: ' . memory_get_usage() . " Bytes\n";
PHP-FPM:ää käyttävällä palvelimella PHP_SAPI tulostaa arvon fpm-fcgi, Apachella ja mod_php:llä arvon apache2handler. Tallentakaa tällaiset tarkistustiedostot julkiseen hakemistoon vain lyhyeksi aikaa ja älkää koskaan pysyvästi, sillä versiotiedot auttavat myös hyökkääjiä suunnistamaan.
Missä tavukoodivälimuisti ja JIT tulevat mukaan
Käännös vaiheessa 5 vie aikaa. OPcache tallentaa käsikirjan mukaan esikäännettyä tavukoodia jaettuun muistiin ja säästää PHP:ltä komentosarjojen lataamisen ja pilkkomisen jokaisella pyynnöllä. PHP 8.0:sta lähtien JIT-kääntäjä voi lisäksi tuottaa opcodeista oikeaa konekoodia. JIT-RFC:n mukaan se on lähes itsenäinen osa OPcachea.
| Vaihe | Tulos | Tallennetaanko välimuistiin? |
|---|---|---|
| Lexing | token-virta | ei |
| Parsing | abstrakti syntaksipuu (AST) | ei |
| Kääntäminen | opcodet (op-taulukot tiedostoa ja funktiota kohden) | kyllä, OPcacheen |
| JIT (valinnainen) | konekoodi | kyllä, OPcachen muistiin |
| Suoritus | sivun tuloste | ei |
Välimuisti koskee vain käännettyä koodia. Yksittäisen pyynnön tietoja, kuten lomakesyötteitä tai istuntoarvoja, ei jaeta OPcachen kautta.
Miksi PHP2Shell iskee juuri tähän kulkuun
Kumpikin PHP2Shell-haavoittuvuus koskee kulkua itseään, ei yksittäistä sovellusta. Haavoittuvuudessa CVE-2026-109618 Out-of-Memory-tila voi keskeyttää PHP:n, kun pyyntötiedot on valmisteltu vasta osittain eli vaiheessa 4. Seuraavassa siivouksessa virheellisiä tietoja voidaan sitten käsitellä kelvollisina.
Haavoittuvuudessa CVE-2026-109619 pyynnön sisäinen tila voi jäädä voimaan muistin vapauttamisen jälkeen. Myöhempi pyyntö samassa worker-prosessissa voi käyttää sitä, ennen kuin tila nollataan. Tämä koskee vaihetta 7, siivousta. Taustatiedot löytyvät sivulta CVE-2026-109619 ja artikkelista pyynnön elinkaari.
Tästä seuraa: sovelluskoodin suojatoimet, esimerkiksi tietoturvalisäosat, tehoavat vasta vaiheessa 6. PHP-tiimin mukaan mod_php:ssä on esitetty jopa hyökkäys, joka toimii ennen kuin sovelluskoodia ajetaan. Tehoavaa on vain PHP-päivitys versioon 8.5.12, 8.4.27, 8.3.36 tai 8.2.35 ja kaikkien PHP-prosessien uudelleenkäynnistys, koska pitkäikäiset worker-prosessit suorittavat muuten yhä vanhaa koodia.
Miten PHP SOS auttaa konkreettisesti?
- Kulun näkyväksi tekeminen: Selvitämme, mikä ajotapa, mikä konfiguraatio ja mikä välimuisti palvelimellanne todella on aktiivinen.
- Päivitys oikein: Asennamme PHP-päivityksen ja varmistamme käynnistysaikojen perusteella, ettei vanha prosessi enää ole käynnissä.
- Kerrosten suojaus: Palvelimen koventamisen puitteissa rajoitamme pyyntökokoja, muistia ja oikeuksia siellä, missä ne tehoavat: ennen sovelluskoodia.
- Jälkien tarkistus: Suojaamattomina tavoitettavissa olleilla palvelimilla etsimme merkkejä murrosta.
Usein kysytyt kysymykset
Käännetäänkö PHP-koodi uudelleen jokaisella kutsulla?
Ilman välimuistia kyllä: PHP pilkkoo komentosarjan, rakentaa syntaksipuun ja luo siitä opcode-käskyt. Kun OPcache on aktiivinen, opcodet ovat jaetussa muistissa ja niitä käytetään uudelleen niin kauan kuin tiedosto ei ole muuttunut.
Mitä muistiin jää pyynnön jälkeen?
Periaatteessa pyynnön tila siivotaan lopussa, jotta seuraava pyyntö alkaa puhtaalta pöydältä. Pitkäikäisiä ovat vain asiat kuten OPcache tai pysyvät yhteydet. Juuri tähän siivoukseen liittyy CVE-2026-109619.
Miksi PHP on käynnistettävä uudelleen päivityksen jälkeen?
PHP-FPM:ssä ja mod_php:ssä prosessit pysyvät käynnissä ja ovat ladanneet vanhan ohjelmakoodin. Levylle tulleet uudet tiedostot eivät muuta sitä. Vasta uudelleenkäynnistys lataa korjatun koodin.
Onko verkkopalvelin ilman PHP:tä turvallisempi?
Siinä on vähemmän hyökkäyspinta-alaa, koska mikään ohjelmalogiikka ei reagoi pyyntöihin. Pelkästään staattiselle sisällölle se on todellinen vaihtoehto. Verkkokauppoihin, lomakkeisiin ja kirjautumisiin tarvitaan kuitenkin palvelinpuolen kieli, ja silloin sen huolto ratkaisee.