Pe scurt: Zend Engine este nucleul PHP. Ea traduce codul PHP în opcodes, le execută într-o mașină virtuală și gestionează variabilele și memoria. Din PHP 4 se află în fiecare instalare PHP. Deoarece vulnerabilitățile PHP2Shell se află în acest nucleu, nu ajută pluginurile sau actualizările de CMS, ci doar un PHP actualizat, urmat de repornire.
Ce este Zend Engine?
Zend Engine este partea din PHP care face munca propriu-zisă. Tot restul, de exemplu legătura cu serverul web sau extensiile pentru baze de date, se sprijină pe ea. O puteți compara cu motorul unei mașini: caroseria și dotările diferă, motorul pune totul în mișcare.
Potrivit manualului PHP, numele provine din prenumele dezvoltatorilor Zeev Suraski și Andi Gutmans. Motorul a fost prezentat la mijlocul anului 1999 și, începând cu PHP 4.0, apărut în mai 2000, a fost nucleul PHP. De atunci a fost refăcut fundamental de mai multe ori.
| Versiune PHP | Motor | Cea mai importantă schimbare potrivit manualului și RFC-urilor |
|---|---|---|
| PHP 4.0 (2000) | Zend Engine | primul nucleu comun, performanță mai bună |
| PHP 5.0 (2004) | Zend Engine 2.0 | model de obiecte nou |
| PHP 7.0 (2015) | Zend Engine 3.0 | PHPNG: structuri de date mai compacte, AST |
| PHP 8.0 (2020) | evoluție ulterioară | compilator JIT ca parte a OPcache |
Componentele: compilator, mașină virtuală, memorie
Motorul lucrează în trepte clar separate. Începând cu PHP 7, potrivit RFC-ului despre arborele sintactic abstract, sunt trei faze până la bytecode:
- Lexer: descompune codul sursă în tokens, de exemplu cuvinte-cheie, nume de variabile și șiruri de caractere.
- Parser: construiește din tokens un arbore sintactic abstract (AST), care reflectă structura programului.
- Compilator: generează din AST op-arrays, adică liste de opcodes, câte una pentru fiecare fișier și funcție.
- Executor (Zend VM): parcurge opcodes. Potrivit RFC-ului JIT, fiecare opcode are o funcție handler care îl execută.
- Gestiunea memoriei: rezervă și eliberează memorie pentru fiecare cerere și urmărește limita din
memory_limit.
Tokens unui script pot fi făcuți vizibili cu extensia Tokenizer. Este inofensiv și instructiv:
<?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";
}
}
Ieșirea arată intrări precum T_VARIABLE: $summe sau T_LNUMBER: 2. Exact cu aceste elemente lucrează parserul mai departe.
Cum gestionează Zend Engine variabilele?
Potrivit manualului, fiecare variabilă PHP se află într-un container numit zval. El conține tipul și valoarea, precum și informații de administrare, printre care un contor de referințe (refcount). Contorul arată câte nume de variabile indică același container.
<?php
$a = str_repeat('x', 10);
$b = $a; // nicio copiere, ambele indică aceeași valoare
$b .= 'y'; // abia acum se copiază (copy on write)
unset($a); // contorul scade, memoria se eliberează când ajunge la 0
Când contorul ajunge la zero, motorul eliberează memoria. Pentru referințele circulare dintre obiecte există suplimentar un garbage collector. Mai multe în articolul Gestiunea memoriei în PHP.
Refacerea PHPNG pentru PHP 7 a pornit exact de aici. Potrivit RFC-ului lui Dmitry Stogov și Zeev Suraski, a fost vorba de structuri de date mai compacte și o reprezentare mai ingenioasă a valorilor. RFC-ul indica câștiguri de performanță de 20 până la 110 la sută în aplicații reale.
OPcache și JIT: extensii ale motorului
Fără cache, motorul traduce fiecare script din nou la fiecare cerere. OPcache ține opcodes gata făcuți în memoria comună. Începând cu PHP 8.0 există suplimentar un compilator JIT. Potrivit RFC-ului, acesta se bazează pe DynASM, un instrument din proiectul LuaJIT, și generează cod-mașină direct din bytecode. Mașina virtuală rămâne neschimbată; JIT înlocuiește doar punctele de intrare ale handler-elor.
Pentru operatori aceasta înseamnă: OPcache și JIT accelerează motorul, dar nu schimbă nimic în comportamentul lui la erori. O vulnerabilitate din nucleu rămâne și cu cache-ul activ.
De ce vulnerabilitățile din motor cântăresc deosebit de greu
Cele două vulnerabilități PHP2Shell se află în nucleul PHP. La CVE-2026-109618, o stare de lipsă de memorie (out-of-memory) poate întrerupe motorul în timp ce datele cererii sunt inițializate doar parțial; la curățare, datele nevalide sunt apoi tratate ca valide. La CVE-2026-109619, starea internă persistă după eliberarea memoriei și poate fi folosită de o cerere ulterioară în același worker.
Versiunile corectate 8.5.12, 8.4.27, 8.3.36 și 8.2.35 modifică, potrivit manualului PHP, și comportamentul limitei de memorie: memory_limit este acolo o limită flexibilă, iar o setare nouă, memory_hard_limit_percent, fixează o limită superioară fermă. Manualul atrage atenția că o versiune care nu cunoaște această setare este afectată de vulnerabilități. La distribuțiile cu backporturi contează suplimentar changelogul pachetului.
Motorul este încărcat în fiecare proces PHP. După actualizare trebuie deci repornite toți workerii PHP-FPM, procesele Apache cu mod_php și celelalte servicii PHP.
Ce se întâmplă în interior la o lipsă de memorie descrie articolul memory_limit și Out-of-Memory. Încadrarea vulnerabilității însăși se află la CVE-2026-109618.
Cum ajută PHP SOS concret?
- Verificarea versiunii și a stării pachetului: Stabilim ce versiune a motorului rulează de fapt, inclusiv backporturile distribuției dumneavoastră.
- Actualizare și repornire: Prin serviciul de patch PHP instalăm actualizarea și verificăm că nu rămâne niciun proces cu cod vechi.
- Setarea rezonabilă a limitelor de memorie: Corelăm
memory_limit, noua limită fermă și limitele cgroup cu aplicația dumneavoastră. - Investigarea anomaliilor: Încadrăm blocările workerilor sau procesele cu statusul de ieșire 137 și verificăm dacă în spatele lor poate fi un atac.
Întrebări frecvente
De unde vine numele Zend Engine?
Numele este format din prenumele dezvoltatorilor ei: Zeev Suraski și Andi Gutmans. Potrivit manualului PHP, motorul a fost prezentat la mijlocul anului 1999 și, începând cu PHP 4.0 din mai 2000, a fost nucleul PHP.
Este Zend Engine un produs separat, pe care trebuie să-l instalez?
Nu. Zend Engine este parte fixă a oricărei instalări PHP. Cine actualizează PHP actualizează automat și motorul. Nu are nicio legătură cu produsele comerciale ale firmei Zend.
Ce este un opcode?
Un opcode este o singură instrucțiune pentru mașina virtuală a PHP, de exemplu o adunare, un apel de funcție sau o atribuire. Compilatorul traduce fiecare script într-o succesiune de asemenea instrucțiuni, pe care motorul le parcurge apoi.
Ce legătură are Zend Engine cu memory_limit?
Motorul gestionează memoria fiecărei cereri și respectă limita din memory_limit. Începând cu lansările de securitate din 21.10.2026, potrivit manualului, această limită este una flexibilă, completată de o limită fermă prin memory_hard_limit_percent.