# Zend Engine: srdce PHP

> Zend Engine vysvetlený: kompilátor, opcódy, virtuálny stroj, zval a správa pamäte v jadre PHP, jeho verzie a význam pre záplatovanie zraniteľností.

Zdroj: https://phpsos.de/sk/php/zend-engine/  
Stav: 25.10.2026  
Poskytovateľ: PHP SOS, Núdzová pomoc pri PHP a bezpečnosť serverov. Okamžitá pomoc cez WhatsApp: https://wa.me/491736494914?text=Dobr%C3%BD%20de%C5%88%2C%20PHP%20SOS%2C%20potrebujeme%20pomoc%20s%20na%C5%A1%C3%ADm%20serverom%20s%20PHP.%20Spolo%C4%8Dnos%C5%A5%3A%20%E2%80%A6%20Web%3A%20%E2%80%A6

**Stručne:** Zend Engine je jadro PHP. Prekladá kód PHP na opcódy, vykonáva ich vo virtuálnom stroji a pritom spravuje premenné a pamäť. Od PHP 4 sa nachádza v každej inštalácii PHP. Keďže zraniteľnosti PHP2Shell ležia práve v tomto jadre, nepomôžu zásuvné moduly ani aktualizácie CMS, ale iba aktualizované PHP s reštartom.

## Čo je Zend Engine?

Zend Engine je tá časť PHP, ktorá vykonáva skutočnú prácu. Všetko ostatné, napríklad napojenie na webový server alebo rozšírenia pre databázy, stavia na ňom. Možno ho prirovnať k motoru auta: karoséria a výbava sa líšia, motor poháňa všetko.

Podľa príručky PHP vznikol názov z krstných mien vývojárov Zeeva Suraského a Andiho Gutmansa. Engine bol predstavený v polovici roka 1999 a od PHP 4.0, vydaného v máji 2000, je jadrom PHP. Odvtedy bol viackrát zásadne prepracovaný.

| Verzia PHP | Engine | Najdôležitejšia zmena podľa príručky a RFC |
|---|---|---|
| PHP 4.0 (2000) | Zend Engine | prvé spoločné jadro, vyšší výkon |
| PHP 5.0 (2004) | Zend Engine 2.0 | nový objektový model |
| PHP 7.0 (2015) | Zend Engine 3.0 | PHPNG: kompaktnejšie dátové štruktúry, AST |
| PHP 8.0 (2020) | ďalší vývoj | kompilátor JIT ako súčasť OPcache |

## Súčasti: kompilátor, virtuálny stroj, pamäť

Engine pracuje v jasne oddelených stupňoch. Od PHP 7 sú podľa RFC k abstraktnému syntaktickému stromu až po bytecode tri fázy:

1. **Lexer:** rozkladá zdrojový text na tokeny, napríklad kľúčové slová, názvy premenných a reťazce znakov.
2. **Parser:** zostavuje z tokenov abstraktný syntaktický strom (AST), ktorý zobrazuje štruktúru programu.
3. **Kompilátor:** vytvára z AST op-arrays, teda zoznamy opcódov, jeden pre každý súbor a funkciu.
4. **Executor (Zend VM):** spracúva opcódy. Podľa RFC k JIT patrí ku každému opcódu obslužná funkcia, ktorá ho vykoná.
5. **Správa pamäte:** vyhradzuje a uvoľňuje pamäť pre každú požiadavku a pritom sleduje hranicu z `memory_limit`.

Tokeny skriptu sa dajú zviditeľniť rozšírením Tokenizer. Je to neškodné a poučné:

```php
<?php
$code = '<?php $summe = 2 + 3; echo $summe;';
foreach (token_get_all($code) as $token) {
    if (is_array($token)) {
        echo token_name($token[0]), ': ', trim($token[1]), "\n";
    } else {
        echo 'Zeichen: ', $token, "\n";
    }
}
```

Výstup ukazuje záznamy ako `T_VARIABLE: $summe` alebo `T_LNUMBER: 2`. Práve s týmito stavebnými prvkami pracuje parser ďalej.

## Ako Zend Engine spravuje premenné?

Každá premenná PHP leží podľa príručky v kontajneri zvanom zval. Obsahuje typ a hodnotu, ako aj správcovské údaje, medzi nimi počítadlo referencií (refcount). Počítadlo udáva, koľko názvov premenných ukazuje na ten istý kontajner.

```php
<?php
$a = str_repeat('x', 10);
$b = $a;        // žiadne kopírovanie, obe ukazujú na tú istú hodnotu
$b .= 'y';      // až teraz sa kopíruje (copy on write)
unset($a);      // počítadlo klesá, pamäť sa uvoľní, keď dosiahne 0
```

Keď počítadlo dosiahne nulu, engine pamäť uvoľní. Pre kruhové odkazy medzi objektmi existuje navyše garbage collector. Viac v príspevku [Správa pamäte v PHP](https://phpsos.de/sk/php/speicherverwaltung/).

Prepracovanie PHPNG pre PHP 7 nadviazalo práve tu. Podľa RFC od Dmitryho Stogova a Zeeva Suraského išlo o kompaktnejšie dátové štruktúry a šikovnejšie zobrazenie hodnôt. RFC uvádzalo nárast výkonu o 20 až 110 percent v reálnych aplikáciách.

## OPcache a JIT: rozšírenia enginu

Bez cache engine preloží každý skript pri každej požiadavke odznova. [OPcache](https://phpsos.de/sk/php/opcache/) drží hotové opcódy pripravené v zdieľanej pamäti. Od PHP 8.0 existuje navyše kompilátor JIT. Podľa RFC je založený na DynASM, nástroji z projektu LuaJIT, a vytvára strojový kód priamo z bytecode. Virtuálny stroj pritom zostáva nezmenený; JIT nahrádza iba vstupné body obslužných funkcií.

Pre prevádzkovateľov to znamená: OPcache a JIT engine zrýchľujú, ale nemenia jeho správanie pri chybách. Zraniteľnosť v jadre zostáva aj pri aktívnej cache.

## Prečo sú zraniteľnosti v engine obzvlášť závažné

Obe zraniteľnosti PHP2Shell ležia v jadre PHP. Pri CVE-2026-109618 môže stav Out-of-Memory prerušiť engine vo chvíli, keď sú údaje požiadavky inicializované len sčasti; pri upratovaní sa potom neplatné údaje spracujú ako platné. Pri CVE-2026-109619 zostáva vnútorný stav po uvoľnení pamäte zachovaný a môže ho použiť neskoršia požiadavka v tom istom workeri.

Opravené verzie 8.5.12, 8.4.27, 8.3.36 a 8.2.35 menia podľa príručky PHP aj správanie hranice pamäte: `memory_limit` je v nich mäkká hranica a nové nastavenie `memory_hard_limit_percent` určuje tvrdý horný limit. Príručka upozorňuje, že verzia, ktorá toto nastavenie nepozná, je zraniteľnosťami dotknutá. Pri distribúciách s backportmi navyše rozhoduje changelog balíka.

> **Dôležité:**
> Engine je načítaný v každom procese PHP. Po aktualizácii sa preto musia reštartovať všetky workery PHP-FPM, procesy Apache s mod_php a ostatné služby PHP.

Čo sa vo vnútri deje pri nedostatku pamäte, opisuje príspevok [memory_limit a Out-of-Memory](https://phpsos.de/sk/php/out-of-memory/). Zaradenie samotnej zraniteľnosti nájdete na stránke [CVE-2026-109618](https://phpsos.de/sk/php2shell/cve-2026-109618/).

## Ako konkrétne pomáha PHP SOS?

- **Skontrolovať verziu a stav balíka:** Zisťujeme, aký stav enginu skutočne beží, vrátane backportov vašej distribúcie.
- **Aktualizovať a reštartovať:** Cez [službu záplatovania PHP](https://phpsos.de/sk/leistungen/php-patch-service/) nasadíme aktualizáciu a skontrolujeme, že nezostal žiadny proces so starým kódom.
- **Rozumne nastaviť limity pamäte:** Ladíme `memory_limit`, novú tvrdú hranicu a hranice cgroup podľa vašej aplikácie.
- **Preskúmať nezrovnalosti:** Pády workerov alebo procesy so stavom ukončenia 137 zaradíme a overíme, či za nimi nemôže stáť útok.


## Časté otázky

**Odkiaľ má Zend Engine svoj názov?**  
Názov vznikol z krstných mien jeho vývojárov: Zeev Suraski a Andi Gutmans. Engine bol podľa príručky PHP predstavený v polovici roka 1999 a od PHP 4.0 v máji 2000 tvorí jadro PHP.

**Je Zend Engine samostatný produkt, ktorý musím inštalovať?**  
Nie. Zend Engine je pevnou súčasťou každej inštalácie PHP. Kto aktualizuje PHP, aktualizuje automaticky aj engine. S komerčnými produktmi firmy Zend to nemá nič spoločné.

**Čo je opcód?**  
Opcód je jednotlivý príkaz pre virtuálny stroj PHP, napríklad sčítanie, volanie funkcie alebo priradenie. Kompilátor preloží každý skript na postupnosť takýchto príkazov, ktoré engine následne vykonáva.

**Čo má Zend Engine spoločné s memory_limit?**  
Engine spravuje pamäť každej požiadavky a pritom dbá na hranicu z memory_limit. Od bezpečnostných vydaní z 21. 10. 2026 je táto hranica podľa príručky mäkká a dopĺňa ju tvrdá hranica cez memory_hard_limit_percent.

## Zdroje

- [Príručka PHP: História PHP](https://www.php.net/manual/en/history.php.php)
- [PHP RFC: PHPNG](https://wiki.php.net/rfc/phpng)
- [PHP RFC: JIT](https://wiki.php.net/rfc/jit)
- [Príručka PHP: Počítanie referencií](https://www.php.net/manual/en/features.gc.refcounting-basics.php)
- [Príručka PHP: Základné nastavenia (memory_limit)](https://www.php.net/manual/en/ini.core.php)
