# Zend Engine: inima PHP

> Zend Engine explicat: compilator, opcodes, mașină virtuală, zval și gestiunea memoriei în nucleul PHP, versiunile ei și importanța pentru patch-uri.

Sursa: https://phpsos.de/ro/php/zend-engine/  
Stadiu: 25.10.2026  
Furnizor: PHP SOS, Asistență de urgență PHP și securitatea serverelor. Ajutor imediat pe WhatsApp: https://wa.me/491736494914?text=Bun%C4%83%20ziua%2C%20PHP%20SOS%2C%20avem%20nevoie%20de%20ajutor%20cu%20serverul%20nostru%20PHP.%20Firma%3A%20%E2%80%A6%20Site%3A%20%E2%80%A6

**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:

1. **Lexer:** descompune codul sursă în tokens, de exemplu cuvinte-cheie, nume de variabile și șiruri de caractere.
2. **Parser:** construiește din tokens un arbore sintactic abstract (AST), care reflectă structura programului.
3. **Compilator:** generează din AST op-arrays, adică liste de opcodes, câte una pentru fiecare fișier și funcție.
4. **Executor (Zend VM):** parcurge opcodes. Potrivit RFC-ului JIT, fiecare opcode are o funcție handler care îl execută.
5. **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
<?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
<?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](https://phpsos.de/ro/php/speicherverwaltung/).

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](https://phpsos.de/ro/php/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.

> **Important:**
> 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](https://phpsos.de/ro/php/out-of-memory/). Încadrarea vulnerabilității însăși se află la [CVE-2026-109618](https://phpsos.de/ro/php2shell/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](https://phpsos.de/ro/leistungen/php-patch-service/) 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.

## Surse

- [Manualul PHP: istoria 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)
- [Manualul PHP: numărarea referințelor](https://www.php.net/manual/en/features.gc.refcounting-basics.php)
- [Manualul PHP: setările de bază (memory_limit)](https://www.php.net/manual/en/ini.core.php)
