Самоучитель: PHP 8.5: инженерный практикум
Глава 8 из 22II. Мастерская данных105 минут

Глава 8. Файлы, потоки и безопасный импорт CSV

Загруженный файл — недоверенный поток байтов, а не PHP-модуль и не готовая таблица: путь, размер, кодировка и каждая строка требуют отдельного решения.

После главы вы сможете
  • нормализовать работу с путями
  • провести потоковый CSV-импорт
  • записать файл атомарно

Путь не приходит от пользователя готовым

Публичное имя файла не используется как серверный путь. Приложение создаёт собственное случайное имя в выделенном каталоге вне web-root и хранит исходное название только как метаданные после очистки управляющих символов.

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

Безопасный маршрут импорта

Импорт тренировок из CSVПользовательский файл никогда не подключается через include или require и не исполняется сервером.UploadlimitsQuarantinerandom nameStreamfgetcsvValidaterow resultCommitbatch
Пользовательский файл никогда не подключается через include или require и не исполняется сервером.

CSV — формат с договором

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

Каждая строка получает номер и результат: принята, отклонена с кодом причины или пропущена по явному правилу. Ошибка не должна превращать половину файла в молча сохранённые данные без отчёта.

Атомарная запись отчёта

<?php

$temporary = $reportPath . '.tmp-' . bin2hex(random_bytes(6));
$bytes = file_put_contents($temporary, $reportJson, LOCK_EX);

if ($bytes === false || !rename($temporary, $reportPath)) {
    throw new RuntimeException('Не удалось опубликовать отчёт');
}

Лимиты работают слоями

Размер ограничивается веб-сервером, PHP-настройками и бизнес-правилом. Проверяйте фактический код ошибки upload, число байтов и максимальное число строк. MIME от клиента не является доказательством формата.

Архивы требуют защиты от zip bomb и path traversal. Для учебного CSV проще запретить архивы целиком. Чем меньше поддерживаемых вариантов, тем яснее сообщения и надёжнее тесты.

Лабораторная работа

Опишите импорт тренировок из CSV с заголовками date, exercise, weight_kg и repetitions. Реализуйте построчный отчёт и гарантируйте, что ни один пользовательский путь не попадает в include/require.

Локальный прогресс

Закрепите материал

Отметка, заметка, чек-лист и ответы остаются в localStorage этого браузера и не отправляются в аналитику.

Перелинковка со справочником

Проверка актуальности

  • cheatsheetseries.owasp.orghttps://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.htmlПервичный источник для актуализации фактов. Адрес приведён как текст и не является активной ссылкой.

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

Данные этого сервиса

Настройки cookie и локальных данных

Аналитика

Текущий статус: не выбран. До согласия обе аналитические системы не загружаются.

Локальные данные

Удаление затрагивает только ключи PHP-сервиса в этом браузере и требует подтверждения.

Политики

Политика конфиденциальности · Политика использования файлов cookie