# Como o PHP gera uma página web: o percurso de um pedido

> Como funciona o PHP? Do clique no navegador, por servidor web, SAPI, compilador e Zend VM, até à página pronta, em sete passos com exemplos.

Fonte: https://phpsos.de/pt/php/wie-php-funktioniert/  
Atualizado em: 25/10/2026  
Prestador: PHP SOS, Assistência de emergência PHP e segurança de servidores. Ajuda imediata por WhatsApp: https://wa.me/491736494914?text=Ol%C3%A1%2C%20PHP%20SOS%2C%20precisamos%20de%20ajuda%20com%20o%20nosso%20servidor%20PHP.%20Empresa%3A%20%E2%80%A6%20Site%3A%20%E2%80%A6

**Em resumo:** Quando um navegador pede uma página PHP, o servidor web aceita o pedido e passa-o ao PHP através de uma interface (SAPI). O PHP traduz o script para bytecode, executa-o na Zend Engine e devolve o resultado, geralmente HTML, ao servidor web. Depois, o estado do pedido é limpo, para que o seguinte comece em condições limpas.

## O que acontece quando alguém acede ao seu site?

Para os visitantes, é um clique. No servidor decorrem muitos passos em milissegundos. Quem conhece este percurso compreende melhor por que razão as atualizações, os reinícios e a configuração são tão importantes e por que razão uma falha no próprio PHP pesa mais do que uma falha num plugin.

O manual do PHP refere três componentes necessários para um site PHP: o interpretador PHP (como CGI ou módulo do servidor), um servidor web e um navegador. O interpretador é o programa que lê e executa o código PHP. A forma como está ligado ao servidor web determina o modo de operação.

## Como funciona o PHP? Sete passos de um pedido

1. **Pedido:** O navegador envia ao servidor um pedido HTTP, por exemplo `GET /kontakt.php`.
2. **Servidor web:** Apache, Nginx ou LiteSpeed aceitam o pedido. Entregam eles próprios os ficheiros estáticos, como imagens. Para ficheiros `.php`, chamam o PHP.
3. **Passagem através da SAPI:** A interface do servidor (SAPI) passa ao PHP os dados do pedido, como cabeçalhos, parâmetros e dados de formulários. No PHP-FPM isto faz-se através do protocolo FastCGI; no mod_php, diretamente no processo do Apache. Pormenores em [SAPI explicada](https://phpsos.de/pt/php/sapi-erklaert/).
4. **Preparar o pedido:** O PHP guarda os dados do pedido em variáveis como `$_GET`, `$_POST`, `$_COOKIE` e `$_FILES` e reserva memória para o pedido.
5. **Traduzir:** O script é decomposto em elementos (tokens), daí resulta uma árvore sintática abstrata (AST) e dela os opcodes, uma espécie de linguagem máquina para o PHP. Se o OPcache estiver ativo, este passo é ignorado quando o script já se encontra na cache.
6. **Executar:** A máquina virtual da [Zend Engine](https://phpsos.de/pt/php/zend-engine/) processa os opcodes, consulta bases de dados, lê ficheiros e gera a saída.
7. **Resposta e limpeza:** A saída regressa ao servidor web através da SAPI e daí ao navegador. Em seguida, o PHP liberta a memória do pedido e repõe o estado.

A AST existe desde o PHP 7. Segundo o RFC correspondente, antes disso o analisador gerava os opcodes diretamente durante a leitura; a separação em três fases tornou o compilador mais fácil de manter.

## Um exemplo: o que o script vê do pedido

O seguinte script inofensivo mostra que informações o PHP recebe do pedido e em que modo de operação corre:

```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";
```

Num servidor com PHP-FPM, `PHP_SAPI` devolve o valor `fpm-fcgi`; no Apache com mod_php, `apache2handler`. Guarde estes ficheiros de teste apenas por pouco tempo e nunca de forma permanente no diretório público, pois as indicações de versão também ajudam os atacantes a orientar-se.

## Onde entram a cache de bytecode e o JIT

A tradução no passo 5 consome tempo. Segundo o manual, o [OPcache](https://phpsos.de/pt/php/opcache/) guarda bytecode pré-compilado na memória partilhada e poupa assim ao PHP o carregamento e a decomposição dos scripts a cada pedido. Desde o PHP 8.0, um compilador JIT pode ainda gerar código máquina real a partir dos opcodes. Segundo o RFC do JIT, é uma parte quase autónoma do OPcache.

| Fase | Resultado | É guardado em cache? |
|---|---|---|
| Análise léxica | fluxo de tokens | não |
| Análise sintática | árvore sintática abstrata (AST) | não |
| Compilação | opcodes (op-arrays por ficheiro e função) | sim, no OPcache |
| JIT (opcional) | código máquina | sim, na memória do OPcache |
| Execução | saída da página | não |

A cache diz respeito apenas ao código traduzido. Os dados de cada pedido, como entradas de formulários ou valores de sessão, não são partilhados através do OPcache.

## Porque é que o PHP2Shell atua precisamente neste percurso

As duas vulnerabilidades do PHP2Shell não dizem respeito a uma aplicação, mas ao próprio percurso. No CVE-2026-109618, uma condição de falta de memória pode interromper o PHP enquanto os dados do pedido estão só parcialmente preparados, ou seja, no passo 4. Na limpeza que se segue, dados inválidos podem então ser tratados como válidos.

No CVE-2026-109619, o estado interno de um pedido pode persistir depois de a memória ser libertada. Um pedido posterior no mesmo worker pode usá-lo antes de ser reposto. Isto diz respeito ao passo 7, a limpeza. Os antecedentes estão na página [CVE-2026-109619](https://phpsos.de/pt/php2shell/cve-2026-109619/) e no artigo sobre o [ciclo de vida do pedido](https://phpsos.de/pt/php/request-lebenszyklus/).

Daqui resulta: as medidas de proteção no código da aplicação, como os plugins de segurança, só atuam no passo 6. No mod_php, segundo a equipa do PHP, chegou a ser demonstrado um exploit antes de qualquer código de aplicação correr. Só é eficaz a atualização do PHP para 8.5.12, 8.4.27, 8.3.36 ou 8.2.35 e o reinício de todos os processos PHP, porque, de outro modo, os workers de longa duração continuam a executar o código antigo.

## Como ajuda concretamente a PHP SOS?

- **Tornar o percurso visível:** Apuramos que modo de operação, que configuração e que cache estão realmente ativos no seu servidor.
- **Atualizar corretamente:** Aplicamos a atualização do PHP e verificamos, através das horas de arranque, que já não corre nenhum processo antigo.
- **Proteger as camadas:** No âmbito do [reforço de servidores](https://phpsos.de/pt/leistungen/server-haertung/), limitamos tamanhos de pedidos, memória e permissões onde fazem efeito: antes do código da aplicação.
- **Verificar vestígios:** Em servidores acessíveis sem proteção, procuramos sinais de intrusão.


## Perguntas frequentes

**O código PHP é traduzido de novo a cada acesso?**  
Sem cache, sim: o PHP decompõe o script, constrói uma árvore sintática e gera a partir dela os opcodes. Com o OPcache ativo, os opcodes ficam na memória partilhada e são reutilizados enquanto o ficheiro não for alterado.

**O que fica na memória depois de um pedido?**  
Em princípio, o estado de um pedido é limpo no fim, para que o pedido seguinte comece em condições limpas. Só coisas como o OPcache ou as ligações persistentes têm vida longa. É precisamente nesta limpeza que atua o CVE-2026-109619.

**Porque é que o PHP tem de ser reiniciado depois de uma atualização?**  
No PHP-FPM e no mod_php, os processos correm de forma permanente e têm carregado o código de programa antigo. Novos ficheiros no disco não alteram isso. Só um reinício carrega o código corrigido.

**Um servidor web sem PHP é mais seguro?**  
Tem menos superfície de ataque, porque nenhuma lógica de programa reage aos pedidos. Para conteúdos puramente estáticos, é uma opção real. Para lojas, formulários e autenticações, porém, é preciso uma linguagem do lado do servidor, e então conta a sua manutenção.

## Fontes

- [Manual do PHP: introdução](https://www.php.net/manual/en/introduction.php)
- [PHP RFC: árvore sintática abstrata](https://wiki.php.net/rfc/abstract_syntax_tree)
- [PHP RFC: JIT](https://wiki.php.net/rfc/jit)
- [Manual do PHP: OPcache](https://www.php.net/manual/en/book.opcache.php)
