# Hogyan állít elő a PHP weboldalt: egy kérés útja

> Hogyan működik a PHP? A böngészőbeli kattintástól a webszerveren, a SAPI-n, a fordítón és a Zend VM-en át a kész oldalig, hét lépésben, példákkal.

Forrás: https://phpsos.de/hu/php/wie-php-funktioniert/  
Állapot: 2026. 10. 25.  
Szolgáltató: PHP SOS, PHP-vészhelyzeti segítség és szerverbiztonság. Azonnali segítség WhatsAppon: https://wa.me/491736494914?text=%C3%9Cdv%C3%B6zl%C3%B6m%2C%20PHP%20SOS%21%20Seg%C3%ADts%C3%A9gre%20van%20sz%C3%BCks%C3%A9g%C3%BCnk%20a%20PHP-szerver%C3%BCnkkel.%20C%C3%A9g%3A%20%E2%80%A6%20Weboldal%3A%20%E2%80%A6

**Röviden:** Amikor egy böngésző PHP-oldalt kér, a webszerver fogadja a kérést, és egy felületen (SAPI) keresztül továbbadja a PHP-nek. A PHP a szkriptet bájtkóddá fordítja, a Zend Engine-ben végrehajtja, az eredményt, többnyire HTML-t, pedig visszaadja a webszervernek. Ezután a kérés állapotát feltakarítják, hogy a következő tisztán indulhasson.

## Mi történik, amikor valaki megnyitja a weboldalát?

A látogatónak ez egy kattintás. A szerveren ezredmásodpercek alatt sok lépés zajlik le. Aki ismeri ezt a folyamatot, jobban érti, miért olyan fontosak a frissítések, az újraindítások és a konfiguráció, és miért nyom többet a latban egy magában a PHP-ban lévő rés, mint egy bővítményben lévő.

A PHP-kézikönyv három összetevőt nevez meg, amelyek egy PHP-weboldalhoz szükségesek: a PHP-értelmezőt (CGI-ként vagy szervermodulként), egy webszervert és egy böngészőt. Az értelmező az a program, amely a PHP-kódot beolvassa és végrehajtja. Az üzemmódot az határozza meg, hogyan kapcsolódik a webszerverhez.

## Hogyan működik a PHP? Egy kérés hét lépése

1. **Kérés:** A böngésző HTTP-kérést küld a szervernek, például `GET /kontakt.php`.
2. **Webszerver:** Az Apache, az Nginx vagy a LiteSpeed fogadja a kérést. A statikus fájlokat, például a képeket maga szolgáltatja ki. A `.php` fájlokhoz meghívja a PHP-t.
3. **Átadás a SAPI-n keresztül:** A szerverfelület (SAPI) átadja a PHP-nek a kérés adatait, például a fejléceket, a paramétereket és az űrlapadatokat. PHP-FPM esetén ez a FastCGI protokollon keresztül történik, mod_php esetén közvetlenül az Apache-folyamatban. Részletek: [A SAPI elmagyarázva](https://phpsos.de/hu/php/sapi-erklaert/).
4. **A kérés előkészítése:** A PHP a kérés adatait olyan változókba teszi, mint a `$_GET`, a `$_POST`, a `$_COOKIE` és a `$_FILES`, és memóriát foglal a kérésnek.
5. **Fordítás:** A szkriptet építőelemekre (tokenekre) bontja, ebből absztrakt szintaxisfa (AST), abból pedig opcode-ok keletkeznek, a PHP számára egyfajta gépi nyelv. Ha az OPcache aktív, ez a lépés kimarad, amennyiben a szkript már a gyorsítótárban van.
6. **Végrehajtás:** A [Zend Engine](https://phpsos.de/hu/php/zend-engine/) virtuális gépe feldolgozza az opcode-okat, adatbázisokat kérdez le, fájlokat olvas, és előállítja a kimenetet.
7. **Válasz és feltakarítás:** A kimenet a SAPI-n keresztül visszakerül a webszerverhez, onnan pedig a böngészőhöz. Ezután a PHP felszabadítja a kérés memóriáját, és visszaállítja az állapotot.

Az AST a PHP 7 óta létezik. A hozzá tartozó RFC szerint korábban az elemző közvetlenül, beolvasás közben állította elő az opcode-okat; a három fázisra bontás egyszerűbben karbantarthatóvá tette a fordítót.

## Példa: mit lát a szkript a kérésből

A következő ártalmatlan szkript megmutatja, milyen információkat kap a PHP a kérésből, és milyen üzemmódban fut:

```php
<?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-es szerveren a `PHP_SAPI` értéke `fpm-fcgi`, Apache és mod_php alatt `apache2handler`. Az ilyen ellenőrző fájlokat csak rövid időre, és soha ne tartósan tegye a nyilvános könyvtárba, mert a verziómegjelölések a támadóknak is segítenek a tájékozódásban.

## Hol jön képbe a bájtkód-gyorsítótár és a JIT

Az 5. lépés fordítása időt vesz igénybe. Az [OPcache](https://phpsos.de/hu/php/opcache/) a kézikönyv szerint előre lefordított bájtkódot tárol a közös memóriában, és így megkíméli a PHP-t attól, hogy minden kérésnél betöltse és szétbontsa a szkripteket. A PHP 8.0 óta emellett egy JIT-fordító is képes az opcode-okból valódi gépi kódot előállítani. A JIT-RFC szerint ez az OPcache szinte önálló része.

| Fázis | Eredmény | Gyorsítótárazzák? |
|---|---|---|
| Lexikális elemzés | tokenfolyam | nem |
| Szintaktikai elemzés | absztrakt szintaxisfa (AST) | nem |
| Fordítás | opcode-ok (op-tömbök fájlonként és függvényenként) | igen, az OPcache-ben |
| JIT (opcionális) | gépi kód | igen, az OPcache memóriájában |
| Végrehajtás | az oldal kimenete | nem |

A gyorsítótár csak a lefordított kódot érinti. Az egyes kérések adatait, például az űrlapbevitelt vagy a munkamenet-értékeket, az OPcache nem osztja meg.

## Miért éppen ennél a folyamatnál támad a PHP2Shell

A két PHP2Shell-rés nem egy alkalmazást érint, hanem magát a folyamatot. A CVE-2026-109618 esetén egy memóriahiányos (out-of-memory) állapot megszakíthatja a PHP-t, miközben a kérés adatai még csak részben vannak előkészítve, vagyis a 4. lépésben. A következő feltakarításkor érvénytelen adatokat kezelhet a rendszer érvényesként.

A CVE-2026-109619 esetén egy kérés belső állapota a memória felszabadítása után is fennmaradhat. Egy későbbi kérés ugyanabban a workerben felhasználhatja, mielőtt visszaállítanák. Ez a 7. lépést, a feltakarítást érinti. A háttér a [CVE-2026-109619](https://phpsos.de/hu/php2shell/cve-2026-109619/) oldalon és a [kérés életciklusáról](https://phpsos.de/hu/php/request-lebenszyklus/) szóló cikkben található.

Ebből következik: az alkalmazáskódban lévő védelmi intézkedések, például a biztonsági bővítmények, csak a 6. lépésben lépnek működésbe. A PHP-csapat szerint mod_php esetén még azelőtt bemutattak egy exploitot, hogy egyáltalán alkalmazáskód futna. Csak a PHP 8.5.12, 8.4.27, 8.3.36 vagy 8.2.35 verzióra való frissítés és az összes PHP-folyamat újraindítása hatásos, mert a hosszú életű workerek különben tovább a régi kódot hajtják végre.

## Hogyan segít konkrétan a PHP SOS?

- **A folyamat láthatóvá tétele:** Megállapítjuk, hogy a szerverén valójában melyik üzemmód, melyik konfiguráció és melyik gyorsítótár aktív.
- **Helyes frissítés:** Telepítjük a PHP-frissítést, és az indítási időpontokból ellenőrizzük, hogy nem fut-e még régi folyamat.
- **A rétegek védelme:** A [szerver-megerősítés](https://phpsos.de/hu/leistungen/server-haertung/) keretében ott korlátozzuk a kérésméreteket, a memóriát és a jogokat, ahol hatnak: az alkalmazáskód előtt.
- **Nyomok vizsgálata:** A védelem nélkül elérhető szervereknél a feltörés jeleit keressük.


## Gyakori kérdések

**A PHP-kódot minden híváskor újrafordítja a rendszer?**  
Gyorsítótár nélkül igen: a PHP szétbontja a szkriptet, szintaxisfát épít, és abból opcode-okat állít elő. Aktív OPcache esetén az opcode-ok a közös memóriában vannak, és újra felhasználhatók, amíg a fájl nem változik.

**Mi marad a memóriában egy kérés után?**  
Alapvetően a kérés állapotát a végén feltakarítják, hogy a következő kérés tisztán indulhasson. Tartósak csak az olyan dolgok, mint az OPcache vagy a perzisztens kapcsolatok. A CVE-2026-109619 éppen ennél a feltakarításnál támad.

**Miért kell a PHP-t frissítés után újraindítani?**  
PHP-FPM és mod_php esetén a folyamatok tartósan futnak, és a régi programkódot töltötték be. A lemezen lévő új fájlok ezen nem változtatnak. Csak az újraindítás tölti be a javított kódot.

**Biztonságosabb a PHP nélküli webszerver?**  
Kisebb a támadási felülete, mert nincs programlogika, amely a kérésekre reagál. Tisztán statikus tartalmaknál ez valódi lehetőség. Webshopokhoz, űrlapokhoz és bejelentkezésekhez viszont szerveroldali nyelv kell, és akkor a gondozása számít.

## Források

- [PHP-kézikönyv: Bevezetés](https://www.php.net/manual/en/introduction.php)
- [PHP RFC: Abstract Syntax Tree](https://wiki.php.net/rfc/abstract_syntax_tree)
- [PHP RFC: JIT](https://wiki.php.net/rfc/jit)
- [PHP-kézikönyv: OPcache](https://www.php.net/manual/en/book.opcache.php)
