Первая программа на PHP
Play ITЗагрузка интерактивного демо…
Первая программа на PHP
PHP - динамические страницы на сервере
PHP изначально создавался для динамических веб-страниц: сервер читает .php, выполняет код, отдаёт HTML. Сегодня на нём работают WordPress, Laravel, Symfony — но первый шаг всё равно "файл в htdocs + echo".
Мы настроим XAMPP (Apache + PHP в одном установщике) и выведем Hello World — без фреймворка. Дальше: Laravel или Symfony.
Что получится
Рабочий Apache, папка myfirstphp, файл index.php, страница в браузере http://localhost/myfirstphp/.
Установка
Установка программ обычно выглядит так (XAMPP — один мастер для Apache, PHP и MySQL):
Play ITЗагрузка интерактивного демо…
А теперь давайте немного попрактикуемся и посмотрим, как выглядит работа с PHP. Пройдитесь и выполните все действия по алгоритму, но на каждом шаге старайтесь исследовать то, что на экране, чтобы понимать.
Можно использовать:
- XAMPP (рекомендуется) – пакет, содержащий Apache, MySQL, PHP и прочие полезные инструменты. Это, кстати, отличный вариант для изучения множества инструментов в комплекте.
- PHP как отдельный пакет через официальный сайт php.net.
XAMPP
Установка и запуск сервера
Рассмотрим XAMPP.
После завершения установки можно запустить XAMPP Control Panel, который предоставит интерфейс управления серверами.

Панель управления даёт нам перечень инструментов, и около каждого из перечисленных есть Start (запуск), Admin, Config и Logs. Общие настройки в меню справа.

Нас интересует Apache – нажмём Start рядом с Apache, чтобы запустить веб-сервер, который будет выполнять PHP-скрипты.
После успешного запуска будет указано, какие порты использует сервер, а в нижней части окна будет логирование информации.
Структура и файлы
Все PHP-файлы, как правило, размещаются в каталоге htdocs, который находится внутри папки, куда мы установили XAMPP – по умолчанию, C:\xampp\htdocs\.
В этой папке мы создадим новую папку – myfirstphp, будет корнем нашего проекта.
Пример структуры каталога XAMPP:
xampp\htdocs\ - основная директория для веб-проектов
xampp\htdocs\index.php - главная страница по умолчанию
К папке можно перейти через панель управления XAMPP - кнопка Explorer - папка htdocs.
Создадим файл index.php внутри папки myfirstphp, откроем его в любом текстовом редакторе и добавим туда код:
<?php
echo "Hello World!";
?>
Разбор:
<?phpоткрывает PHP-режим внутри файла, и всё до?>интерпретируется как исполняемый код на сервере.echoотправляет строку в HTTP-ответ, поэтому пользователь видит текст прямо в браузере.- Строковый литерал
"Hello World!"берётся как есть и выводится без дополнительных преобразований. ;завершает инструкциюecho; без неё интерпретатор не сможет корректно разобрать следующую команду.?>закрывает PHP-блок; в файлах с чистым PHP его часто можно опускать, чтобы избежать случайного вывода пробелов.
В PHP всё начинается с тега <?php. Команда echo выводит текст на экран.
Запуск программы
Чтобы запустить скрипт, убедимся, что Apache запущен, откроем браузер и перейдём по адресу:
http://localhost/myfirstphp
Мы должны увидеть Hello World в браузере.
Вот и всё.
Командная строка
Альтернативный способ:
- CLI (командная строка);
- но сохраним тот же код в другом файле;
hello.php;- перейдём к нему в командной строке.
Пример:
cd C:\xampp\htdocs\myfirstphp
Разбор:
cd(change directory) меняет текущую рабочую папку терминала.- Путь
C:\xampp\htdocs\myfirstphpуказывает директорию, где лежит создаваемый PHP-проект. - После перехода все команды запуска (
php hello.php) будут выполняться относительно этой папки. - Такой шаг нужен, чтобы CLI-интерпретатор точно нашёл нужный файл скрипта.
Затем выполним:
php hello.php
Разбор:
phpзапускает интерпретатор PHP в консольном режиме (CLI).hello.phpпередаётся как входной файл, и весь код в нём выполняется сверху вниз.- Вывод из
echoпопадает не в браузер, а в stdout консоли. - Если команда не найдена, проблема обычно в том, что путь к
php.exeне добавлен вPATH.
Результат будет в консоли:

Если через командную строку не удалось запустить, проверьте, что php в PATH. В Windows: Параметры системы → Дополнительно → Переменные среды → Path — добавьте каталог PHP (например, C:\xampp\php).
Если мы установили XAMPP, то PHP будет по пути: C:\xampp\php
Если же PHP установлен отдельно – то нужно будет указать путь установки.
Можем попробовать усложнить скрипт.
Попробуйте изменить код нашего index.php на следующий:
<?php
$name = "Имя";
echo "Привет, $name!<br>";
echo "Сегодня: " . date("d.m.Y");
?>
Разбор:
$name = "Имя";создаёт переменную и сохраняет в ней строку.- В строке
"Привет, $name!<br>"используется интерполяция: значение$nameподставляется внутрь текста автоматически. <br>добавляет перенос строки в HTML-выводе браузера.date("d.m.Y")форматирует текущую дату какдень.месяц.год.- Оператор
.выполняет конкатенацию строк: соединяет"Сегодня: "и результатdate(...).
Тогда мы получим переменную $name, которая будет выводиться, функцию date() для вывода текущей даты и конкатенацию строк с помощью точки.
Работа с базой данных
Основные моменты
XAMPP является учебным. Лучше не разворачивать ценные сервера веб-приложений через него. В реальности лучше полноценно управлять средой через специализированные инструменты.
Важные моменты:
- Директория htdocs — это
document root Apache. - Все файлы должны иметь расширение
.phpдля обработки интерпретатором. - Доступ к файлам осуществляется через виртуальный хост
localhost. - Реальные пути к файлам недоступны напрямую — только через веб-интерфейс.
Создание базы данных
Если нажать на кнопку Shell в панели управления XAMPP, то откроется терминал. Давайте создадим базу данных.
Перейдите в директорию htdocs:
cd C:\xampp\htdocs
Разбор:
- Команда переводит терминал в корневую папку веб-проектов XAMPP.
- Это удобно, потому что дальше база
mydb.sq3создаётся рядом с PHP-скриптами. - Относительные пути в SQLite и PHP будут разрешаться относительно этой директории.
Создайте базу данных.
sqlite3 mydb.sq3
Разбор:
sqlite3запускает консольный клиент SQLite.mydb.sq3— имя файла БД; если файла нет, он будет создан автоматически.- После запуска вы переходите в интерактивный режим
sqlite>, где можно выполнять SQL-команды. - Вся база хранится в одном файле, без отдельного серверного процесса.
После выполнения команды откроется интерактивная оболочка SQLite с приглашением sqlite>.

Создайте таблицу.
Для этого просто вставьте скрипт в терминал:
CREATE TABLE items(
id INTEGER PRIMARY KEY,
name TEXT,
price REAL
);
Разбор:
CREATE TABLE itemsсоздаёт новую таблицу с именемitems.id INTEGER PRIMARY KEYзадаёт целочисленный первичный ключ для уникальной идентификации строки.name TEXTхранит название товара как текст.price REALхранит цену в формате числа с плавающей точкой.;завершает SQL-инструкцию и отправляет её на выполнение.
Таблица items содержит три поля:
- id — уникальный идентификатор (целое число, первичный ключ)
- name — название товара (текст)
- price — цена (число с плавающей точкой)
Добавьте тестовые данные:
INSERT INTO items VALUES(1001, 'Salt', 3.15);
INSERT INTO items VALUES(1002, 'Pepper', 2.75);
INSERT INTO items VALUES(1003, 'Eggs', 2.00);
INSERT INTO items VALUES(1004, 'Bacon', 7.25);
INSERT INTO items VALUES(1005, 'Milk', 1.15);
INSERT INTO items VALUES(1006, 'Strawberries', 8.73);
INSERT INTO items VALUES(1007, 'Cereal', 2.65);
Разбор:
INSERT INTO items VALUES(...)добавляет новую запись в таблицуitems.- Первое значение —
id, второе — название (name), третье — цена (price). - Каждая строка
INSERTвыполняется отдельно, поэтому при ошибке видно конкретную проблемную команду. - Строковые значения пишутся в одинарных кавычках, числовые — без кавычек.
- Такие тестовые данные нужны, чтобы проверить запросы выборки в следующих шагах.
Проверьте данные:
SELECT * FROM items WHERE price < 3.00;
Разбор:
SELECT *выбирает все столбцы таблицы.FROM itemsуказывает, из какой таблицы брать данные.WHERE price < 3.00фильтрует строки по условию цены.- Результат содержит только товары дешевле 3.00, что удобно для проверки корректности данных.
Команда вернет все товары стоимостью менее 3.00.

Завершите работу с базой
.quit
Разбор:
.quit— служебная команда консоли SQLite, а не SQL-оператор.- Команда завершает интерактивный сеанс и возвращает вас в обычный терминал.
- Все изменения, уже выполненные
INSERT/CREATE, остаются сохранёнными в файлеmydb.sq3.
Файл базы данных mydb.sq3 содержит все таблицы и данные. Рекомендуется регулярно создавать резервные копии.

Настройка расширения
Откройте файл конфигурации PHP и включите расширение для работы с базой данных.
Через панель управления XAMPP: нажмите кнопку Config напротив Apache, выберите PHP (php.ini), или откройте напрямую: C:\xampp\php\php.ini.
Найдите и раскомментируйте строку:
;extension=sqlite3
Разбор:
;вphp.iniозначает комментарий: строка не применяется.- Такая запись показывает, что расширение есть в конфигурации, но отключено.
- Чтобы включить модуль, нужно удалить ведущую
;.
Раскомментировать означает "убрать комментарий". Для этого нужно удалить точку с запятой в начале:
extension=sqlite3
Разбор:
- Здесь директива активна, и PHP попытается загрузить расширение
sqlite3при старте. - После изменения обязательно требуется перезапуск Apache/PHP-процесса.
- Проверка через
phpinfo()подтверждает, что модуль действительно подхватился.
Перезапустите Apache. В панели управления XAMPP остановите и снова запустите модуль Apache. Так работает перезапуск сервера.
Проверьте доступность расширения. Создайте файл info.php в htdocs со следующим содержимым:
<?php phpinfo(); ?>
Разбор:
phpinfo()выводит полную диагностическую страницу окружения PHP.- На странице видны версия PHP, загруженные расширения, пути к
php.iniи системные параметры. - По разделу
sqlite3можно быстро проверить, активировано ли нужное расширение. - Такой файл лучше удалять после проверки, чтобы не раскрывать технические детали окружения.
Откройте в браузере http://localhost/info.php и найдите раздел sqlite3. Если раздел присутствует — расширение активировано.
Создание скрипта
Создайте файл sqlite.php:
Код ITЗагрузка примера кода…
Разбор:
new SQLite3('mydb.sq3')открывает файл БД и создаёт объект соединения.$db->query($sql)выполняет SQL-запрос и возвращает набор результатов.while ($row = $result->fetchArray(SQLITE3_ASSOC))читает строки по одной как ассоциативный массив.$row['name']и$row['price']берут значения столбцов текущей строки.unset($db)освобождает объект соединения; на практике это эквивалентно закрытию после завершения скрипта.
Запуск скрипта
Откройте браузер и перейдите по адресу: http://localhost/sqlite.php.
Результат выполнения:
Pepper: $2.75
Eggs: $2.00
Milk: $1.15
Cereal: $2.65
Разбор:
- Это ожидаемый вывод фильтра
price < 3.00. - Каждая строка соответствует одной записи таблицы, прошедшей условие
WHERE. - Формат
name: $priceсобирается в PHP через конкатенацию строк. - Если список пуст, значит либо данные не вставлены, либо условие фильтра не совпадает.
Разбор кода
Теперь давайте разберём код.
Подключение к базе данных:
$db = new SQLite3('mydb.sq3');
Здесь создается объект SQLite3, который открывает файл базы данных mydb.sq3 в текущей директории.
Выполнение запроса:
$result = $db->query($sql);
Метод query() выполняет SQL-запрос и возвращает объект результата.
Получение данных:
$row = $result->fetchArray(SQLITE3_ASSOC)
Метод fetchArray() извлекает следующую строку результата. Параметр SQLITE3_ASSOC указывает, что данные должны возвращаться в виде ассоциативного массива, где ключами являются названия столбцов.
Цикл обработки:
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
// обработка строки
}
Цикл продолжает извлекать строки, пока не достигнет конца результата.
SQLite3
SQLite3 — это расширение PHP, предоставляющее объектно-ориентированный интерфейс для работы с базами данных SQLite версии 3. Расширение реализует класс SQLite3, экземпляры которого представляют соединение с файлом базы данных.
Это расширение, как можно понять из названия, имеет прямую привязку к СУБД SQLite, и работает исключительно с этим движком. Используется при этом объектная модель, где каждый экземпляр класса SQLite3 управляет отдельным соединением. Все данные хранятся в локальном файле.
Как мы запомнили, оно требует явной активации в конфигурации PHP (extension=sqlite3 в php.ini). В некоторых сборках XAMPP для Windows расширение отключено по умолчанию.
PDO
Для более универсального кода можно использовать расширение PDO. Оно не требует изменения php.ini.
PDO — это абстрактный слой доступа к базам данных, встроенный в ядро PHP начиная с версии 5.1. Представляет унифицированный интерфейс для взаимодействия с различными СУБД через драйверы.
У него есть единый API для разных СУБД — один и тот же код работает с MySQL, PostgreSQL, SQLite, Oracle и другими (при наличии соответствующего драйвера), а смена СУБД требует изменения только строки подключения.
<?php
try {
// Подключение через PDO
$pdo = new PDO('sqlite:mydb.sq3');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Подготовленный запрос
$stmt = $pdo->prepare("SELECT * FROM items WHERE price < :price");
$stmt->execute(['price' => 3.00]);
// Вывод результатов
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo $row['name'] . ': $' . $row['price'] . '<br/>';
}
} catch (PDOException $e) {
echo 'Ошибка подключения: ' . $e->getMessage();
}
?>
Разбор:
try { ... } catch (PDOException $e)перехватывает ошибки подключения и выполнения запросов.new PDO('sqlite:mydb.sq3')создаёт соединение через универсальный интерфейс PDO.setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)включает режим исключений для ошибок.prepare(...):execute(...)использует подготовленный запрос с параметром:price, что безопаснее ручной подстановки.fetch(PDO::FETCH_ASSOC)возвращает строку как ассоциативный массив, аналогичноSQLITE3_ASSOC.
С PDO снижается зависимость от конкретной СУБД, имеется единообразная обработка ошибок, а режим этот активирован по умолчанию.
Более сложный пример
Пример кода
А теперь попробуйте создать новый файл test.php и добавить туда следующий код:
Код ITЗагрузка примера кода…
Разбор:
- До
<!DOCTYPE html>размещена серверная логика — переменные, функции, классы, расчёты и подготовка данных. - Классы
ProductиProductCatalogпоказывают инкапсуляцию, типизацию свойств и методы доступа. array_map,array_sum,min,maxформируют статистику по каталогу без ручного цикла суммирования.foreachстроит HTML-карточки товаров на основе объектов и сразу формирует готовый фрагмент вывода.- В блоке HTML используется встраивание PHP (
<?php ... ?>) для вывода заголовков, списков, статистики и сообщений. - Такой пример демонстрирует полный цикл: подготовка данных на сервере -> генерация HTML -> отображение в браузере.
Структура документа
Код разделён на две логические части:
- Бизнес-логика (до
<!DOCTYPE html>) — объявление переменных, функций, классов и подготовка данных - Представление (HTML + встроенный PHP) — вывод данных в пользовательский интерфейс
Такой подход демонстрирует разделение ответственности: вычисления выполняются до формирования разметки, что улучшает читаемость и производительность.
Переменные и типизация
$siteTitle = "Демонстрация возможностей PHP"; // string
$version = "8.2"; // string
$currentYear = date("Y"); // string (результат функции)
$features = [ ... ]; // array
Особенности:
- PHP использует динамическую типизацию, но поддерживает строгую типизацию в сигнатурах методов
- Переменные начинаются со знака
$ - Имена переменных чувствительны к регистру (
$price≠$Price) - Тип выводится автоматически при присваивании
Массивы
$features = [
"Переменные и типы данных",
"Операторы и выражения",
// ...
];
Используется современный синтаксис массивов (начиная с PHP 5.4). Массивы в PHP:
- Реализованы как хэш-таблицы
- Поддерживают как числовые, так и строковые ключи
- Динамически расширяются при добавлении элементов
Операторы
$calculationResult = (10 + 5) * 2; // Арифметические: +, -, *, /, %
$comparison = 15 > 10; // Сравнения: >, <, >=, <=, ==, ===
$logical = true && false; // Логические: &&, ||, !, and, or
Особенности:
- Приоритет операторов соответствует математическим правилам (скобки изменяют порядок)
==сравнивает значения с приведением типов,===— строгое сравнение (значение+тип)- Логические операторы возвращают булевы значения
true/false
Условные выражения
$statusMessage = $catalog->getProductCount() > 0
? "Каталог содержит {$catalog->getProductCount()} товаров"
: "Каталог пуст";
Используется тернарный оператор условие ? значение_если_истина : значение_если_ложь. Преимущества:
- Компактная запись простых условий
- Возвращает значение, которое можно присвоить переменной
- Поддерживает вложенность (хотя это снижает читаемость)
Циклы
foreach ($catalog->getProducts() as $product) {
$productsHtml .= " ... ";
}
foreach — основной цикл для перебора массивов и итерируемых объектов:
- Автоматически извлекает ключ/значение на каждой итерации
- Не требует ручного управления счётчиком
- Работает с любыми итерируемыми структурами данных
В шаблоне также используется альтернативный синтаксис цикла для встраивания в HTML:
<?php foreach ($features as $feature): ?>
<div>...</div>
<?php endforeach; ?>
Функции
function calculateDiscount($price, $discount = 0.1) {
return $price * (1 - $discount);
}
Характеристики:
- Параметры по умолчанию (
$discount = 0.1) позволяют вызывать функцию с разным количеством аргументов - Область видимости переменных ограничена телом функции
- Возврат значения через
return - Функции могут вызываться до их объявления (из-за особенностей парсинга PHP)
Объектно-ориентированное программирование
Классы и свойства
class Product {
private string $name; // Строгая типизация свойств (PHP 7.4+)
private float $price;
private int $stock;
Особенности:
- Модификаторы доступа —
private,protected,public - Строгая типизация свойств доступна с PHP 7.4
- Инкапсуляция: прямой доступ к приватным свойствам запрещён
Конструктор
public function __construct(string $name, float $price, int $stock = 0) {
$this->name = $name;
$this->price = $price;
$this->stock = $stock;
}
- Метод
__construct()вызывается автоматически при создании объекта черезnew - Параметры с типизацией обеспечивают валидацию входных данных
- Параметр
$stockимеет значение по умолчанию
Методы с типизацией возврата
public function getName(): string {
return $this->name;
}
- Синтаксис
: типпосле имени метода указывает ожидаемый тип возвращаемого значения - Типизация повышает надёжность кода и упрощает статический анализ
Композиция объектов
class ProductCatalog {
private array $products = [];
public function addProduct(Product $product): void {
$this->products[] = $product;
}
}
- Класс
ProductCatalogсодержит коллекцию объектовProduct - Типизация параметра
$productгарантирует, что метод принимает только экземплярыProduct - Метод
getProducts()возвращает массив объектов для дальнейшей обработки
Работа с массивами и функциональное программирование
$prices = array_map(fn($product) => $product->getPrice(), $catalog->getProducts());
$averagePrice = array_sum($prices) / count($prices);
Используются:
array_map()— применяет функцию к каждому элементу массива- Стрелочная функция
fn()— краткая запись анонимной функции (PHP 7.4+) array_sum()— суммирует элементы числового массиваcount()— возвращает количество элементов
Встраивание PHP в HTML
<title><?php echo $siteTitle; ?> - PHP <?php echo $version; ?></title>
Механизмы вывода:
<?php ... ?>— стандартные теги для выполнения PHP-кода<?php echo $var; ?>— вывод значения переменной в поток вывода- Альтернативный синтаксис
<?= $var ?>эквивалентен<?php echo $var; ?>
Важно: весь код между открывающим и закрывающим тегами выполняется на сервере до отправки ответа клиенту.
Работа со строками
$productsHtml .= "<div class='product-card'>Цена: {$product->getPrice()}</div>";
Особенности:
- Конкатенация через оператор
., присваивание с конкатенацией —.= - Двойные кавычки позволяют интерполировать переменные:
"{$var}" - Одинарные кавычки интерпретируются дословно, без интерполяции
- Для экранирования кавычек внутри строки используется обратный слеш
\
Современные возможности языка
Код демонстрирует возможности PHP 7.4–8.2:
- Строгая типизация свойств классов
- Стрелочные функции (
fn()) - Типизация параметров и возвращаемых значений
- Объявление типов в свойствах без инициализации в конструкторе
- Использование скалярных типов (
string,int,float,bool)
Безопасность вывода
В демонстрационном коде используется прямой вывод переменных через echo. В production-коде необходимо применять экранирование для защиты от XSS:
<?php echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8'); ?>
Для демонстрации синтаксиса экранирование опущено, так как все данные контролируются разработчиком.
Частые ошибки
| Симптом | Причина |
|---|---|
| Страница не открывается | Apache не запущен в XAMPP или порт 80 занят |
| Белый экран | Синтаксическая ошибка — смотрите php_error.log |
mysqli / PDO не работает | Расширение не включено в php.ini |
| 404 на localhost | Файл не в htdocs или неверный URL |
Что попробовать
php -S localhost:8000— встроенный сервер без Apache.- Форма POST на ту же страницу — обработка
$_POST. - Фреймворк: Laravel или Symfony.
Частые ошибки
| Симптом | Причина |
|---|---|
| Страница не открывается | Apache не запущен в XAMPP или порт 80 занят |
| Белый экран | Синтаксическая ошибка — смотрите php_error.log |
mysqli / PDO не работает | Расширение не включено в php.ini |
| 404 на localhost | Файл не в htdocs или неверный URL |
Что попробовать
php -S localhost:8000— встроенный сервер без Apache.- Форма POST на ту же страницу — обработка
$_POST. - Фреймворк: Laravel или Symfony.
В подборках
Статья входит в тематические подборки и блок "С чего начать?" на главной. Соседние шаги того же маршрута:
Первые шаги (маршрут подборки) — Первая программа на Java, Первая программа на Go, Первая программа на Python, Первая программа на C#, Первая программа на C++, Первая программа на TypeScript.