Как PHP обрабатывает запрос
Чему вы научитесь:
- объяснять, как адрес в браузере превращается в страницу и почему PHP забывает всё после запроса;
- читать параметры запроса из
$_GETи$_POSTи подставлять значения по умолчанию через??; - экранировать вывод через
htmlspecialchars, чтобы текст посетителя не стал кодом страницы; - проверять ввод через
filter_varи белый список разрешённых значений.

Представьте ресторан с раздачей. Посетитель подходит к стойке и отдаёт заказ. Повар читает его, готовит блюдо по рецепту и ставит тарелку на стойку.
Следующий заказ он начинает с чистого стола и ничего не помнит о прошлом.
Сайт на PHP устроен так же:
- браузер — посетитель;
- веб-сервер — стойка;
- PHP — повар;
- ваш файл
.php— рецепт.
Блюдо — это HTML, из которого браузер собирает страницу.
До сих пор вы запускали программы командой php file.php, и echo печатал в окно терминала. На сайте PHP выполняет такой же файл, только напечатанное уходит в браузер.
Запрос и ответ
Запрос — сообщение, которое браузер отправляет серверу: какой адрес открыть и, может быть, какие данные передать. Ответ — то, что сервер присылает обратно, чаще всего HTML.
Давайте разберём, что происходит, когда вы открываете адрес localhost:8000/menu.php:
- Браузер отправляет запрос на этот адрес.
- Веб-сервер — это программа, которая принимает запросы. Увидев, что имя файла заканчивается на
.php, он передаёт файл в PHP. - PHP выполняет
menu.phpс первой строки до последней, как в терминале. - Всё, что программа напечатала, становится ответом.
- Браузер получает ответ и рисует страницу.
Встроенный сервер
Для опытов отдельный веб-сервер не нужен: он встроен в PHP. Откройте терминал в папке с файлами и выполните команду:
php -S localhost:8000Пока команда работает, PHP отвечает на запросы к адресу localhost:8000. Здесь localhost означает ваш компьютер, а 8000 — номер, на котором сервер ждёт запросы.
Откройте в браузере localhost:8000/menu.php, и PHP выполнит файл menu.php из этой папки. Чтобы остановить сервер, нажмите Ctrl+C в терминале.
Встроенный сервер — инструмент для разработки. Сайты в интернете работают на других веб-серверах, но путь запроса у них тот же.
HTML и <?=
Файл .php не обязан состоять из одного кода. Всё, что стоит вне тегов <?php … ?>, PHP отправляет в ответ как есть. Такой файл — HTML со вставками PHP — называют шаблоном:
<?php
$title = 'Menu';
$dish = 'Soup';
?>
<h1><?= $title ?></h1>
<p>Dish of the day: <?= $dish ?></p>Давайте разберём по строкам:
- Между
<?phpи?>стоит обычный код: две переменные. - Вне тегов
<?php … ?>идёт HTML, и PHP копирует его в ответ без изменений. <?= $title ?>— короткая запись для<?php echo $title; ?>: она печатает значение прямо посреди HTML.
Браузер получит такой ответ:
<h1>Menu</h1>
<p>Dish of the day: Soup</p>Закрывающий тег ?> в файле, где есть только код, не ставят. В шаблоне он нужен: после него снова начинается HTML.
Каждый запрос с чистого листа
Вот программа, которая будто бы считает посещения:
<?php
$visits = 0;
$visits++;
echo 'Visits: ', $visits, "\n"; // Visits: 1Сколько бы раз вы ни обновили страницу, она покажет Visits: 1. На каждый запрос PHP выполняет файл заново, с первой строки, а в конце запроса уничтожает все его переменные и объекты. Следующий запрос о них ничего не знает.
Такую модель называют shared-nothing — «ничего общего»: у запросов нет общих переменных и объектов. Даже статическое свойство класса, общее для всех объектов, живёт только до конца запроса.
На настоящем сервере PHP обычно работает через php-fpm. php-fpm заранее запускает несколько копий PHP — рабочих процессов, и каждый из них обслуживает запросы по очереди. Процесс живёт долго, но после каждого запроса PHP освобождает всю память этого запроса.
Здесь картинка с поваром упрощает. У сайта тоже есть память о посетителях, только хранится она не в PHP.
Данные, которые должны пережить запрос, записывают в базу данных. А то, что нужно помнить о конкретном посетителе, хранят в сессии. Браузер приносит с каждым запросом номерок, как из гардероба, и по нему сервер находит данные посетителя.
На собеседовании часто спрашивают, переживёт ли статическое свойство следующий запрос. Ответ — нет, и это защищает запросы друг от друга: ошибка в одном не испортит данные другого.
Частая ошибка
Счётчик посещений хранят в статическом свойстве и ждут, что он будет расти:
<?php
class Counter
{
public static int $hits = 0;
}
Counter::$hits++; // ✗
echo 'Hits: ', Counter::$hits, "\n";Каждый запрос печатает Hits: 1, и PHP не выдаёт никаких сообщений. К концу запроса свойство исчезает вместе со всем остальным, и следующий запрос снова начинает с 0. Счётчик, который должен расти, хранят в базе данных.
Главное
- Браузер отправляет запрос, веб-сервер передаёт файл
.phpв PHP, а всё напечатанное становится ответом. php -S localhost:8000запускает встроенный сервер для разработки, а<?= $x ?>печатает значение посреди HTML.- Каждый запрос начинается с чистого листа: в конце запроса PHP уничтожает все переменные, объекты и статические свойства.
- То, что должно пережить запрос, хранят в базе данных или в сессии.