Глава 0.1: Как работает веб
HTTP, клиент-сервер, и что происходит, когда ты открываешь сайт
Зачем это знать?
Прежде чем писать PHP-код, тебе нужно понять среду, в которой этот код работает. PHP — это язык для веба. Если ты не понимаешь, как работает веб, ты будешь писать код вслепую.
Представь, что ты учишься водить машину, но не знаешь, что у неё есть двигатель, колёса и руль. Технически можно запомнить последовательность действий, но понимания не будет.
Эта глава — твой "курс автомеханика" перед вождением.
1. Клиент и сервер: два участника разговора
Что такое клиент?
Клиент — это программа, которая запрашивает информацию.
Примеры клиентов:
- Браузер (Chrome, Firefox, Safari)
- Мобильное приложение
- Программа curl в терминале
- Даже другой сервер может быть клиентом!
Когда ты открываешь браузер и вводишь адрес — твой браузер становится клиентом.
Что такое сервер?
Сервер — это программа (а часто и компьютер), которая отвечает на запросы.
Сервер:
- Ждёт входящих запросов
- Обрабатывает их
- Отправляет ответ обратно
Важно понять: сервер — это не магическая коробка где-то в облаках. Это обычный компьютер с программой, которая слушает сеть. Ты можешь запустить сервер прямо на своём ноутбуке.
Модель "клиент-сервер"
┌──────────────┐ ┌──────────────┐
│ │ 1. Запрос (Request) │ │
│ КЛИЕНТ │ ──────────────────────────► │ СЕРВЕР │
│ (Браузер) │ │ (PHP + веб) │
│ │ ◄────────────────────────── │ │
│ │ 2. Ответ (Response) │ │
└──────────────┘ └──────────────┘Это всегда работает так:
- Клиент инициирует общение (отправляет запрос)
- Сервер отвечает
- Соединение закрывается
Сервер никогда не начинает разговор первым. Он только отвечает.
Аналогия: Представь ресторан. Ты (клиент) делаешь заказ официанту. Кухня (сервер) готовит и возвращает блюдо. Кухня не выбегает к тебе с едой, пока ты не попросил.
2. Что такое HTTP?
Определение
HTTP (HyperText Transfer Protocol) — это язык общения между клиентом и сервером.
Когда браузер и сервер "разговаривают", им нужен общий язык. HTTP — это набор правил, как формулировать запросы и ответы, чтобы обе стороны понимали друг друга.
Почему именно HTTP?
В интернете есть разные протоколы:
- FTP — для передачи файлов
- SMTP — для почты
- SSH — для удалённого доступа
- HTTP/HTTPS — для веб-страниц и API
Когда ты вводишь https://google.com, буквы https:// говорят браузеру: "используй протокол HTTPS" (это HTTP с шифрованием).
HTTP — текстовый протокол
Это важно: HTTP — это просто текст. Никакой магии. Когда браузер отправляет запрос, он буквально отправляет текстовое сообщение по сети.
Вот как выглядит реальный HTTP-запрос:
GET /index.html HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0
Accept: text/html
Accept-Language: ru-RU,ruИ вот реальный HTTP-ответ:
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 1234
<!DOCTYPE html>
<html>
<head><title>Привет!</title></head>
<body><h1>Добро пожаловать</h1></body>
</html>Да, это всё. Браузер отправляет текст, сервер возвращает текст. Браузер потом этот текст (HTML) превращает в красивую страницу.
3. Анатомия HTTP-запроса
Структура запроса
┌─────────────────────────────────────────────────────────────┐
│ GET /products?category=phones HTTP/1.1 ← Стартовая │
├─────────────────────────────────────────────────────────────┤
│ Host: shop.example.com ← Заголовки │
│ User-Agent: Mozilla/5.0 (Headers) │
│ Accept: text/html │
│ Cookie: session_id=abc123 │
│ Accept-Language: ru-RU │
├─────────────────────────────────────────────────────────────┤
│ ← Пустая строка│
├─────────────────────────────────────────────────────────────┤
│ (тело запроса — для POST/PUT) ← Тело (Body) │
└─────────────────────────────────────────────────────────────┘Стартовая строка: три части
GET /products?category=phones HTTP/1.1
│ │ │
│ │ └── Версия протокола
│ │
│ └── URI (путь + параметры)
│
└── Метод (что хотим сделать)HTTP-методы (самые важные)
| Метод | Для чего | Пример |
|---|---|---|
| GET | Получить данные | Открыть страницу, загрузить картинку |
| POST | Отправить данные | Отправить форму регистрации |
| PUT | Заменить данные | Обновить профиль пользователя |
| PATCH | Частично изменить | Изменить только email |
| DELETE | Удалить | Удалить комментарий |
На этапе изучения тебе нужны только GET и POST:
- GET — когда ты просто открываешь страницу
- POST — когда отправляешь форму
URI: путь к ресурсу
/products?category=phones&sort=price
│ │
│ └── Query String (параметры после ?)
│
└── Path (путь)URI говорит серверу, что именно ты хочешь получить.
Заголовки (Headers)
Заголовки — это метаданные о запросе. Они сообщают серверу дополнительную информацию:
| Заголовок | Что означает | Пример |
|---|---|---|
Host | Какой сайт запрашиваем | Host: google.com |
User-Agent | Какой браузер/программа | User-Agent: Chrome/120 |
Accept | Какой формат ответа хотим | Accept: text/html |
Cookie | Куки для авторизации | Cookie: session=xyz |
Content-Type | Тип отправляемых данных | Content-Type: application/json |
Тело запроса (Body)
Тело есть только у POST, PUT, PATCH. В GET тела нет.
Пример POST-запроса с телом:
POST /login HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 29
username=ivan&password=secretЗдесь тело — это username=ivan&password=secret. Именно так браузер отправляет данные формы.
4. Анатомия HTTP-ответа
Структура ответа
┌─────────────────────────────────────────────────────────────┐
│ HTTP/1.1 200 OK ← Статус │
├─────────────────────────────────────────────────────────────┤
│ Content-Type: text/html; charset=UTF-8 ← Заголовки │
│ Content-Length: 1234 │
│ Set-Cookie: session_id=xyz789 │
│ Cache-Control: max-age=3600 │
├─────────────────────────────────────────────────────────────┤
│ ← Пустая строка│
├─────────────────────────────────────────────────────────────┤
│ <!DOCTYPE html> ← Тело ответа │
│ <html> │
│ <body>Контент страницы</body> │
│ </html> │
└─────────────────────────────────────────────────────────────┘Статусная строка
HTTP/1.1 200 OK
│ │ │
│ │ └── Текстовое пояснение
│ │
│ └── Код статуса
│
└── Версия протоколаКоды статуса (запомни эти!)
Коды делятся на группы по первой цифре:
| Группа | Значение | Примеры |
|---|---|---|
| 1xx | Информационные | 100 Continue |
| 2xx | Успех | 200 OK, 201 Created |
| 3xx | Перенаправление | 301 Moved, 302 Found, 304 Not Modified |
| 4xx | Ошибка клиента | 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found |
| 5xx | Ошибка сервера | 500 Internal Error, 502 Bad Gateway, 503 Unavailable |
Самые частые:
200 OK — Всё хорошо, держи ответ
201 Created — Ресурс создан (после POST)
301 Moved — Страница переехала навсегда
302 Found — Временный редирект
400 Bad Request — Кривой запрос
401 Unauthorized — Нужна авторизация
403 Forbidden — Доступ запрещён
404 Not Found — Страница не найдена
500 Internal Error — Сервер сломался
503 Unavailable — Сервер перегруженЗаголовки ответа
| Заголовок | Что означает |
|---|---|
Content-Type | Тип контента (HTML, JSON, картинка) |
Content-Length | Размер тела в байтах |
Set-Cookie | Установить куку в браузере |
Location | Куда перенаправить (для 3xx) |
Cache-Control | Как кешировать ответ |
Тело ответа
Тело — это сам контент: HTML страницы, JSON данные, байты картинки, и т.д.
5. Что происходит, когда ты вводишь URL в браузер?
Давай разберём по шагам, что происходит, когда ты вводишь https://example.com/about и нажимаешь Enter.
Шаг 1: Парсинг URL
Браузер разбирает URL на части:
https://example.com/about?ref=main#section2
│ │ │ │ │
│ │ │ │ └── Fragment (не отправляется серверу)
│ │ │ │
│ │ │ └── Query String (параметры)
│ │ │
│ │ └── Path (путь)
│ │
│ └── Host (домен)
│
└── Scheme (протокол)Шаг 2: DNS-резолвинг
Браузеру нужен IP-адрес сервера. Доменное имя example.com — это для людей. Компьютеры общаются по IP.
┌──────────┐ "Какой IP у example.com?" ┌─────────────┐
│ Браузер │ ──────────────────────────────► │ DNS-сервер │
│ │ ◄────────────────────────────── │ │
└──────────┘ "93.184.216.34" └─────────────┘DNS (Domain Name System) — это как телефонная книга интернета. Преобразует имена в адреса.
Шаг 3: TCP-соединение
Браузер устанавливает соединение с сервером по IP и порту.
Порты по умолчанию:
- HTTP: 80
- HTTPS: 443Происходит "рукопожатие" (handshake):
┌──────────┐ ┌──────────┐
│ Браузер │ ── SYN ───────────────────► │ Сервер │
│ │ ◄─ SYN-ACK ───────────────── │ │
│ │ ── ACK ───────────────────► │ │
└──────────┘ Соединение установлено └──────────┘Для HTTPS добавляется ещё TLS-рукопожатие (обмен ключами шифрования).
Шаг 4: Отправка HTTP-запроса
Браузер формирует и отправляет запрос:
GET /about HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0
Accept: text/html,application/xhtml+xml
Accept-Language: ru-RU,ru;q=0.9,en;q=0.8
Accept-Encoding: gzip, deflate, br
Connection: keep-aliveШаг 5: Сервер обрабатывает запрос
На сервере работает веб-сервер (Nginx, Apache) и твой PHP-код:
┌────────────────────────────────────────────────────────────┐
│ СЕРВЕР │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────────────┐ │
│ │ Nginx │ ───► │ PHP │ ───► │ База данных │ │
│ │ │ ◄─── │ │ ◄─── │ (если нужно) │ │
│ └─────────┘ └─────────┘ └─────────────────────┘ │
│ │ │
│ ▼ │
│ Статика (CSS, JS, картинки) отдаётся напрямую │
│ │
└────────────────────────────────────────────────────────────┘- Nginx получает запрос
- Если это
.phpфайл — передаёт PHP-интерпретатору - PHP выполняет код, возможно обращается к базе данных
- PHP возвращает HTML
- Nginx отправляет ответ клиенту
Шаг 6: Получение ответа
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 5432
<!DOCTYPE html>
<html>
<head>
<title>О нас</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<h1>О компании</h1>
<img src="/images/logo.png">
<script src="/js/app.js"></script>
</body>
</html>Шаг 7: Рендеринг страницы
Браузер получил HTML. Но в нём есть ссылки на другие ресурсы: CSS, JS, картинки.
Браузер отправляет дополнительные запросы:
GET /css/style.css HTTP/1.1
GET /images/logo.png HTTP/1.1
GET /js/app.js HTTP/1.1Каждый ресурс — отдельный HTTP-запрос!
Шаг 8: Финальный рендер
Когда всё загружено:
- Браузер строит DOM (структуру HTML)
- Применяет CSS (визуальные стили)
- Выполняет JavaScript
- Отрисовывает страницу на экране
Полная схема
┌─────────┐ ┌─────┐ ┌──────────┐ ┌─────────┐ ┌────────┐
│ Ты │────►│ DNS │────►│ TCP/TLS │────►│ Сервер │────►│ PHP │
│ вводишь │ │ │ │ connect │ │ (Nginx) │ │ │
│ URL │ └─────┘ └──────────┘ └─────────┘ └────────┘
└─────────┘ │ │ │ │
│ │ │ │
▼ ▼ ▼ ▼
IP-адрес Соединение HTTP-запрос Обработка
установлено принят + ответ
│
┌─────────┐ ┌──────────┐ ┌──────────┐ │
│ Страница│◄────│ Рендеринг│◄────│ HTML + │◄──────────────────┘
│ на │ │ + доп. │ │ ресурсы │
│ экране │ │ запросы │ │ получены │
└─────────┘ └──────────┘ └──────────┘6. Stateless: HTTP не помнит тебя
Что значит "stateless"?
HTTP — stateless (без состояния). Это значит, что каждый запрос независим. Сервер не помнит предыдущие запросы.
Запрос 1: GET / → Ответ: Главная страница
Запрос 2: GET /profile → Ответ: "А ты кто?"Сервер не знает, что запрос 1 и запрос 2 — от одного человека!
Как тогда работает авторизация?
Через куки (cookies) и сессии (sessions):
1. Ты логинишься (POST /login)
2. Сервер проверяет пароль
3. Сервер создаёт сессию и отправляет:
Set-Cookie: session_id=abc123
4. Браузер сохраняет куку
5. При следующих запросах браузер автоматически отправляет:
Cookie: session_id=abc123
6. Сервер видит session_id, находит твою сессию, знает кто тыМы подробно разберём это в главе про сессии.
7. HTTPS: шифрование
Зачем нужен HTTPS?
HTTP передаёт данные открытым текстом. Любой, кто "слушает" сеть (Wi-Fi в кафе, провайдер), видит всё: логины, пароли, сообщения.
HTTPS = HTTP + TLS (шифрование)
HTTP: Браузер ──[пароль: "secret123"]──► Сервер
Хакер видит: "пароль: secret123"
HTTPS: Браузер ──[x7@#kL9!mNq...]──► Сервер
Хакер видит: бессмысленный набор символовКак работает (упрощённо)
- Браузер и сервер договариваются о ключе шифрования
- Все данные шифруются этим ключом
- Даже если кто-то перехватит — не расшифрует без ключа
На практике
- Современные сайты обязаны использовать HTTPS
- Браузеры помечают HTTP-сайты как "небезопасные"
- Let's Encrypt даёт бесплатные сертификаты
8. Практика: смотрим реальные запросы
Инструменты разработчика в браузере
Открой любой сайт и нажми F12 (или Ctrl+Shift+I). Перейди на вкладку Network (Сеть).
Обнови страницу — увидишь все HTTP-запросы:
┌─────────────────────────────────────────────────────────────────┐
│ Network │
├──────────┬────────┬────────┬─────────┬────────┬────────────────┤
│ Name │ Status │ Type │ Size │ Time │ Waterfall │
├──────────┼────────┼────────┼─────────┼────────┼────────────────┤
│ / │ 200 │ doc │ 15.2 KB │ 234 ms │ ████ │
│ style.css│ 200 │ css │ 4.1 KB │ 45 ms │ ██ │
│ logo.png │ 200 │ png │ 12.0 KB │ 67 ms │ ███ │
│ app.js │ 200 │ js │ 89.3 KB │ 123 ms │ █████ │
└──────────┴────────┴────────┴─────────┴────────┴────────────────┘Кликни на любой запрос — увидишь:
- Headers — заголовки запроса и ответа
- Response — тело ответа
- Timing — сколько времени заняло
Упражнение: исследуй запросы
- Открой
https://example.com - Открой DevTools → Network
- Обнови страницу
- Найди главный запрос (первый, тип
document) - Посмотри:
- Какой HTTP-метод использован?
- Какой статус ответа?
- Какие заголовки отправил браузер?
- Какой
Content-Typeв ответе?
curl: HTTP из терминала
curl — это программа для отправки HTTP-запросов из командной строки.
# Простой GET-запрос
curl https://example.com
# Показать заголовки ответа
curl -I https://example.com
# Показать и заголовки, и тело
curl -i https://example.com
# Показать всё (включая заголовки запроса)
curl -v https://example.comПопробуй выполнить:
curl -i https://httpbin.org/gethttpbin.org — это тестовый сервис, который возвращает информацию о твоём запросе.
9. Где здесь PHP?
PHP работает на стороне сервера. Когда приходит запрос на .php файл:
┌─────────┐ GET /index.php ┌─────────┐ Запустить PHP ┌─────────┐
│ Браузер │ ─────────────────► │ Nginx │ ────────────────► │ PHP │
│ │ │ │ │ │
│ │ │ │ ◄──────────────── │ Выполнить│
│ │ ◄───────────────── │ │ HTML-результат │ код │
└─────────┘ HTML-страница └─────────┘ └─────────┘PHP-код выполняется до того, как ответ уходит клиенту. Клиент никогда не видит PHP-код — только результат его работы.
<?php
// Это видит только сервер
$name = "Мир";
?>
<!DOCTYPE html>
<html>
<body>
<h1>Привет, <?php echo $name; ?>!</h1>
</body>
</html>Браузер получит:
<!DOCTYPE html>
<html>
<body>
<h1>Привет, Мир!</h1>
</body>
</html>Никакого <?php — только чистый HTML.
10. Ключевые термины (глоссарий)
| Термин | Определение |
|---|---|
| Клиент | Программа, отправляющая запросы (браузер) |
| Сервер | Программа, отвечающая на запросы |
| HTTP | Протокол передачи гипертекста |
| HTTPS | HTTP с шифрованием |
| Запрос (Request) | Сообщение от клиента к серверу |
| Ответ (Response) | Сообщение от сервера к клиенту |
| Метод | Тип действия (GET, POST, PUT, DELETE) |
| URI/URL | Адрес ресурса |
| Заголовки | Метаданные запроса/ответа |
| Тело (Body) | Содержимое запроса/ответа |
| Статус-код | Числовой код результата (200, 404, 500) |
| DNS | Система преобразования доменов в IP |
| Stateless | Без сохранения состояния между запросами |
| Cookie | Данные, хранимые браузером и отправляемые с каждым запросом |
11. Упражнения
Упражнение 1: Анализ запросов (15 минут)
- Открой
https://github.comв браузере - Открой DevTools (F12) → Network
- Обнови страницу
- Ответь на вопросы:
- Сколько всего запросов было сделано?
- Какой самый "тяжёлый" ресурс (по размеру)?
- Есть ли запросы со статусом не 200?
- Найди запрос с типом
xhrилиfetch— это AJAX-запросы
Упражнение 2: curl эксперименты (15 минут)
Выполни команды и изучи результат:
# 1. Получи заголовки Google
curl -I https://google.com
# 2. Посмотри, куда редиректит http://github.com
curl -I http://github.com
# 3. Отправь POST-запрос
curl -X POST https://httpbin.org/post -d "name=Ivan&age=25"
# 4. Отправь JSON
curl -X POST https://httpbin.org/post \
-H "Content-Type: application/json" \
-d '{"name": "Ivan", "age": 25}'Упражнение 3: Нарисуй схему (10 минут)
На бумаге нарисуй схему того, что происходит, когда:
- Ты вводишь
https://shop.example.com/products?category=phones - Логинишься на сайт (отправляешь форму с логином и паролем)
Отметь: DNS, TCP, HTTP-запрос, сервер, PHP, базу данных, ответ.
12. Вопросы для самопроверки
Ответь своими словами, без подглядывания:
Чем отличается клиент от сервера?
Что такое HTTP и зачем он нужен?
Какая разница между GET и POST?
Что означает статус 404? А 500?
Почему HTTP называют "stateless"?
Что видит браузер: PHP-код или результат его выполнения?
Зачем нужен HTTPS?
Что такое DNS?
13. Частые заблуждения
"Сервер — это какой-то особенный компьютер"
Нет. Сервер — это роль. Твой ноутбук может быть сервером, если на нём запущена программа, принимающая HTTP-запросы. Так работает локальная разработка.
"PHP выполняется в браузере"
Нет! PHP выполняется на сервере. Браузер получает только результат (HTML, JSON). Браузер вообще не знает, что на сервере был PHP — может, это Python или Go.
"Каждый клик — один запрос"
Не всегда. Современные сайты используют JavaScript для динамических обновлений без полной перезагрузки (AJAX). Но в основе всё равно HTTP-запросы.
"HTTPS защищает от всего"
HTTPS защищает данные в пути (от перехвата). Он не защищает от:
- Вирусов на твоём компьютере
- Фишинговых сайтов (сайт может быть HTTPS, но мошенническим)
- SQL-инъекций и других атак на сервер
14. Что дальше?
Теперь ты понимаешь, как работает веб на базовом уровне. В следующей главе мы:
- Установим PHP и настроим рабочее окружение
- Запустим локальный сервер
- Напишем первый PHP-скрипт и увидим, как он обрабатывает HTTP-запрос
Резюме главы
┌────────────────────────────────────────────────────────────────┐
│ ЗАПОМНИ ГЛАВНОЕ │
├────────────────────────────────────────────────────────────────┤
│ │
│ • Веб — это клиент-серверная архитектура │
│ • Клиент запрашивает, сервер отвечает │
│ • HTTP — протокол (язык) их общения │
│ • Запрос: метод + путь + заголовки + тело │
│ • Ответ: статус + заголовки + тело │
│ • HTTP stateless — каждый запрос независим │
│ • PHP работает на сервере, клиент видит только результат │
│ • HTTPS = HTTP + шифрование │
│ │
└────────────────────────────────────────────────────────────────┘Следующая глава: Глава 0.2: Окружение разработчика — установка PHP, настройка VS Code, локальный сервер