Ukratko: Zend Engine jezgra je PHP-a. Prevodi PHP kod u opcodeove, izvršava ih u virtualnom stroju i pritom upravlja varijablama i memorijom. Od PHP-a 4 nalazi se u svakoj PHP instalaciji. Budući da PHP2Shell ranjivosti leže u toj jezgri, ne pomažu dodaci ni ažuriranja CMS-a, nego samo ažurirani PHP uz ponovno pokretanje.
Što je Zend Engine?
Zend Engine je dio PHP-a koji obavlja stvarni posao. Sve ostalo, na primjer povezivanje s web-poslužiteljem ili ekstenzije za baze podataka, nadograđuje se na njega. Može se usporediti s motorom automobila: karoserija i oprema se razlikuju, a motor sve pokreće.
Prema PHP priručniku naziv je nastao od imena razvijatelja Zeeva Suraskog i Andija Gutmansa. Engine je predstavljen sredinom 1999., a od PHP-a 4.0, izišlog u svibnju 2000., bio je jezgra PHP-a. Otad je više puta temeljito prerađivan.
| PHP verzija | Engine | Najvažnija promjena prema priručniku i RFC-ovima |
|---|---|---|
| PHP 4.0 (2000.) | Zend Engine | prva zajednička jezgra, bolja učinkovitost |
| PHP 5.0 (2004.) | Zend Engine 2.0 | novi model objekata |
| PHP 7.0 (2015.) | Zend Engine 3.0 | PHPNG: kompaktnije podatkovne strukture, AST |
| PHP 8.0 (2020.) | daljnji razvoj | JIT kompilator kao dio OPcachea |
Gradivni dijelovi: kompilator, virtualni stroj, memorija
Engine radi u jasno odvojenim stupnjevima. Od PHP-a 7 prema RFC-u o apstraktnom sintaktičkom stablu do bytecodea vode tri faze:
- Lexer: rastavlja izvorni kod na tokene, na primjer ključne riječi, nazive varijabli i nizove znakova.
- Parser: iz tokena gradi apstraktno sintaktičko stablo (AST) koje prikazuje strukturu programa.
- Kompilator: iz AST-a stvara op-nizove, dakle popise opcodeova, po jedan za svaku datoteku i funkciju.
- Executor (Zend VM): obrađuje opcodeove. Prema JIT RFC-u svakom opcodeu pripada funkcija rukovatelj koja ga izvršava.
- Upravljanje memorijom: rezervira i oslobađa memoriju za svaki zahtjev i pritom nadzire granicu iz
memory_limit.
Tokeni skripte mogu se učiniti vidljivima ekstenzijom Tokenizer. To je bezopasno i poučno:
<?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";
}
}
Ispis prikazuje unose poput T_VARIABLE: $summe ili T_LNUMBER: 2. Upravo s tim gradivnim dijelovima parser dalje radi.
Kako Zend Engine upravlja varijablama?
Svaka PHP varijabla prema priručniku leži u spremniku zvanom zval. Sadrži tip i vrijednost te podatke za upravljanje, među ostalim brojač referenci (refcount). Brojač pokazuje koliko naziva varijabli upućuje na isti spremnik.
<?php
$a = str_repeat('x', 10);
$b = $a; // nema kopiranja, oba upućuju na istu vrijednost
$b .= 'y'; // tek sada se kopira (copy on write)
unset($a); // brojač pada, memorija se oslobađa kad dosegne 0
Kada brojač dosegne nulu, engine oslobađa memoriju. Za kružne reference među objektima postoji dodatno sakupljač smeća (garbage collector). Više o tome u članku Upravljanje memorijom u PHP-u.
Prerada PHPNG za PHP 7 počela je upravo ovdje. Prema RFC-u Dmitryja Stogova i Zeeva Suraskog radilo se o kompaktnijim podatkovnim strukturama i pametnijem prikazu vrijednosti. RFC je navodio dobitke u učinkovitosti od 20 do 110 posto u stvarnim aplikacijama.
OPcache i JIT: proširenja enginea
Bez predmemorije engine svaku skriptu pri svakom zahtjevu prevodi iznova. OPcache gotove opcodeove drži spremnima u zajedničkoj memoriji. Od PHP-a 8.0 postoji i JIT kompilator. Prema RFC-u temelji se na DynASM-u, alatu iz projekta LuaJIT, i strojni kod stvara izravno iz bytecodea. Virtualni stroj pritom ostaje nepromijenjen; JIT zamjenjuje samo ulazne točke rukovatelja.
Za operatere to znači: OPcache i JIT ubrzavaju engine, ali ne mijenjaju njegovo ponašanje pri pogreškama. Ranjivost u jezgri ostaje i s aktivnom predmemorijom.
Zašto ranjivosti u engineu posebno teško pogađaju
Obje PHP2Shell ranjivosti leže u jezgri PHP-a. Kod CVE-2026-109618 stanje nedostatka memorije može prekinuti engine dok su podaci zahtjeva tek djelomično inicijalizirani; pri čišćenju se nevaljani podaci tada tretiraju kao valjani. Kod CVE-2026-109619 unutarnje stanje ostaje sačuvano nakon oslobađanja memorije i može ga iskoristiti kasniji zahtjev u istom workeru.
Ispravljene verzije 8.5.12, 8.4.27, 8.3.36 i 8.2.35 prema PHP priručniku mijenjaju i ponašanje granice memorije: memory_limit je tamo meka granica, a nova postavka memory_hard_limit_percent određuje tvrdu gornju granicu. Priručnik upozorava da je verzija koja ne poznaje tu postavku pogođena ranjivostima. Kod distribucija s backportovima dodatno vrijedi changelog paketa.
Engine je učitan u svakom PHP procesu. Nakon ažuriranja zato se moraju ponovno pokrenuti svi PHP-FPM workeri, Apache procesi s mod_php-om i ostale PHP usluge.
Što se iznutra događa kod nedostatka memorije, opisuje članak memory_limit i Out-of-Memory. Procjena same ranjivosti nalazi se na stranici CVE-2026-109618.
Kako PHP SOS konkretno pomaže?
- Provjeriti verziju i stanje paketa: Utvrđujemo koje stanje enginea stvarno radi, uključujući backportove Vaše distribucije.
- Ažurirati i ponovno pokrenuti: Putem PHP Patch usluge instaliramo ažuriranje i provjeravamo da nije ostao nijedan proces sa starim kodom.
- Smisleno postaviti granice memorije: Usklađujemo
memory_limit, novu tvrdu granicu i cgroup granice s Vašom aplikacijom. - Istražiti neobičnosti: Padove workera ili procese sa statusom izlaska 137 procjenjujemo i provjeravamo može li iza njih stajati napad.
Česta pitanja
Odakle Zend Engineu naziv?
Naziv je sastavljen od imena njezinih razvijatelja: Zeev Suraski i Andi Gutmans. Prema PHP priručniku engine je predstavljen sredinom 1999., a od PHP-a 4.0 u svibnju 2000. bio je jezgra PHP-a.
Je li Zend Engine zaseban proizvod koji moram instalirati?
Ne. Zend Engine čvrsti je dio svake PHP instalacije. Tko ažurira PHP, automatski ažurira i engine. S komercijalnim proizvodima tvrtke Zend to nema nikakve veze.
Što je opcode?
Opcode je pojedina naredba za virtualni stroj PHP-a, na primjer zbrajanje, poziv funkcije ili dodjela vrijednosti. Kompilator svaku skriptu prevodi u niz takvih naredbi koje engine zatim obrađuje.
Kakve veze Zend Engine ima s memory_limit?
Engine upravlja memorijom svakog zahtjeva i pritom pazi na granicu iz memory_limit. Od sigurnosnih izdanja od 21. 10. 2026. ta je granica prema priručniku meka granica, dopunjena tvrdom granicom putem memory_hard_limit_percent.