Перейти к содержимому
Поиск
Php Разработка

PHP: полный мануал с примерами, функциями и ООП

Практический мануал PHP: от переменных и читаемого кода до безопасных форм, интеграций, базы данных и ООП на примере магазина. Учебный маршрут, поиск функций, подробные примеры, разбор ошибок и исходники для скачивания.

Александр НекрасовИзменено:
Практический мануал PHP: от переменных и функций к объектной модели интернет-магазина
PHP 8.5.11149 глав4458 карточек справочника
Дерево руководства

Глава 2 · С нуля → практика

Начало: первый PHP-файл, страница и данные формы

От одной инструкции echo до понятного пути HTML-форма → запрос → проверка → ответ. Каждый новый знак и участник разобран до применения.

Что вы сможете сделать с PHP

Представьте небольшую мастерскую. Сначала на сайте достаточно адреса и расписания. Затем посетитель хочет оставить заявку, увидеть свои заказы и получить сообщение о готовности. Одного текста страницы уже мало: нужно принять данные, проверить их, сохранить и построить персональный ответ. PHP позволяет описать эти действия программой. Здесь начнём с одного видимого сообщения, затем разберём, как посетитель передаёт программе данные.

PHP — открытый язык программирования общего назначения, особенно распространённый в веб-разработке. Название раскрывается как PHP: Hypertext Preprocessor. Исполняющую программу тоже часто называют PHP; её вы запускаете, чтобы выполнить файл с кодом. Исходный файл — записанная инструкция, а результат выполнения — то, что получилось после её обработки. Эти две вещи важно различать с первого примера.

ЗадачаЧто поручить PHPКуда идти после первых шагов
Сайт мастерскойПринять заявку, проверить поля, сформировать ответФорма от HTML до обработчика
Каталог или личный кабинетПолучить разрешённые записи из базы и показать их посетителюПараметры SQL и PDO
Связать CRM и другой сервисОтправить запрос, разобрать ответ, преобразовать данныеИнтеграция по шагам
Ежедневный отчётЗапустить файл из терминала или планировщика без браузераРабота с файлами

Для работы с конкретной базой, архивом, изображениями или сетевым протоколом могут потребоваться расширение PHP либо сторонняя библиотека. Поэтому «PHP умеет» не означает «это доступно в любой установке». Вы сможете сочетать обычные функции и объекты; выбор разбираем на задачах по мере роста программы.

Файл, PHP, веб-сервер и браузер: четыре разные роли

Наглядная модель

Что происходит, когда вы запускаете PHP-файл

Вы хотите получить сумму заказа. Файл хранит инструкции; выполнять их будет интерпретатор PHP.

  1. Файл order.php

    В тексте программы записаны цены, расчёт и команда вывода.

  2. Интерпретатор PHP

    Читает программу и выполняет её инструкции.

  3. Терминал или HTTP-ответ

    Получает вывод, например «Итого: 1500 руб.».

Для CLI вывод виден в терминале. При веб-запросе PHP обычно работает на сервере: браузер получает сформированный ответ, а не исполняет PHP-код.

Как сообщение мастерской добирается до человека
  1. Автор сохраняет hello.php с инструкцией echo
  2. Браузер запрашивает /hello.php у локального веб-сервера
  3. Веб-сервер передаёт файл PHP; PHP выполняет echo
  4. Текст ответа возвращается браузеру; браузер показывает его

Все участники могут работать на одном вашем компьютере. «Сервер» здесь обозначает роль программы, а не обязательно отдельный дорогой компьютер. В интернете браузер обычно находится у посетителя, а веб-сервер и PHP — у владельца сайта. Веб-сервер принимает запрос, PHP выполняет программу, браузер читает полученный ответ.

При запуске из терминала середина пути короче: вы → PHP → файл → вывод в терминал. Веб-сервер и браузер вообще не требуются. Напротив, открытие файла в браузере через file:///... само по себе PHP не запускает. Браузер не превращается в PHP-интерпретатор от расширения файла.

Это схема участников, а не буквальное описание внутренней памяти PHP или устройства всех серверов. В реальном приложении обработчик может выбирать файл по маршруту; адрес /orders не обязан совпадать с именем orders.php. Для первого опыта оставим прямое соответствие имени и URL.

Первая инструкция: вывести одно сообщение

Создайте в редакторе обычного текста файл hello.php. Сохраните его в UTF-8 без BOM. Не используйте документ Word и проверьте настоящее имя: при скрытых расширениях легко получить hello.php.txt. В этом файле пока только начало PHP и одна инструкция.

hello.php: первое сообщениеСамостоятельный пример
<?php
echo 'Мастерская открыта';
Ожидаемый результат
Мастерская открыта

Результат — только сообщение. Ни открывающий PHP-тег, ни echo, ни кавычки, ни точка с запятой в него не входят. Переменные, функции и классы для этой первой инструкции не нужны.

Часть записиЧто означает
<?phpНачало участка PHP-кода. После php нужен разделитель, здесь перевод строки.
echoКонструкция языка: направить следующее значение в вывод.
'Мастерская открыта'Буквальный текст, то есть строка. Кавычки отделяют его от названий команд.
;Завершение инструкции. Новая строка в редакторе не заменяет этот знак.

Закрывающий тег в файле, состоящем только из PHP, можно опустить. Здесь так и сделано. Команда echo сама не приписывает перевод строки. В терминале приглашение следующей команды поэтому может оказаться сразу после сообщения; чуть ниже добавим явный перенос.

Попробуйте сами. Поменяйте сообщение на «Приём заказов до 19:00». Что нужно изменить?

Разбор решения

Только содержимое кавычек. Назначение echo и расположение точки с запятой сохраняются.

Запустить файл в терминале и увидеть результат

Сначала PHP должен быть установлен. Команда php -v проверяет, доступен ли он в текущем терминале, и показывает версию. Если команда не найдена, это вопрос установки или пути к исполняемому файлу, а не ошибка нашего echo. Откройте терминал в папке, где лежит hello.php; только затем выполняйте следующую команду.

Команда терминала, не содержимое hello.phpФрагмент или команда
php hello.php

php — исполняемая программа, hello.php — переданный ей файл. Нажмите Enter; после сообщения выполнение закончится. Команду не вставляют между PHP-тегами. Запуск PHP-файла повторно начинает его выполнение заново.

Добавить перевод строки в вывод терминалаСамостоятельный пример
<?php
echo "Мастерская открыта\n";
Ожидаемый результат
Мастерская открыта

В двойных кавычках последовательность обратная косая черта + n обозначает один символ перевода строки. Используйте именно обратную косую черту: /n — обычный текст. Одинарные кавычки по-другому обрабатывают такие последовательности; их правила разберём в строках.

Не каждый пример ниже можно одинаково проверить через CLI: HTTP-заголовки, данные формы и сессия связаны с веб-запросом. У примеров отмечено окружение. Если серверная программа ожидает форму, запуск php handler.php не создаёт эту форму за вас.

Тот же файл через локальный веб-сервер

В той же учебной папке запустите команду ниже. Она занимает текущий терминал, пока сервер работает. Откройте браузер отдельно и введите http://127.0.0.1:8000/hello.php. На экране должно появиться наше сообщение. Здесь 127.0.0.1 — ваш компьютер, 8000 — выбранный порт, /hello.php — запрашиваемый файл внутри папки сервера.

Локальный сервер для этой учебной папкиФрагмент или команда
php -S 127.0.0.1:8000

Большая S имеет значение. Для остановки нажмите Ctrl+C в этом терминале. Если порт занят, выберите, например, 8001 и измените его также в URL. Сервер видит папку запуска; храните в ней только учебные файлы.

Встроенный сервер предназначен для разработки и проверки, а не для публичного сайта. Не меняйте адрес на 0.0.0.0, чтобы «просто заработало»: это меняет доступность сервера из сети. Для рабочего сайта используется настроенное серверное окружение. Установка и настройка рассматриваются отдельно, когда первый файл уже понятен.

Вы видитеЧто проверить
Не удаётся подключитьсяРаботает ли терминал с сервером; совпадают ли адрес и порт.
404 / Not FoundВ какой папке запущен сервер; существует ли hello.php именно там; нет ли лишнего .txt.
Исходный <?php или скачивание файлаЕсть ли PHP-обработка на выбранном сервере; не открыт ли файл напрямую; используется ли полный открывающий тег.
Старое сообщениеСохранён ли файл; тот ли путь открыт; обновлена ли страница.

HTML задаёт страницу, PHP подставляет её часть

HTML описывает содержание страницы. <h1>...</h1> выделяет главный заголовок, <p>...</p> — абзац. У большинства таких элементов есть начало и конец. PHP может стоять внутри HTML-документа и создавать только меняющуюся часть. Сначала попробуем заранее известный текст — так легче увидеть границу двух языков.

page.php: полная страница с одним PHP-участкомСамостоятельный пример
<!doctype html>
<html lang="ru">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Мастерская</title>
</head>
<body>
    <h1>Мастерская</h1>
    <p><?php echo 'Приём заказов до 19:00'; ?></p>
</body>
</html>
Ожидаемый результат
<!doctype html>
<html lang="ru">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Мастерская</title>
</head>
<body>
    <h1>Мастерская</h1>
    <p>Приём заказов до 19:00</p>
</body>
</html>

Сохраните как page.php рядом с hello.php и откройте /page.php. Ожидаемый результат в раскрывающемся блоке — исходный HTML ответа, а не рисунок страницы. При CLI-запуске вы также увидите именно этот текст. В браузере он станет заголовком и абзацем.

<!doctype html> выбирает современный HTML; lang="ru" сообщает язык; charset — кодировку; viewport задаёт удобную основу масштаба на телефоне; title — название вкладки. Между <?php и ?> выполняется PHP, остальной текст передаётся в вывод. Само имя .php — соглашение настройки обработчика, а не команда для браузера.

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

Почему посетитель не видит echo и где проверять результат

Одна строка page.php и её судьба
  1. На диске: <p><?php echo 'Приём заказов до 19:00'; ?></p>
  2. PHP добавляет в вывод текст внутри кавычек
  3. В ответе: <p>Приём заказов до 19:00</p>
  4. Браузер рисует абзац «Приём заказов до 19:00»

Откройте просмотр исходного кода страницы в браузере: там находится полученный HTML. Исходный PHP-файл остаётся у сервера при корректной настройке. Панель Elements показывает уже разобранный браузером документ; браузер и JavaScript могли изменить его. Поэтому для сравнения с ожидаемым HTML смотрите также исходный ответ в Network.

Скрытость исходника не делает приложение безопасным сама по себе. Посетитель управляет отправляемыми значениями и может обращаться к обработчику без вашей формы. Проверки нужно выполнять на сервере; к этому вернёмся в следующем учебном опыте.

Почему перенос строки в PHP и перенос на странице выглядят по-разному

Две строки текстового выводаСамостоятельный пример
<?php
echo "Первый заказ\n";
echo "Второй заказ\n";
Ожидаемый результат
Первый заказ
Второй заказ

В терминале две записи идут на отдельных строках. Если такой текст отдать браузеру как обычный HTML, стандартное отображение схлопнет переводы строк вместе с другими пробельными символами. Значение вывода не потеряно: это правило отображения HTML.

Два абзаца HTML остаются двумя абзацамиСамостоятельный пример
<p><?php echo 'Первый заказ'; ?></p>
<p><?php echo 'Второй заказ'; ?></p>
Ожидаемый результат
<p>Первый заказ</p>
<p>Второй заказ</p>

Теги p задают два смысловых абзаца. Для отдельного перевода строки внутри абзаца существует br. Не добавляйте br в исходные данные, которые потом должны попасть в CSV, JSON или текстовый журнал: оформление зависит от места вывода.

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

Если первый пример не работает: отделяем синтаксис от окружения

Ошибка синтаксиса означает, что PHP не смог прочитать запись программы: например, не закрыта кавычка. Ошибка окружения означает, что нужный файл или PHP ещё не был запущен. Проверяйте эти причины отдельно. Для локального файла есть проверка синтаксиса без выполнения его инструкций:

Проверить запись hello.phpФрагмент или команда
php -l hello.php

Маленькая l означает lint. Сообщение No syntax errors detected подтверждает только читаемость записи: оно не проверяет правильность расчёта, работу базы или все подключаемые файлы. При ошибке смотрите указанную строку и строку непосредственно перед ней.

Страница без текста не всегда сломана: программа может ничего не выводить. Если ожидался текст, смотрите журнал локального сервера. При отключённом показе ошибок PHP может записать причину в журнал, а браузер увидит пустой ответ. Не вставляйте сложный обработчик исключений в самый первый echo; сначала восстановите минимальный работающий файл.

info.php: посмотреть настройки только в своём учебном окруженииПример для указанного окружения
<?php
phpinfo();

phpinfo — встроенная функция. Круглые скобки означают её вызов; пустые скобки здесь означают вызов без переданных значений. Она сама выводит страницу со сведениями об окружении. Откройте info.php только на локальном сервере и уберите после проверки: сведения о путях и настройках не предназначены для посетителей. Это контекстный пример, его вывод зависит от вашей установки.

Веб-окружение и терминал способны использовать разные настройки. Поэтому результат php -v не доказывает версию PHP у опубликованного сайта. Подробности диагностики будут в главе об ошибках.

Первый файл: из текста программы получается ответ

Начнём с результата: программа должна написать, какой магазин открыт. Для этого пока не нужны ни сайт, ни база, ни классы. Сохраните пример в example.php в UTF-8 и выполните в терминале php example.php из его каталога. Если команда php не найдена, перейдите к настройке окружения ниже и затем вернитесь сюда. Каждый пример запускается отдельным файлом; несколько полных программ не склеивают вместе.

Четыре действия первой программы
  1. Запустить example.php через PHP
  2. Положить текст «Чайная» в имя $shop
  3. Передать текст и значение в echo
  4. Увидеть одну строку в терминале
ЗаписьКак её прочитать
<?phpЗдесь начинается PHP-код. В чистом PHP-файле закрывающий тег обычно опускают.
$shopИмя переменной: доллар — часть записи обращения к переменной, shop — выбранное нами имя.
=Вычислить значение справа и сохранить под именем слева. Это присваивание, не вопрос о равенстве.
'Чайная'Текст ограничен кавычками. Кавычки не входят в само значение.
;Конец инструкции. Перенос строки сам по себе её не заканчивает.
echoОтправить текст в вывод. Запятые позволяют передать несколько частей.
"\n"Перевод строки в терминале. В HTML обычный перенос в исходном тексте не заменяет тег <br>.
Имя магазина и одна строка ответаСамостоятельный пример
<?php
$shop = 'Чайная';
echo 'Открыт магазин: ', $shop, "\n";
Ожидаемый результат
Открыт магазин: Чайная

Сначала выполняется присваивание, затем echo читает уже сохранённое значение. Если поменять строку справа от =, изменится ответ без изменения команды вывода.

Попробуйте сами. Переименуйте магазин в «Книжная». Где меняется программа и что выведется?

Разбор решения

Меняется только текст в кавычках при присваивании. Ответ: «Открыт магазин: Книжная». Доллар нужен у имени переменной, но не у буквального текста.

Первое изменение: сообщение зависит от данных

Теперь у нас есть переменная — имя для значения. Допустим, мастерская временно работает по другому расписанию. Храним часы под понятным именем и выводим их в нужном месте. Одинарные кавычки обозначают готовый текст, доллар — обращение к переменной. Запятые у echo передают несколько частей вывода по порядку.

Поменять часы работы в одном местеСамостоятельный пример
<?php
$closingTime = '18:30';
echo 'Приём заказов до ', $closingTime, "\n";
Ожидаемый результат
Приём заказов до 18:30

Сначала значение 18:30 присваивается имени closingTime. Затем echo читает его. Эта маленькая программа ещё не хранит настройки между запросами: число часов записано в самом файле. База и файлы будут следующим отдельным шагом.

Обращение к данным с квадратными скобками — следующий уровень. $_SERVER представляет набор сведений, подготовленный PHP для текущего запуска. Набор называется массивом; запись $_SERVER['HTTP_USER_AGENT'] выбирает значение под ключом HTTP_USER_AGENT. Этот ключ связан с заголовком User-Agent, который может отправить клиент.

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

Как использовать готовую функцию и выполнить нужную ветку

Задача: показать подсказку, если в диагностической строке клиента есть слово Firefox. str_contains — готовая функция поиска фрагмента. В скобках передаются два значения: где искать и что искать. Функция возвращает true, когда фрагмент найден, и false, когда не найден. Это логические значения «да» и «нет», а не строки с такими словами.

От строки до выбранного сообщения
  1. $agent = 'Учебный Firefox': сохраняем строку
  2. str_contains($agent, 'Firefox'): передаём строку и искомый фрагмент
  3. Функция возвращает true; if выбирает первую ветку
  4. echo выводит подсказку; после закрытия ветки программа продолжается
Небольшая проверка с двумя возможными результатамиСамостоятельный пример
<?php
$agent = 'Учебный Firefox';
if (str_contains($agent, 'Firefox')) {
    echo "В строке есть Firefox\n";
} else {
    echo "В строке нет Firefox\n";
}
echo "Проверка закончена\n";
Ожидаемый результат
В строке есть Firefox
Проверка закончена

if проверяет результат внутри своих круглых скобок. Фигурные скобки объединяют инструкции выбранной ветки. else обозначает случай «иначе». Строка после обеих веток выполнится при любом результате. Замените строку на Учебный клиент: изменится первая строка ответа, но проверка всё равно закончится.

Найденная подстрока — лишь свойство текста. Она не доказывает настоящий браузер или личность человека: User-Agent можно изменить. Не разрешайте оплату или вход по такому признаку. Для поддерживаемых возможностей браузера предпочтительна проверка самой возможности на стороне клиента. Здесь мы учимся читать данные, вызывать функцию и выбирать ветку.

Дальше можно подробно разобрать параметры, аргументы и возврат, условия и циклы и поиск в строке.

Как взять строку из настоящего запроса и безопасно показать её

Сохраним следующий файл как agent.php в папке локального сервера. Ключ может отсутствовать: например, запрос отправляет другая программа без User-Agent. Запись ?? '' выбирает пустую строку, если значения нет или оно равно null. Запрос клиента — внешние данные, поэтому при вставке в HTML его текст отдельно преобразуем для этого контекста.

Новая записьЗачем она здесь
header(...)Задаёт тип ответа HTML и UTF-8 до отправки тела; не печатает заголовок абзацем.
htmlspecialchars(...)Возвращает безопасное для HTML-текста представление строки; не очищает её для всех возможных задач.
ENT_QUOTESПросит преобразовать и одинарные, и двойные кавычки.
ENT_SUBSTITUTEПросит заменять некорректные последовательности кодировки, а не терять весь вывод.
| между этими именамиОбъединяет два флага настройки; это не символ-разделитель выводимого текста.
agent.php: диагностическая строка из HTTPПример для указанного окружения
<?php
$agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
header('Content-Type: text/html; charset=utf-8');
echo '<p>Строка клиента: ';
echo htmlspecialchars($agent, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
echo '</p>';

Откройте /agent.php через локальный сервер. Вывод зависит от присланного заголовка. htmlspecialchars возвращает текст с HTML-экранированием; например, знак < становится последовательностью &lt; и отображается символом, а не началом тега. Само echo этого преобразования не делает. При корректном штатном HTTP-окружении этот заголовок представлен строкой; отсутствие ключа обработано.

Отдельно увидеть, что делает HTML-экранированиеСамостоятельный пример
<?php
$message = '<b>Заказ</b> & "Клиент"';
echo htmlspecialchars($message, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), "\n";
Ожидаемый результат
&lt;b&gt;Заказ&lt;/b&gt; &amp; &quot;Клиент&quot;

В терминале видно преобразованную строку. Внутри HTML-абзаца браузер покажет буквальный текст <b>Заказ</b> & "Клиент", без жирного выделения. Это защита именно данного места вывода; для SQL, URL и JavaScript действуют свои правила.

Не выводите весь $_SERVER посетителям. Набор содержит и служебные сведения. Остальные источники входа разобраны по отдельным суперглобальным массивам.

Выбирать целый HTML-фрагмент, сохраняя понятную разметку

Когда сообщение состоит из заголовка и абзаца, не обязательно превращать каждую строку HTML в длинный echo. Можно выйти из PHP внутри ветки. PHP продолжает следить за условием: в ответ попадёт только HTML выбранной ветки. Ниже значение true задаём сами; позже его можно получить из проверенного расписания.

notice.php: показать один из двух блоковСамостоятельный пример
<?php
$isOpen = true;
if ($isOpen) {
?>
<h2>Принимаем заказы</h2>
<p>Можно оставить заявку.</p>
<?php
} else {
?>
<h2>Мастерская закрыта</h2>
<p>Откроемся завтра.</p>
<?php
}
Ожидаемый результат
<h2>Принимаем заказы</h2>
<p>Можно оставить заявку.</p>

Фрагмент можно поместить в body полной страницы. Он остаётся исполняемым PHP-файлом и даёт указанный HTML также в CLI. Поменяйте true на false: первая пара тегов не попадёт в ответ, а вторая попадёт. Закрытие PHP-тега не означает завершения условия.

Альтернативная запись if (...): ... endif; полезна для больших шаблонов; она изучается вместе с управляющими конструкциями. PHP не поддерживает смешение записи с фигурными скобками и альтернативной записи внутри одной управляющей конструкции: выберите для неё один стиль.

Форма: как поле в браузере становится значением в PHP

Следующая полезная задача — дать посетителю ввести имя и увидеть предпросмотр подписи обращения. Это ещё не отправка заявки: пример ничего не сохраняет и никуда не пересылает. Нам нужен полный видимый путь от поля до ответа. HTML формы и PHP-обработчик лежат в одной папке; в скачиваемом примере это form.html и example.php.

Путь конкретного имени «Анна»
  1. Посетитель вводит Анна в поле с name="customer_name"
  2. Кнопка отправляет POST на адрес example.php
  3. PHP разбирает тело обычной формы: $_POST['customer_name'] получает строку Анна
  4. Обработчик проверяет форму значения, убирает крайние пробелы и проверяет длину
  5. HTML-экранирование → вывод имени в абзаце ответа
form.html: полная форма для следующего обработчикаФрагмент или команда
<!doctype html>
<html lang="ru">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Предпросмотр подписи</title>
</head>
<body>
    <h1>Как подписать ваше обращение</h1>
    <form action="example.php" method="post">
        <label for="customer-name">Ваше имя</label>
        <input id="customer-name" name="customer_name"
               type="text" maxlength="80" required>
        <button type="submit">Посмотреть подпись</button>
    </form>
</body>
</html>

Откройте /form.html через тот же локальный сервер. id связывает поле с подписью label; name определяет ключ отправляемых данных. Одного id недостаточно. required и maxlength помогают пользователю в браузере, но серверу всё равно нужно проверять полученное значение.

АтрибутСвязь с обработчиком
action="example.php"Адрес, куда браузер отправит запрос; это не имя вызываемой PHP-функции.
method="post"Поля отправляются в теле HTTP-запроса. Для этой обычной формы PHP создаст $_POST.
name="customer_name"Имя ключа в $_POST. Текст внутри поля становится значением.
id="customer-name"Имя элемента в документе; label for ссылается на него. Оно не заменяет name.

Первый обработчик: проверить вход прежде, чем выводить

Теперь каждую часть проверки можно связать с задачей. Сначала допускаем POST. Затем читаем нужное поле с запасным значением. Посетитель может отправить массив вместо строки, поэтому проверяем is_string до обработки текста. trim убирает крайние пробельные символы, strlen считает байты. exit завершает текущую программу после ошибки; иначе выполнение пошло бы дальше.

ВыражениеКак его прочитать
!== 'POST'Если значение не равно строке POST с учётом типа, это неподходящий запрос.
!is_string($rawName)Вызвать проверку «это строка?» и отрицать её результат.
$name === ''Проверить строгое равенство пустой строке после trim.
||Логическое «или»: отклонить и пустое, и слишком длинное имя.
http_response_code(400)Установить HTTP-статус ошибки; это не вывод числа 400 на страницу.
example.php: обработчик формы предпросмотраПример для указанного окружения
<?php
if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
    http_response_code(405);
    header('Allow: POST');
    echo 'Откройте форму form.html и отправьте её.';
    exit;
}
$rawName = $_POST['customer_name'] ?? '';
if (!is_string($rawName)) {
    http_response_code(400);
    echo 'Передайте одно имя текстом.';
    exit;
}
$name = trim($rawName);
if ($name === '' || strlen($name) > 320) {
    http_response_code(400);
    echo 'Имя нужно заполнить; максимум 320 байт UTF-8.';
    exit;
}
header('Content-Type: text/html; charset=utf-8');
echo '<h1>Предпросмотр подписи</h1><p>';
echo htmlspecialchars($name, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
echo '</p><p>Данные не сохранены и не отправлены оператору.</p>';

В ZIP уже включён form.html из предыдущего блока. Положите оба файла в учебную папку и откройте форму через HTTP. Для имени « Анна » ответ содержит абзац «Анна». Отправка имени <b>Анна</b> покажет эти символы как текст. Обращение GET возвращает 405, пустое или слишком длинное имя и массив вместо строки — 400. Это HTTP-пример; отдельное выполнение в терминале не моделирует заполненную форму.

Лимит 320 здесь задан в байтах, а HTML maxlength — ограничение браузерного поля, не эквивалент PHP strlen. Для пользовательского лимита в символах изучите многобайтовые строки. Обработчик не утверждает, что это настоящее имя человека: он проверяет только согласованную форму входа.

POST не шифрует данные и не делает запрос доверенным; для передачи по сети нужен HTTPS. Здесь нет изменения учётной записи, заказа или данных сессии, поэтому пример ограничен безопасным предпросмотром. Как только действие что-либо меняет, добавляются CSRF-проверка, полномочия и правила операции. Они подробно разобраны вместе с полной формой в главе обработки форм.

Чем отличается GET и почему данные не появляются сами собой

Для поиска по каталогу обычно удобно поместить условия в URL: результат можно сохранить в закладки и передать ссылкой. При method="get" поле той же формы попадёт в строку запроса, и читать его нужно из $_GET. Обычная POST-форма отправляет поля в теле; её значения читаются из $_POST. Если поменять только method, но оставить чтение из другого массива, обработчик не получит ожидаемые данные.

ЗапросГде читать данные в PHP
GET /search.php?q=чай$_GET['q'] содержит строку «чай».
POST /example.php с customer_name=Анна в теле формы$_POST['customer_name'] содержит строку «Анна».
POST /example.php?source=site с тем же телом формыsource находится в $_GET, customer_name — в $_POST. GET-массив существует и у POST-запроса, если есть query string.
POST с JSON вместо обычной формыНе появляется автоматически тот же $_POST; JSON-тело читается и разбирается отдельно.

Поля не становятся свободными переменными $customer_name автоматически. Мы сами выбираем ключ, проверяем его значение и присваиваем понятному локальному имени. $_REQUEST смешивает источники в зависимости от настройки и мешает увидеть договор обработчика; для учебного и рабочего кода здесь явно выбирается нужный источник.

Неотмеченный checkbox, выключенное disabled-поле или поле без name могут отсутствовать в отправленных данных. Файлы имеют свой путь через $_FILES. Эти варианты, вложенные имена и JSON-тело разобраны в суперглобальных массивах, формах и загрузке файлов.

Куда двигаться после первого ответа

После этих опытов у вас есть три наблюдаемых результата: текст из PHP-файла, HTML-страница с вычисляемой частью и значение формы, прошедшее проверку. Не требуется сразу запомнить весь справочник. Продолжайте последовательно по механике, возвращаясь к тому же сайту мастерской и добавляя по одной возможности.

Следующий результатЧто изучить сначалаЗатем применить
Хранить название и цену товараПеременные; типыМассив каталога
Повторить действие для всех позицийУсловия и циклыВложенные данные интеграции
Переиспользовать расчётВход, тело и returnКогда полезен объект
Сохранить заявкуПолная проверка формыБаза и параметры SQL
Загрузить фото работыЗагрузка файловХранение файлов
Узнавать посетителя между запросамиЗапрос и ответСессия и вход

Попробуйте сами. В форме отправили имя « <b>Анна</b> ». Что должен показать ответ и почему?

Разбор решения

После trim исчезнут крайние пробелы. htmlspecialchars преобразует специальные символы для HTML, поэтому посетитель увидит буквальный текст <b>Анна</b>, а не жирное имя. Это не удаление тегов из данных, а выбор безопасного представления в конкретном месте.

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

Когда программа выросла: подключить свой файл

Один и тот же заголовок можно хранить отдельно. require подключает и выполняет PHP-файл в текущем процессе; это не запуск второй программы. Суффикс _once означает «не подключать тот же файл повторно». В ZIP примера лежат example.php и heading.php; держите их рядом.

Общий заголовок подключается только один разСамостоятельный пример
<?php
require_once __DIR__ . '/heading.php';
require_once __DIR__ . '/heading.php';
echo "Каталог товаров\n";
Ожидаемый результат
Чайная
Каталог товаров

__DIR__ обозначает каталог текущего PHP-файла. Точка склеивает его с именем файла. heading.php выполняется при первом require_once; второй не повторяет вывод.

include при невозможности загрузки файла выдаёт предупреждение и позволяет продолжить; require в PHP 8 бросает Error и без обработчика останавливает выполнение. Обязательный файл приложения обычно подключают через require. Имена здесь зафиксированы разработчиком: путь из запроса пользователя нельзя напрямую подставлять в include/require. Данные читают как данные, а не как исполняемый PHP.

Строка declare(strict_types=1);, которую вы увидите дальше, задаёт строгий режим скалярных объявлений типов для этого файла; она должна быть первой инструкцией после открывающего тега. Она не объявляет тип каждой переменной, не проверяет все поля массива и не заменяет проверку формы. Разберём её смысл на типах аргументов функции.

Дальше: переменная и первое присваивание → типы значений → действия со значениями → выбор и повторение. Ниже — устройство CLI/HTTP и диагностика окружения.

Теги PHP, точка с запятой и комментарии: читаем исходный файл

В смешанном файле тег <?php начинает участок PHP, а ?> возвращает обработку обычного текста. Внутри PHP имена переменных начинаются с $, строки берут в кавычки, большинство инструкций завершается ;. Фигурные скобки объединяют инструкции в блок. Перенос строки помогает человеку читать код, но обычно не завершает инструкцию сам по себе.

Разметка и PHP находятся в одном файлеСамостоятельный пример
<?php
// Эта строка выводит название учебного магазина.
echo "Мастерская\n";
/* Несколько строк комментария допустимы,
   но такие комментарии нельзя вкладывать друг в друга. */
?>
<p><?= 'Работаем с 10 до 19' ?></p>
Ожидаемый результат
Мастерская
<p>Работаем с 10 до 19</p>

Комментарий // продолжается до конца строки или окончания PHP-участка; # также начинает однострочный комментарий, кроме специального синтаксиса атрибута #[...]. Комментарий /* ... */ занимает несколько строк. Документирующий /** ... */ сам не запускает проверку типов.

Тег <?= эквивалентен выводу выражения и доступен независимо от настройки коротких тегов. Здесь выводится заранее заданный автором текст. Значения от посетителей требуют отдельного безопасного вывода, который будем изучать в главах о формах. Короткий открывающий <? зависит от настройки, поэтому в переносимом коде используйте <?php. В чистом PHP-файле закрывающий тег обычно опускают: случайный пробел после него стал бы выводом и мог помешать отправке заголовков. Комментарии обосновывайте смыслом решения, а не пересказом каждой строки.

Где живет программа

PHP выполняется на сервере или в командной строке. Браузер получает результат: HTML, JSON, файл или ответ об ошибке. Когда покупатель открывает корзину, веб-сервер передает запрос PHP, программа читает входные данные, проверяет права, рассчитывает сумму и формирует ответ. Исходный PHP-код при правильной настройке сервера в браузер не отправляется. JavaScript в браузере и PHP на сервере не делят обычные переменные; они обмениваются HTTP-запросами.

Один запрос к каталогу
  1. Браузер отправляет GET /catalog
  2. Веб-сервер передает запрос PHP
  3. PHP получает данные и строит ответ
  4. Браузер читает HTML или JSON

В обычном PHP-FPM приложении состояние локальных переменных относится к текущему запросу. Следующий запрос не продолжает выполнение предыдущей функции. Для корзины между запросами нужны сессия, база или другое хранилище. В CLI-воркере и некоторых серверных средах процесс может жить долго: там забытые массивы, статические счетчики и открытые ресурсы сохраняются дольше, чем ожидает автор обычного сайта. Это различие пригодится в разделах об области видимости и очередях.

Проверяем именно то окружение, в котором работает задача

Сначала установите поддерживаемую ветку PHP с официального сайта или из доверенного репозитория вашей системы. Не подменяйте системную версию вслепую: сайт и терминал могут использовать разные бинарные файлы и разные php.ini. Команда php -v сообщает версию CLI, php --ini — конфигурацию, php -m — расширения. Для веб-сервера проверяйте его конфигурацию отдельно. Полный phpinfo() удобен локально, но публично раскрывает пути и параметры окружения.

Три проверки перед запускомФрагмент или команда
php -v
php --ini
php -m

Запускайте команды в терминале. Для примеров с Unicode нужен mbstring, для SQLite — pdo_sqlite. Отсутствующее расширение исправляют в окружении; не прячут ошибку оператором @.

Первая полезная программа: сумма корзиныСамостоятельный пример
<?php
declare(strict_types=1);

$unitPriceKopecks = 129900;
$quantity = 2;
$totalKopecks = $unitPriceKopecks * $quantity;
echo "Итого: {$totalKopecks} коп.\n";
Ожидаемый результат
Итого: 259800 коп.

Сохраните пример как cart.php в UTF-8 и выполните php cart.php. Здесь нет сайта, базы и сети: можно отдельно проверить расчет. Деньги представлены целыми копейками, поэтому двоичное представление float не влияет на умножение.

Тот же язык в браузере

Для учебного сайта заведите каталог public и запускайте встроенный сервер только на локальном интерфейсе: php -S 127.0.0.1:8000 -t public. Он предназначен для разработки. Не публикуйте его в интернет и не храните в public секреты, резервные копии или исходные CSV клиентов. В реальном развертывании точку входа и обработку .php настраивают в Nginx/Apache и PHP-FPM либо в другой выбранной серверной среде.

JSON-ответ проверки состоянияПример для указанного окружения
<?php
declare(strict_types=1);

header('Content-Type: application/json; charset=utf-8');
echo json_encode(['status' => 'ok'], JSON_THROW_ON_ERROR);

Сохраните как public/health.php и откройте локальный URL /health.php. Это HTTP-пример: заголовки проверяются в браузере или curl, а не по выводу CLI. Не добавляйте сюда ключи доступа и детали базы.

В PHP-файле, содержащем только код, закрывающий тег обычно опускают: случайные пробелы после него могут отправить тело раньше заголовков. Ошибки в разработке показывают разработчику, в рабочем окружении записывают в журнал. Клиенту возвращают понятное сообщение и идентификатор запроса; пароль, стек и SQL-запрос не должны попадать в страницу ошибки.

Как учиться на примерах и искать неисправность

Читайте подпись режима каждого примера. «Самостоятельный» имеет фиксированные данные и ожидаемый вывод. Контекстный пример требует HTTP, базы или заданной зависимости. Команда терминала не вставляется внутрь PHP-файла. При ошибке сначала проверьте имя файла и бинарный PHP, затем строку сообщения, тип входного значения и установленные расширения. Меняйте одно условие за раз: пустая корзина, нулевой остаток, неверный JSON. Так вы исследуете контракт, а не просто убеждаетесь, что счастливый случай работает.

Попробуйте сами. Измените корзину так, чтобы количество было 0. Затем передайте строку "две". Какая проверка должна стоять перед расчетом?

Разбор решения

Ноль может быть разрешен для пустой корзины, но не для позиции заказа. Строку из формы сначала проверяют как допустимое целое в диапазоне, затем приводят к int. Произвольное (int) "две" превратит ошибку в 0 и скроет причину. Продолжите главы о типах и безопасных формах.

Источники и обсуждения

Код и руководство с собой

Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.

Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.