W3docs

Работа с файлами в PHP

PHP предоставляет широкие возможности для работы с файлами и папками на сервере. В этой статье рассматриваются функции файловой системы PHP.

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

В этой главе рассматривается полный жизненный цикл файла — создание, чтение, обновление и удаление (CRUD) — и объясняется, когда использовать тот или иной подход. В целом PHP предлагает два стиля:

  • Вспомогательные функции для работы с целым файлом (file_get_contents(), file_put_contents()) — одна строка кода, идеально подходит для небольших файлов, которые целиком помещаются в памяти.
  • Потоковые функции (fopen(), fread(), fwrite(), fgets(), fclose()) — предоставляют дескриптор, позволяющий читать или писать большой файл по частям, не загружая его целиком.

Умение выбрать правильный подход — разница между кодом, который работает с конфигурационным файлом размером 2 КБ, и кодом, который справится с логом размером 2 ГБ.

Режимы открытия файлов

Каждый потоковый вызов начинается с fopen($filename, $mode), и именно режим чаще всего вызывает затруднения у начинающих. Он определяет, открывается ли файл для чтения, записи или обоих операций, стирается ли существующее содержимое и где начинается внутренний указатель.

РежимЧтениеЗаписьУказательЕсли файл отсутствуетСуществующее содержимое
"r"данетначалопредупреждение, возвращает falseсохраняется
"r+"даданачалопредупреждение, возвращает falseсохраняется
"w"нетданачалосоздаётсястирается (усекается)
"w+"даданачалосоздаётсястирается (усекается)
"a"нетдаконецсоздаётсясохраняется (дописывается)
"a+"дадаконецсоздаётсясохраняется (дописывается)
"x"нетданачалосоздаётсязавершается ошибкой, если файл уже существует

Добавьте "b" (например "rb", "wb") для безопасной работы с бинарными данными при работе с изображениями, PDF-файлами или любыми нетекстовыми данными — это предотвращает преобразование символов перевода строки в Windows.

Создание и запись файла

Чтобы создать файл, откройте его в режиме записи с помощью fopen() и запишите данные через fwrite(). Всегда закрывайте дескриптор с помощью fclose() по завершении работы — это сбрасывает буфер на диск и освобождает ресурс.

<?php
$file = fopen("test.txt", "w");   // create/truncate, open for writing
fwrite($file, "Hello World\n");
fwrite($file, "Second line\n");   // each call appends after the previous one
fclose($file);                    // flush to disk and release the handle

Открытие с режимом "w" стирает любое существующее содержимое. Чтобы добавить данные в файл, не уничтожая уже имеющиеся, откройте его в режиме дозаписи ("a"):

<?php
$log = fopen("app.log", "a");     // pointer starts at end of file
fwrite($log, "User logged in at " . date("H:i:s") . "\n");
fclose($log);

Для быстрой однострочной записи, когда вся строка уже находится в памяти, пропустите дескриптор и используйте file_put_contents():

<?php
file_put_contents("test.txt", "Hello World\n");          // overwrite
file_put_contents("app.log", "another line\n", FILE_APPEND); // append

Всегда проверяйте возвращаемое значение fopen(). Если путь неверен или директория недоступна для записи, функция вернёт false и PHP выдаст предупреждение — использование false в качестве дескриптора приведёт к скрытой ошибке.

<?php
$file = fopen("/protected/test.txt", "w");
if ($file === false) {
    die("Could not open the file for writing.");
}
fwrite($file, "data");
fclose($file);

Чтение файла

Самый простой способ прочитать небольшой файл — file_get_contents(), которая возвращает всё содержимое в виде одной строки:

<?php
$content = file_get_contents("test.txt");
echo $content;          // prints everything in the file

Когда файл большой, загружать его целиком в память неэффективно. Читайте его построчно с помощью fgets(), в цикле до достижения feof() (конца файла):

<?php
$file = fopen("test.txt", "r");
while (!feof($file)) {
    $line = fgets($file);   // reads one line, including the newline
    echo $line;
}
fclose($file);

Если нужно получить каждую строку как элемент массива за один вызов, удобна функция file() — однако, как и file_get_contents(), она загружает весь файл в память:

<?php
$lines = file("test.txt");          // array, one element per line
echo "This file has " . count($lines) . " lines.";

Хорошей практикой является проверка существования файла перед его чтением с помощью file_exists() (или is_readable() для проверки прав доступа):

<?php
if (file_exists("test.txt")) {
    echo file_get_contents("test.txt");
} else {
    echo "File not found.";
}

Обновление файла

Для замены содержимого файла наиболее удобный инструмент — file_put_contents(). Она открывает, записывает и закрывает файл за один вызов:

<?php
$content = "Hello World Again\n";
file_put_contents("test.txt", $content);   // replaces the old contents

Чтобы добавить данные в файл, а не заменить их, передайте флаг FILE_APPEND (показано выше) или откройте файл в режиме дозаписи через fopen(). Функции «изменить строку 3» не существует — для изменения части файла обычно читают его, модифицируют данные в PHP и записывают обратно.

Удаление файла

Используйте unlink() — обратите внимание на нестандартное название — для удаления файла. Функция возвращает true при успехе и false при неудаче, поэтому используйте её совместно с file_exists(), чтобы избежать предупреждения:

<?php
if (file_exists("test.txt")) {
    if (unlink("test.txt")) {
        echo "File deleted.";
    } else {
        echo "Could not delete the file.";
    }
} else {
    echo "Nothing to delete.";
}

unlink() удаляет только файлы. Для удаления пустой директории используйте rmdir(); смотрите раздел Директории PHP для работы с папками.

Когда использовать тот или иной подход

  • Небольшие текстовые или конфигурационные файлы, содержимое целикомfile_get_contents() / file_put_contents().
  • Большие файлы, построчное чтениеfopen() + fgets() / fread().
  • Дозапись в лог → режим "a" или FILE_APPEND.
  • Создание файла только если он ещё не существует → режим "x".
  • Бинарные данные (изображения, PDF) → добавьте флаг "b" и используйте fread()/fwrite().

Итоги

Работа с файлами — ключевая часть серверного PHP. Вы познакомились с двумя семействами функций — однострочными вспомогательными функциями для работы с целым файлом и потоковыми функциями с дескрипторами — и узнали, когда каждое из них уместно, как режимы управляют усечением и дозаписью, как эффективно читать большие файлы с помощью fgets()/feof(), а также как обновлять и безопасно удалять файлы.

Для более глубокого изучения загляните в специализированные главы: Создание и запись файла, Открытие и чтение файла, Функции файловой системы PHP, Загрузка файлов и Директории PHP.

Практика

Практика
Какие способы открытия файла в PHP являются правильными?
Какие способы открытия файла в PHP являются правильными?
Was this page helpful?