Skip to content

Глава 0.1: Как работает веб

HTTP, клиент-сервер, и что происходит, когда ты открываешь сайт


Зачем это знать?

Прежде чем писать PHP-код, тебе нужно понять среду, в которой этот код работает. PHP — это язык для веба. Если ты не понимаешь, как работает веб, ты будешь писать код вслепую.

Представь, что ты учишься водить машину, но не знаешь, что у неё есть двигатель, колёса и руль. Технически можно запомнить последовательность действий, но понимания не будет.

Эта глава — твой "курс автомеханика" перед вождением.


1. Клиент и сервер: два участника разговора

Что такое клиент?

Клиент — это программа, которая запрашивает информацию.

Примеры клиентов:

  • Браузер (Chrome, Firefox, Safari)
  • Мобильное приложение
  • Программа curl в терминале
  • Даже другой сервер может быть клиентом!

Когда ты открываешь браузер и вводишь адрес — твой браузер становится клиентом.

Что такое сервер?

Сервер — это программа (а часто и компьютер), которая отвечает на запросы.

Сервер:

  • Ждёт входящих запросов
  • Обрабатывает их
  • Отправляет ответ обратно

Важно понять: сервер — это не магическая коробка где-то в облаках. Это обычный компьютер с программой, которая слушает сеть. Ты можешь запустить сервер прямо на своём ноутбуке.

Модель "клиент-сервер"

┌──────────────┐                              ┌──────────────┐
│              │      1. Запрос (Request)     │              │
│    КЛИЕНТ    │  ──────────────────────────► │    СЕРВЕР    │
│   (Браузер)  │                              │  (PHP + веб) │
│              │  ◄────────────────────────── │              │
│              │      2. Ответ (Response)     │              │
└──────────────┘                              └──────────────┘

Это всегда работает так:

  1. Клиент инициирует общение (отправляет запрос)
  2. Сервер отвечает
  3. Соединение закрывается

Сервер никогда не начинает разговор первым. Он только отвечает.

Аналогия: Представь ресторан. Ты (клиент) делаешь заказ официанту. Кухня (сервер) готовит и возвращает блюдо. Кухня не выбегает к тебе с едой, пока ты не попросил.


2. Что такое HTTP?

Определение

HTTP (HyperText Transfer Protocol) — это язык общения между клиентом и сервером.

Когда браузер и сервер "разговаривают", им нужен общий язык. HTTP — это набор правил, как формулировать запросы и ответы, чтобы обе стороны понимали друг друга.

Почему именно HTTP?

В интернете есть разные протоколы:

  • FTP — для передачи файлов
  • SMTP — для почты
  • SSH — для удалённого доступа
  • HTTP/HTTPS — для веб-страниц и API

Когда ты вводишь https://google.com, буквы https:// говорят браузеру: "используй протокол HTTPS" (это HTTP с шифрованием).

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
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-запроса с телом:

http
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-запроса

Браузер формирует и отправляет запрос:

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, картинки) отдаётся напрямую           │
│                                                            │
└────────────────────────────────────────────────────────────┘
  1. Nginx получает запрос
  2. Если это .php файл — передаёт PHP-интерпретатору
  3. PHP выполняет код, возможно обращается к базе данных
  4. PHP возвращает HTML
  5. Nginx отправляет ответ клиенту

Шаг 6: Получение ответа

http
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: Финальный рендер

Когда всё загружено:

  1. Браузер строит DOM (структуру HTML)
  2. Применяет CSS (визуальные стили)
  3. Выполняет JavaScript
  4. Отрисовывает страницу на экране

Полная схема

┌─────────┐     ┌─────┐     ┌──────────┐     ┌─────────┐     ┌────────┐
│ Ты      │────►│ 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...]──► Сервер
        Хакер видит: бессмысленный набор символов

Как работает (упрощённо)

  1. Браузер и сервер договариваются о ключе шифрования
  2. Все данные шифруются этим ключом
  3. Даже если кто-то перехватит — не расшифрует без ключа

На практике

  • Современные сайты обязаны использовать 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 — сколько времени заняло

Упражнение: исследуй запросы

  1. Открой https://example.com
  2. Открой DevTools → Network
  3. Обнови страницу
  4. Найди главный запрос (первый, тип document)
  5. Посмотри:
    • Какой HTTP-метод использован?
    • Какой статус ответа?
    • Какие заголовки отправил браузер?
    • Какой Content-Type в ответе?

curl: HTTP из терминала

curl — это программа для отправки HTTP-запросов из командной строки.

bash
# Простой GET-запрос
curl https://example.com

# Показать заголовки ответа
curl -I https://example.com

# Показать и заголовки, и тело
curl -i https://example.com

# Показать всё (включая заголовки запроса)
curl -v https://example.com

Попробуй выполнить:

bash
curl -i https://httpbin.org/get

httpbin.org — это тестовый сервис, который возвращает информацию о твоём запросе.


9. Где здесь PHP?

PHP работает на стороне сервера. Когда приходит запрос на .php файл:

┌─────────┐   GET /index.php   ┌─────────┐   Запустить PHP   ┌─────────┐
│ Браузер │ ─────────────────► │  Nginx  │ ────────────────► │   PHP   │
│         │                    │         │                    │         │
│         │                    │         │ ◄──────────────── │ Выполнить│
│         │ ◄───────────────── │         │   HTML-результат  │  код    │
└─────────┘   HTML-страница    └─────────┘                   └─────────┘

PHP-код выполняется до того, как ответ уходит клиенту. Клиент никогда не видит PHP-код — только результат его работы.

php
<?php
// Это видит только сервер
$name = "Мир";
?>
<!DOCTYPE html>
<html>
<body>
    <h1>Привет, <?php echo $name; ?>!</h1>
</body>
</html>

Браузер получит:

html
<!DOCTYPE html>
<html>
<body>
    <h1>Привет, Мир!</h1>
</body>
</html>

Никакого <?php — только чистый HTML.


10. Ключевые термины (глоссарий)

ТерминОпределение
КлиентПрограмма, отправляющая запросы (браузер)
СерверПрограмма, отвечающая на запросы
HTTPПротокол передачи гипертекста
HTTPSHTTP с шифрованием
Запрос (Request)Сообщение от клиента к серверу
Ответ (Response)Сообщение от сервера к клиенту
МетодТип действия (GET, POST, PUT, DELETE)
URI/URLАдрес ресурса
ЗаголовкиМетаданные запроса/ответа
Тело (Body)Содержимое запроса/ответа
Статус-кодЧисловой код результата (200, 404, 500)
DNSСистема преобразования доменов в IP
StatelessБез сохранения состояния между запросами
CookieДанные, хранимые браузером и отправляемые с каждым запросом

11. Упражнения

Упражнение 1: Анализ запросов (15 минут)

  1. Открой https://github.com в браузере
  2. Открой DevTools (F12) → Network
  3. Обнови страницу
  4. Ответь на вопросы:
    • Сколько всего запросов было сделано?
    • Какой самый "тяжёлый" ресурс (по размеру)?
    • Есть ли запросы со статусом не 200?
    • Найди запрос с типом xhr или fetch — это AJAX-запросы

Упражнение 2: curl эксперименты (15 минут)

Выполни команды и изучи результат:

bash
# 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 минут)

На бумаге нарисуй схему того, что происходит, когда:

  1. Ты вводишь https://shop.example.com/products?category=phones
  2. Логинишься на сайт (отправляешь форму с логином и паролем)

Отметь: DNS, TCP, HTTP-запрос, сервер, PHP, базу данных, ответ.


12. Вопросы для самопроверки

Ответь своими словами, без подглядывания:

  1. Чем отличается клиент от сервера?

  2. Что такое HTTP и зачем он нужен?

  3. Какая разница между GET и POST?

  4. Что означает статус 404? А 500?

  5. Почему HTTP называют "stateless"?

  6. Что видит браузер: PHP-код или результат его выполнения?

  7. Зачем нужен HTTPS?

  8. Что такое 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, локальный сервер

Выпущено под лицензией MIT