Current situation: PHP2Shell. Two critical PHP vulnerabilities (CVSS 9.2) allow malicious code without login. Patches since 21 October 2026.What to do now →

How PHP Generates a Web Page: The Path of a Request

What happens between the click and the finished page: web server, SAPI, compiler, OPcache and Zend VM in seven steps, and why PHP2Shell targets exactly this process.

Last updated 5 min readPHP knowledge

In short: When a browser requests a PHP page, the web server accepts the request and passes it to PHP through an interface (SAPI). PHP compiles the script into bytecode, executes it in the Zend Engine and returns the result, usually HTML, to the web server. Afterwards the state of the request is cleaned up so that the next one starts clean.

What happens when someone visits your website?

For visitors it is a single click. On the server, many steps run within milliseconds. Knowing this process makes it easier to understand why updates, restarts and configuration matter so much, and why a flaw in PHP itself weighs more heavily than a flaw in a plugin.

The PHP manual names three components required for a PHP website: the PHP interpreter (as CGI or server module), a web server and a browser. The interpreter is the program that reads and executes PHP code. How it is connected to the web server determines the operating mode.

How does PHP work? Seven steps of a request

  1. Request: The browser sends an HTTP request, such as GET /kontakt.php, to the server.
  2. Web server: Apache, Nginx or LiteSpeed accept the request. They deliver static files such as images themselves. For .php files they call PHP.
  3. Handover via the SAPI: The server interface (SAPI) passes request data such as headers, parameters and form data to PHP. With PHP-FPM this happens over the FastCGI protocol, with mod_php directly inside the Apache process. Details under SAPI explained.
  4. Prepare the request: PHP stores the request data in variables such as $_GET, $_POST, $_COOKIE and $_FILES and reserves memory for the request.
  5. Compile: The script is broken into building blocks (tokens), from which an abstract syntax tree (AST) is built and then opcodes, a kind of machine language for PHP. If OPcache is active, this step is skipped when the script is already in the cache.
  6. Execute: The virtual machine of the Zend Engine works through the opcodes, queries databases, reads files and produces the output.
  7. Response and clean-up: The output goes back to the web server via the SAPI and from there to the browser. PHP then releases the request's memory and resets the state.

The AST has existed since PHP 7. According to the associated RFC, the parser previously generated the opcodes directly while reading the source; splitting this into three phases made the compiler easier to maintain.

An example: what the script sees of the request

The following harmless script shows what information PHP receives from the request and in which operating mode it runs:

<?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";

On a server with PHP-FPM, PHP_SAPI outputs the value fpm-fcgi; under Apache with mod_php it outputs apache2handler. Place such test files in the public directory only briefly and never permanently, because version details also help attackers get their bearings.

Where the bytecode cache and the JIT come in

The compilation in step 5 takes time. According to the manual, the OPcache stores precompiled bytecode in shared memory and thereby spares PHP from loading and parsing the scripts on every request. Since PHP 8.0, a JIT compiler can additionally generate real machine code from opcodes. According to the JIT RFC, it is an almost independent part of OPcache.

Phase Result Cached?
Lexing token stream no
Parsing abstract syntax tree (AST) no
Compiling opcodes (op arrays per file and function) yes, in OPcache
JIT (optional) machine code yes, in OPcache memory
Executing page output no

The cache concerns only the compiled code. Data of the individual request, such as form input or session values, is not shared through OPcache.

Why PHP2Shell targets exactly this process

The two PHP2Shell flaws do not concern an application but the process itself. With CVE-2026-109618, an out-of-memory condition can interrupt PHP while request data has only been partially prepared, that is, in step 4. During the subsequent clean-up, invalid data can then be treated as valid.

With CVE-2026-109619, internal state of a request can persist after its memory has been released. A later request in the same worker can use it before it is reset. This concerns step 7, the clean-up. Background is on the page CVE-2026-109619 and in the article on the request lifecycle.

It follows that protective measures in application code, such as security plugins, only take effect in step 6. With mod_php, according to the PHP team, an exploit was even demonstrated before any application code runs at all. The only effective measure is the PHP update to 8.5.12, 8.4.27, 8.3.36 or 8.2.35 and a restart of all PHP processes, because long-lived workers otherwise keep executing the old code.

How does PHP SOS help?

  • Make the process visible: We determine which operating mode, configuration and cache are actually active on your server.
  • Update correctly: We install the PHP update and use process start times to verify that no old process is still running.
  • Secure the layers: As part of server hardening we limit request sizes, memory and permissions where they take effect: in front of the application code.
  • Check for traces: On servers that were reachable without protection, we look for signs of an intrusion.

Frequently asked questions

Is PHP code recompiled on every request?

Without a cache, yes: PHP breaks the script into tokens, builds a syntax tree and generates opcodes from it. With OPcache active, the opcodes sit in shared memory and are reused as long as the file has not changed.

What stays in memory after a request?

In principle, the state of a request is cleaned up at the end so that the next request starts clean. Only things such as the OPcache or persistent connections are long-lived. CVE-2026-109619 targets exactly this clean-up.

Why does PHP have to be restarted after an update?

With PHP-FPM and mod_php, processes run continuously and have the old program code loaded. New files on disk change nothing about that. Only a restart loads the corrected code.

Is a web server without PHP more secure?

It has less attack surface because no program logic responds to requests. For purely static content this is a real option. For shops, forms and logins, however, you need a server-side language, and then its maintenance matters.

Sources

Immediate contact

Every hour counts. Write to us now.

Briefly describe your system, PHP version and observation. We will get back to you, clarify the situation and work remotely until the incident is closed and documented.

Immediate help