# Hoe PHP een webpagina genereert: de weg van een verzoek

> Hoe werkt PHP? Van de klik in de browser via webserver, SAPI, compiler en Zend VM tot de kant-en-klare pagina, uitgelegd in zeven stappen met voorbeelden.

Bron: https://phpsos.de/nl/php/wie-php-funktioniert/  
Stand: 25-10-2026  
Aanbieder: PHP SOS, PHP-noodhulp en serverbeveiliging. Directe hulp via WhatsApp: https://wa.me/491736494914?text=Hallo%20PHP%20SOS%2C%20wij%20hebben%20hulp%20nodig%20met%20onze%20PHP-server.%20Bedrijf%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**Kort gezegd:** Wanneer een browser een PHP-pagina opvraagt, neemt de webserver het verzoek aan en geeft het via een interface (SAPI) door aan PHP. PHP vertaalt het script naar bytecode, voert die uit in de Zend Engine en geeft het resultaat, meestal HTML, terug aan de webserver. Daarna wordt de toestand van het verzoek opgeruimd, zodat het volgende schoon begint.

## Wat gebeurt er als iemand uw website opvraagt?

Voor bezoekers is het een klik. Op de server verlopen in milliseconden veel stappen. Wie dit verloop kent, begrijpt beter waarom updates, herstarts en configuratie zo belangrijk zijn en waarom een lek in PHP zelf zwaarder weegt dan een lek in een plug-in.

De PHP-handleiding noemt drie onderdelen die voor een PHP-website nodig zijn: de PHP-interpreter (als CGI of servermodule), een webserver en een browser. De interpreter is het programma dat PHP-code leest en uitvoert. Hoe hij met de webserver is verbonden, bepaalt de uitvoeringsmodus.

## Hoe werkt PHP? Zeven stappen van een verzoek

1. **Verzoek:** De browser stuurt een HTTP-verzoek, bijvoorbeeld `GET /kontakt.php`, naar de server.
2. **Webserver:** Apache, Nginx of LiteSpeed nemen het verzoek aan. Statische bestanden zoals afbeeldingen leveren ze zelf uit. Voor `.php`-bestanden roepen ze PHP aan.
3. **Overdracht via de SAPI:** De serverinterface (SAPI) geeft verzoekgegevens zoals headers, parameters en formuliergegevens door aan PHP. Bij PHP-FPM gebeurt dat via het FastCGI-protocol, bij mod_php direct in het Apache-proces. Details onder [SAPI uitgelegd](https://phpsos.de/nl/php/sapi-erklaert/).
4. **Verzoek voorbereiden:** PHP legt de verzoekgegevens vast in variabelen zoals `$_GET`, `$_POST`, `$_COOKIE` en `$_FILES` en reserveert geheugen voor het verzoek.
5. **Vertalen:** Het script wordt in bouwstenen (tokens) ontleed, daaruit ontstaat een abstracte syntaxisboom (AST) en daaruit opcodes, een soort machinetaal voor PHP. Is de OPcache actief, dan wordt deze stap overgeslagen als het script al in de cache staat.
6. **Uitvoeren:** De virtuele machine van de [Zend Engine](https://phpsos.de/nl/php/zend-engine/) werkt de opcodes af, bevraagt databases, leest bestanden en maakt de uitvoer.
7. **Antwoord en opruimen:** De uitvoer gaat via de SAPI terug naar de webserver en van daar naar de browser. Vervolgens geeft PHP het geheugen van het verzoek vrij en zet de toestand terug.

De AST bestaat sinds PHP 7. Volgens de bijbehorende RFC maakte de parser daarvoor de opcodes direct tijdens het inlezen; de splitsing in drie fasen maakte de compiler eenvoudiger te onderhouden.

## Een voorbeeld: wat het script van het verzoek ziet

Het volgende onschuldige script laat zien welke informatie PHP uit het verzoek krijgt en in welke uitvoeringsmodus het draait:

```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";
```

Op een server met PHP-FPM geeft `PHP_SAPI` de waarde `fpm-fcgi` uit, onder Apache met mod_php `apache2handler`. Zet zulke testbestanden alleen kort en nooit blijvend in de openbare map, want versiegegevens helpen ook aanvallers bij de oriëntatie.

## Waar de bytecodecache en de JIT een rol spelen

Het vertalen in stap 5 kost tijd. De [OPcache](https://phpsos.de/nl/php/opcache/) slaat volgens de handleiding vooraf gecompileerde bytecode op in het gedeelde geheugen en bespaart PHP zo het laden en ontleden van de scripts bij elk verzoek. Sinds PHP 8.0 kan bovendien een JIT-compiler uit opcodes echte machinecode maken. Volgens de JIT-RFC is hij een vrijwel zelfstandig onderdeel van OPcache.

| Fase | Resultaat | Wordt gecachet? |
|---|---|---|
| Lexing | tokenstroom | nee |
| Parsing | abstracte syntaxisboom (AST) | nee |
| Compileren | opcodes (op-arrays per bestand en functie) | ja, in de OPcache |
| JIT (optioneel) | machinecode | ja, in het OPcache-geheugen |
| Uitvoeren | uitvoer van de pagina | nee |

De cache betreft alleen de vertaalde code. Gegevens van het afzonderlijke verzoek, zoals formulierinvoer of sessiewaarden, worden niet via de OPcache gedeeld.

## Waarom PHP2Shell precies in dit verloop aangrijpt

De twee PHP2Shell-lekken betreffen niet een toepassing, maar het verloop zelf. Bij CVE-2026-109618 kan een out-of-memory-toestand PHP onderbreken terwijl verzoekgegevens pas gedeeltelijk zijn voorbereid, dus in stap 4. Bij het daaropvolgende opruimen kunnen ongeldige gegevens dan als geldig worden behandeld.

Bij CVE-2026-109619 kan de interne toestand van een verzoek na het vrijgeven van het geheugen blijven bestaan. Een later verzoek in dezelfde worker kan die gebruiken voordat hij wordt teruggezet. Dat betreft stap 7, het opruimen. Achtergronden staan op de pagina [CVE-2026-109619](https://phpsos.de/nl/php2shell/cve-2026-109619/) en in het artikel over de [levenscyclus van een verzoek](https://phpsos.de/nl/php/request-lebenszyklus/).

Hieruit volgt: beschermende maatregelen in de toepassingscode, bijvoorbeeld beveiligingsplug-ins, werken pas in stap 6. Bij mod_php is volgens het PHP-team zelfs een exploit gedemonstreerd voordat er ook maar toepassingscode draait. Werkzaam is alleen de PHP-update naar 8.5.12, 8.4.27, 8.3.36 of 8.2.35 en een herstart van alle PHP-processen, omdat langlevende workers anders de oude code blijven uitvoeren.

## Hoe helpt PHP SOS concreet?

- **Verloop zichtbaar maken:** Wij stellen vast welke uitvoeringsmodus, welke configuratie en welke cache op uw server daadwerkelijk actief zijn.
- **Juist bijwerken:** Wij installeren de PHP-update en controleren aan de hand van de starttijden dat er geen oud proces meer draait.
- **Lagen beveiligen:** In het kader van de [serverhardening](https://phpsos.de/nl/leistungen/server-haertung/) beperken wij verzoekgroottes, geheugen en rechten daar waar ze werken: vóór de toepassingscode.
- **Sporen controleren:** Bij onbeschermd bereikbare servers zoeken wij naar tekenen van een inbraak.


## Veelgestelde vragen

**Wordt PHP-code bij elke aanroep opnieuw vertaald?**  
Zonder cache wel: PHP ontleedt het script, bouwt een syntaxisboom en maakt daaruit opcodes. Met actieve OPcache staan de opcodes in het gedeelde geheugen en worden ze hergebruikt zolang het bestand niet is gewijzigd.

**Wat blijft er na een verzoek in het geheugen?**  
In beginsel wordt de toestand van een verzoek aan het einde opgeruimd, zodat het volgende verzoek schoon begint. Langlevend zijn alleen zaken als de OPcache of persistente verbindingen. Precies bij dit opruimen grijpt CVE-2026-109619 aan.

**Waarom moet PHP na een update opnieuw worden gestart?**  
Bij PHP-FPM en mod_php draaien processen permanent en hebben ze de oude programmacode geladen. Nieuwe bestanden op de schijf veranderen daar niets aan. Pas een herstart laadt de gecorrigeerde code.

**Is een webserver zonder PHP veiliger?**  
Hij heeft minder aanvalsoppervlak, omdat er geen programmalogica op verzoeken reageert. Voor puur statische inhoud is dat een echte optie. Voor webshops, formulieren en aanmeldingen is echter een serverzijdige taal nodig, en dan telt het onderhoud ervan.

## Bronnen

- [PHP-handleiding: inleiding](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-handleiding: OPcache](https://www.php.net/manual/en/book.opcache.php)
