# Jak PHP generuje stronę internetową: droga żądania

> Jak działa PHP? Od kliknięcia w przeglądarce przez serwer WWW, SAPI, kompilator i Zend VM aż po gotową stronę, wyjaśnione w siedmiu krokach z przykładami.

Źródło: https://phpsos.de/pl/php/wie-php-funktioniert/  
Stan: 25.10.2026  
Dostawca: PHP SOS, Pomoc awaryjna PHP i bezpieczeństwo serwerów. Natychmiastowa pomoc przez WhatsApp: https://wa.me/491736494914?text=Dzie%C5%84%20dobry%2C%20PHP%20SOS%2C%20potrzebujemy%20pomocy%20z%20naszym%20serwerem%20PHP.%20Firma%3A%20%E2%80%A6%20Strona%20internetowa%3A%20%E2%80%A6

**Krótko:** Gdy przeglądarka żąda strony PHP, serwer WWW przyjmuje żądanie i przekazuje je przez interfejs (SAPI) do PHP. PHP tłumaczy skrypt na bajtkod, wykonuje go w Zend Engine i zwraca wynik, zwykle HTML, serwerowi WWW. Potem stan żądania jest sprzątany, aby następne zaczynało od czystego stanu.

## Co się dzieje, gdy ktoś otwiera Państwa stronę?

Dla odwiedzającego to jedno kliknięcie. Na serwerze w ciągu milisekund przebiega wiele kroków. Kto zna ten przebieg, lepiej rozumie, dlaczego aktualizacje, restarty i konfiguracja są tak ważne i dlaczego luka w samym PHP waży więcej niż luka we wtyczce.

Podręcznik PHP wymienia trzy elementy potrzebne dla strony w PHP: interpreter PHP (jako CGI lub moduł serwera), serwer WWW i przeglądarkę. Interpreter to program, który czyta i wykonuje kod PHP. To, jak jest połączony z serwerem WWW, określa tryb pracy.

## Jak działa PHP? Siedem kroków żądania

1. **Żądanie:** Przeglądarka wysyła do serwera żądanie HTTP, na przykład `GET /kontakt.php`.
2. **Serwer WWW:** Apache, Nginx lub LiteSpeed przyjmują żądanie. Pliki statyczne, takie jak obrazy, wydają samodzielnie. Dla plików `.php` wywołują PHP.
3. **Przekazanie przez SAPI:** Interfejs serwera (SAPI) przekazuje do PHP dane żądania, takie jak nagłówki, parametry i dane formularzy. W PHP-FPM odbywa się to przez protokół FastCGI, w mod_php bezpośrednio w procesie Apache. Szczegóły na stronie [SAPI wyjaśnione](https://phpsos.de/pl/php/sapi-erklaert/).
4. **Przygotowanie żądania:** PHP zapisuje dane żądania w zmiennych takich jak `$_GET`, `$_POST`, `$_COOKIE` i `$_FILES` oraz rezerwuje pamięć dla żądania.
5. **Tłumaczenie:** Skrypt jest rozbijany na elementy (tokeny), z nich powstaje abstrakcyjne drzewo składni (AST), a z niego opcody, rodzaj języka maszynowego dla PHP. Jeśli OPcache jest aktywny, ten krok jest pomijany, o ile skrypt leży już w pamięci podręcznej.
6. **Wykonanie:** Maszyna wirtualna [Zend Engine](https://phpsos.de/pl/php/zend-engine/) przetwarza opcody, odpytuje bazy danych, czyta pliki i tworzy wyjście.
7. **Odpowiedź i sprzątanie:** Wyjście wraca przez SAPI do serwera WWW, a stamtąd do przeglądarki. Następnie PHP zwalnia pamięć żądania i resetuje stan.

AST istnieje od PHP 7. Według powiązanego RFC parser tworzył wcześniej opcody bezpośrednio podczas wczytywania; podział na trzy fazy ułatwił utrzymanie kompilatora.

## Przykład: co skrypt widzi z żądania

Poniższy nieszkodliwy skrypt pokazuje, jakie informacje PHP otrzymuje z żądania i w jakim trybie pracy działa:

```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";
```

Na serwerze z PHP-FPM `PHP_SAPI` zwraca wartość `fpm-fcgi`, w Apache z mod_php `apache2handler`. Takie pliki kontrolne proszę umieszczać w katalogu publicznym tylko na krótko i nigdy na stałe, ponieważ informacje o wersji pomagają także atakującym w orientacji.

## Gdzie wchodzą pamięć podręczna bajtkodu i JIT

Tłumaczenie w kroku 5 kosztuje czas. [OPcache](https://phpsos.de/pl/php/opcache/) przechowuje według podręcznika prekompilowany bajtkod we wspólnej pamięci i oszczędza PHP wczytywania oraz rozbijania skryptów przy każdym żądaniu. Od PHP 8.0 dodatkowo kompilator JIT może tworzyć z opcodów prawdziwy kod maszynowy. Według RFC dotyczącego JIT jest to niemal samodzielna część OPcache.

| Faza | Wynik | Czy jest buforowana? |
|---|---|---|
| Analiza leksykalna | strumień tokenów | nie |
| Parsowanie | abstrakcyjne drzewo składni (AST) | nie |
| Kompilacja | opcody (tablice op dla pliku i funkcji) | tak, w OPcache |
| JIT (opcjonalnie) | kod maszynowy | tak, w pamięci OPcache |
| Wykonanie | wyjście strony | nie |

Pamięć podręczna dotyczy tylko przetłumaczonego kodu. Dane pojedynczego żądania, na przykład wpisy w formularzu czy wartości sesji, nie są współdzielone przez OPcache.

## Dlaczego PHP2Shell uderza właśnie w ten przebieg

Obie luki PHP2Shell nie dotyczą jednej aplikacji, lecz samego przebiegu. W przypadku CVE-2026-109618 stan braku pamięci (out of memory) może przerwać PHP, gdy dane żądania są dopiero częściowo przygotowane, czyli w kroku 4. Przy późniejszym sprzątaniu nieprawidłowe dane mogą zostać potraktowane jako prawidłowe.

W przypadku CVE-2026-109619 wewnętrzny stan żądania może pozostać po zwolnieniu pamięci. Późniejsze żądanie w tym samym workerze może go użyć, zanim zostanie zresetowany. Dotyczy to kroku 7, czyli sprzątania. Tło wyjaśniamy na stronie [CVE-2026-109619](https://phpsos.de/pl/php2shell/cve-2026-109619/) oraz w artykule o [cyklu życia żądania](https://phpsos.de/pl/php/request-lebenszyklus/).

Wynika z tego: środki ochrony w kodzie aplikacji, na przykład wtyczki bezpieczeństwa, działają dopiero w kroku 6. W mod_php według zespołu PHP pokazano nawet exploit, zanim w ogóle zacznie działać kod aplikacji. Skuteczna jest tylko aktualizacja PHP do 8.5.12, 8.4.27, 8.3.36 lub 8.2.35 i restart wszystkich procesów PHP, ponieważ długo żyjące workery w przeciwnym razie nadal wykonują stary kod.

## Jak konkretnie pomaga PHP SOS?

- **Uwidocznienie przebiegu:** Ustalamy, jaki tryb pracy, jaka konfiguracja i jaka pamięć podręczna są faktycznie aktywne na Państwa serwerze.
- **Prawidłowa aktualizacja:** Instalujemy aktualizację PHP i na podstawie czasów startu sprawdzamy, że nie działa już żaden stary proces.
- **Zabezpieczenie warstw:** W ramach [utwardzania serwera](https://phpsos.de/pl/leistungen/server-haertung/) ograniczamy rozmiary żądań, pamięć i uprawnienia tam, gdzie działają: przed kodem aplikacji.
- **Sprawdzenie śladów:** Na serwerach dostępnych bez zabezpieczeń szukamy oznak włamania.


## Częste pytania

**Czy kod PHP jest tłumaczony od nowa przy każdym wywołaniu?**  
Bez pamięci podręcznej tak: PHP rozbija skrypt, buduje drzewo składni i tworzy z niego opcody. Przy aktywnym OPcache opcody leżą we wspólnej pamięci i są używane ponownie, dopóki plik się nie zmieni.

**Co pozostaje w pamięci po żądaniu?**  
Co do zasady stan żądania jest na końcu sprzątany, aby następne żądanie zaczynało od czystego stanu. Długo żyją tylko takie rzeczy jak OPcache czy trwałe połączenia. Właśnie to sprzątanie dotyczy CVE-2026-109619.

**Dlaczego po aktualizacji trzeba zrestartować PHP?**  
W PHP-FPM i mod_php procesy działają nieprzerwanie i mają załadowany stary kod programu. Nowe pliki na dysku niczego tu nie zmieniają. Dopiero restart ładuje poprawiony kod.

**Czy serwer WWW bez PHP jest bezpieczniejszy?**  
Ma mniejszą powierzchnię ataku, ponieważ żadna logika programu nie reaguje na żądania. Dla czysto statycznych treści to realna opcja. Dla sklepów, formularzy i logowania potrzebny jest jednak język po stronie serwera, a wtedy liczy się jego utrzymanie.

## Źródła

- [Podręcznik PHP: wprowadzenie](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)
- [Podręcznik PHP: OPcache](https://www.php.net/manual/en/book.opcache.php)
