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

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

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

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

Глава 13 · От основ к практике

Предопределённые переменные: CLI, HTTP, сессии и загрузки

От источника данных до безопасной проверки суперглобальных и специальных переменных.

$argv: значения после имени команды

Реальная потребность: запустить импорт, резервное копирование или фоновую задачу с параметрами без редактирования файла. Оболочка разбирает командную строку по своим правилам и передаёт PHP готовый список строк; $argv — этот индексированный массив.

Увидеть имя сценария и количество пользовательских аргументовСамостоятельный пример
<?php
echo 'Сценарий: ', basename($argv[0]), "\n";
echo 'Пользовательских аргументов: ', $argc - 1, "\n";
Ожидаемый результат
Сценарий: example.php
Пользовательских аргументов: 0

PHP CLI помещает имя запущенного файла в $argv[0], поэтому $argc равен как минимум 1. Пользовательские значения начинаются с индекса 1. В веб-запросе эти переменные могут отсутствовать: это интерфейс командной строки.

Проверить обязательный путь и необязательный флагСамостоятельный пример
<?php
function readCommand(array $arguments): array
{
    $input = $arguments[1] ?? null;
    $dryRun = in_array('--dry-run', $arguments, true);

    if ($input === null) {
        return ['ok' => false, 'message' => 'Укажите CSV-файл'];
    }

    return ['ok' => true, 'input' => $input, 'dryRun' => $dryRun];
}

$command = readCommand(['import.php', 'orders.csv', '--dry-run']);
echo $command['input'], "\n";
echo $command['dryRun'] ? "Без записи\n" : "С записью\n";
Ожидаемый результат
orders.csv
Без записи

Для воспроизводимой проверки массив аргументов задан явно. В настоящем CLI-входе передайте в функцию глобальный $argv. Оператор ?? задаёт запасное значение, а строгое сравнение в in_array не смешивает строки с числами.

Для сложных опций пригодится getopt(). Пути всё равно проверяют до открытия файла; сам факт присутствия строки ничего не говорит о доступности.

$argc: сколько элементов PHP передал сценарию

$argc содержит число элементов $argv, включая имя сценария. Поэтому проверка «передан ли один пользовательский аргумент» выглядит как $argc >= 2. count($argv) даёт то же количество, но $argc сразу сообщает назначение.

Что происходит при php import.php orders.csv
  1. Оболочка запускает PHP и передаёт два токена после настроек PHP.
  2. В $argv[0] оказывается путь import.php, в $argv[1] — orders.csv.
  3. $argc равен 2; пользовательских значений — $argc - 1.
  4. Код проверяет количество и только затем читает нужный индекс.

$http_response_header: метаданные ответа HTTP-wrapper

Когда file_get_contents() открывает HTTP/HTTPS URL, PHP создаёт в текущей локальной области массив строк ответа: первая строка содержит статус, остальные — заголовки. Это не заголовки входящего запроса к вашему сайту и не массив $_SERVER.

Разделить статус и повторяющиеся HTTP-заголовкиСамостоятельный пример
<?php
function indexHeaders(array $lines): array
{
    $result = ['status' => array_shift($lines), 'headers' => []];
    foreach ($lines as $line) {
        [$name, $value] = array_map('trim', explode(':', $line, 2));
        $result['headers'][strtolower($name)][] = $value;
    }
    return $result;
}

$response = indexHeaders([
    'HTTP/1.1 200 OK',
    'Content-Type: application/json',
    'Set-Cookie: region=ru',
    'Set-Cookie: theme=light',
]);

echo $response['status'], "\n";
echo $response['headers']['content-type'][0], "\n";
echo count($response['headers']['set-cookie']), " cookies\n";
Ожидаемый результат
HTTP/1.1 200 OK
application/json
2 cookies

Фикстура повторяет форму данных HTTP-wrapper без сетевого запроса. Один заголовок может встретиться несколько раз, поэтому значения сохраняются списком; разбиение ограничено двумя частями, чтобы двоеточие внутри значения не потерялось.

Получить заголовки последнего HTTP-запроса в современном PHPПример для указанного окружения
<?php
$context = stream_context_create([
    'http' => ['timeout' => 3.0, 'ignore_errors' => true],
]);
$body = file_get_contents('https://example.com/', false, $context);

if ($body === false) {
    throw new RuntimeException('HTTP-запрос не выполнен');
}

$headers = http_get_last_response_headers();
var_dump($headers[0] ?? null);

Контекстный пример требует сети, включённого HTTP-wrapper и PHP с http_get_last_response_headers(). Вывод зависит от ответа сервера, поэтому пример только проверяется синтаксически. В PHP 8.5 переменная $http_response_header устарела; современная функция явно выражает намерение.

$php_errormsg: почему старую глобальную переменную больше не используют

Эта переменная нужна прежде всего для понимания старого проекта. Она содержала текст последней ошибки в области, где произошла ошибка, но зависела от настройки и легко перезаписывалась следующим предупреждением.

Сохранить сведения о последнем предупреждении современным способомСамостоятельный пример
<?php
error_clear_last();
@file_get_contents(__DIR__ . '/missing.txt');
$error = error_get_last();

echo $error === null ? "Ошибки нет\n" : "Предупреждение сохранено\n";
Ожидаемый результат
Предупреждение сохранено

@ здесь использован только для учебной демонстрации: он скрывает показ, но error_get_last() всё равно позволяет прочитать сведения. В приложении заранее проверяют путь или обрабатывают конкретную ошибку, а не прячут все предупреждения.

Историческая запись до PHP 8Фрагмент или команда
<?php
// Только для чтения старого кода PHP 7.1 и более раннего:
ini_set('track_errors', '1');
@file_get_contents(__DIR__ . '/missing.txt');
echo $php_errormsg;

$php_errormsg зависела от устаревшей настройки track_errors, была deprecated в PHP 7.2 и удалена в PHP 8.0. Фрагмент намеренно не исполняется и не должен копироваться в современный проект.

Для нормального потока используйте возвращаемые значения, исключения и явную обработку ошибок. error_get_last() — диагностический снимок, а не замена такой обработке.

$_SESSION: состояние между HTTP-запросами

HTTP-запросы независимы. Сессия связывает случайный идентификатор клиента с данными на сервере: корзиной, одноразовым сообщением или этапом формы. После session_start() PHP читает хранилище и заполняет суперглобальный массив.

Как значение переживает переход на другую страницу
  1. Браузер отправляет идентификатор сессии в cookie.
  2. session_start() открывает серверное хранилище и заполняет $_SESSION.
  3. Код читает или меняет ключи массива.
  4. PHP сохраняет изменения; следующий запрос с тем же идентификатором увидит их.
Сохранить имя между двумя запусками сессии в одном опытеСамостоятельный пример
<?php
$store = __DIR__ . '/session-data';
if (!is_dir($store)) {
    mkdir($store);
}

ini_set('session.use_cookies', '0');
session_save_path($store);
session_id('lesson-session');

session_start();
$_SESSION['customerName'] = 'Анна';
session_write_close();

session_id('lesson-session');
session_start();
echo 'Покупатель: ', $_SESSION['customerName'], "\n";
$_SESSION = [];
session_destroy();
Ожидаемый результат
Покупатель: Анна

Пример создаёт собственный каталог внутри распакованного архива и не трогает системную сессию. session_start() загружает данные в $_SESSION; session_write_close() сохраняет их и освобождает блокировку.

$_FILES: что именно приходит из HTML-формы

Поле <input type="file" name="avatar"> при форме с method="post" и enctype="multipart/form-data" создаёт $_FILES['avatar']. Текстовые поля той же формы оказываются в $_POST.

КлючЧто означаетМожно ли доверять
name / full_pathИмя и относительный путь от клиентаНет; не используйте как серверный путь
typeMIME, заявленный клиентомНет; определите через finfo
tmp_nameВременный файл PHPПроверить is_uploaded_file
errorКод UPLOAD_ERR_*Проверить первым
sizeРазмер принятого временного файлаПроверить вместе с серверными лимитами
Прочитать один файл и объяснить пять полей записиСамостоятельный пример
<?php
$upload = [
    'name' => 'avatar.png',
    'full_path' => 'avatar.png',
    'type' => 'image/png',
    'tmp_name' => '/tmp/phpABC',
    'error' => UPLOAD_ERR_OK,
    'size' => 2048,
];

echo $upload['name'], "\n";
echo $upload['size'], " bytes\n";
echo $upload['error'] === UPLOAD_ERR_OK ? "Передан PHP\n" : "Ошибка загрузки\n";
Ожидаемый результат
avatar.png
2048 bytes
Передан PHP

Массив задан как безопасная фикстура, чтобы увидеть форму одной записи. name и type пришли от клиента и не доказывают содержимое; tmp_name в реальном запросе указывает на временный серверный файл.

Проверить ошибку, фактический MIME и перенести HTTP-загрузкуПример для указанного окружения
<?php
if (!isset($_FILES['avatar']) || !is_array($_FILES['avatar'])) {
    throw new RuntimeException('Поле avatar не отправлено');
}

$file = $_FILES['avatar'];
if ($file['error'] !== UPLOAD_ERR_OK) {
    throw new RuntimeException('Код ошибки загрузки: ' . $file['error']);
}
if ($file['size'] > 2_000_000 || !is_uploaded_file($file['tmp_name'])) {
    throw new RuntimeException('Файл слишком большой или не является HTTP-загрузкой');
}

$mime = (new finfo(FILEINFO_MIME_TYPE))->file($file['tmp_name']);
$extension = ['image/jpeg' => 'jpg', 'image/png' => 'png'][$mime] ?? null;
if ($extension === null) {
    throw new RuntimeException('Разрешены только JPEG и PNG');
}

$target = __DIR__ . '/uploads/' . bin2hex(random_bytes(16)) . '.' . $extension;
if (!move_uploaded_file($file['tmp_name'], $target)) {
    throw new RuntimeException('Не удалось сохранить файл');
}

Это контекстный HTTP-обработчик: CLI не создаёт настоящую загрузку, поэтому заявлена только проверка синтаксиса. Каталог uploads заранее создают вне публично исполняемого места и задают ему минимальные права. Лимиты upload_max_filesize и post_max_size могут остановить запрос до прикладной проверки.

Связь HTML-поля, $_POST, CSRF и ответа подробно разобрана в главе о формах.

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

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

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

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

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