Имя клиента не является путём
Pulse принимает логическое имя отчёта, но сервер сам создаёт физическое имя. Последовательность ../, абсолютный путь, NUL и альтернативные разделители не проходят boundary. Простая замена '../' недостаточна: путь нормализуется и проверяется относительно разрешённого корня.
realpath полезен для существующего объекта, но возвращает false для будущего файла. Поэтому родительский каталог разрешается отдельно, а новое basename создаётся из строгого канонического алфавита.
Crash-safe публикация
Почему один file_put_contents не всегда достаточен
Короткая запись удобна, но ошибка может оставить неполное содержимое или конкурировать с читателем. Для критичного отчёта создайте temp в том же filesystem, проверьте все write, при необходимости fsync и выполните rename.
Атомарность rename зависит от платформы и границы filesystem. Кросс-дисковое перемещение превращается в копирование. Требование тестируется в целевой среде, а не выводится из имени функции.
flock — соглашение участников
Advisory lock работает, если все писатели и читатели соблюдают один протокол. Он не защищает от процесса, который игнорирует lock, и может вести себя иначе на сетевых файловых системах. Lock держат минимальное время и всегда освобождают.
Для координации нескольких production workers база или специализированный lock service часто дают более ясные гарантии. Локальный файл подходит одному хосту после теста отказа процесса.
Permissions и umask
Режим файла определяется запрошенными правами и umask процесса. chmod после создания имеет окно и не исправляет владельца. Каталог Pulse создаётся заранее deployment-процессом с минимальными правами, а FPM worker не получает доступ к исходникам и секретам сверх необходимости.
Загруженный или сгенерированный файл хранится вне public web-root. Если его нужно скачать, контроллер повторно проверяет право и отдаёт заданный Content-Type без исполнения.
Лаборатория
Реализуйте ReportPublisher с temp+rename и тестом сбоя после половины записи. Попробуйте имена ../secret, абсолютный путь и Unicode-двойник разделителя.
- Temp расположен рядом с целью.
- После сбоя старый отчёт цел.
- Клиентское имя никогда не соединяется с root напрямую.
Закрепите материал
Отметка, заметка, чек-лист и ответы остаются в localStorage этого браузера и не отправляются в аналитику.
Перелинковка со справочником
Проверка актуальности
- php.nethttps://www.php.net/manual/en/book.filesystem.phpПервичный источник для актуализации фактов. Адрес приведён как текст и не является активной ссылкой.
- php.nethttps://www.php.net/manual/en/book.stream.phpПервичный источник для актуализации фактов. Адрес приведён как текст и не является активной ссылкой.
Текст и схемы созданы для этого самоучителя без воспроизведения страниц, иллюстраций и листингов приложенной книги. Проверено: .