Методы записи в файл в языке PHP: обзор и примеры
Запись в файл в PHP
Как проще всего записать строку в файл?
Основной и наиболее эффективный способ - использование встроенной функции file_put_contents. Она объединяет открытие, запись и закрытие файла в один вызов. Функция автоматически создаёт файл, если он не существует, и возвращает количество записанных байт или false в случае ошибки.
<?php
$data = "Строка для записи.\n";
$bytes = file_put_contents('example.txt', $data);
if ($bytes !== false) {
echo "Записано $bytes байт.";
} else {
echo "Ошибка записи.";
}
?>Php file write (запись в файл в php)
Типичные проблемы: отсутствие прав на запись в директорию, превышение лимита диска, неверный путь (если каталог не существует, функция не создаёт его). Решение: проверять существование каталога и права через is_writable() перед записью, использовать абсолютные пути.
Как записать данные с помощью fwrite?
Более гибкий способ - работа с ресурсом файла через fopen, fwrite и fclose. Это позволяет управлять режимом открытия (чтение, запись, добавление), блокировками и записывать данные частями.
<?php
$filename = 'log.txt';
$handle = fopen($filename, 'w'); // режим 'w' - перезапись
if ($handle) {
fwrite($handle, "Первая строка.\n");
fwrite($handle, "Вторая строка.\n");
fclose($handle);
echo "Запись завершена.";
} else {
echo "Не удалось открыть файл.";
}
?>Saved files php (сохраненные файлы в php)
Типичные ошибки: забыть закрыть файл (утечка ресурсов), открытие в неверном режиме (например, 'r' вместо 'w'), конфликты блокировок при параллельном доступе. Решение: всегда закрывать файл, использовать flock() для исключительной блокировки.
Как дописать данные в конец существующего файла?
Для добавления данных без удаления существующего содержимого применяется флаг FILE_APPEND у file_put_contents или режим 'a' (append) у fopen.
<?php
// Вариант 1: file_put_contents с флагом
file_put_contents('data.txt', "Новая строка.\n", FILE_APPEND);
// Вариант 2: fopen + fwrite с режимом 'a'
$handle = fopen('data.txt', 'a');
fwrite($handle, "Ещё одна строка.\n");
fclose($handle);
?>
Ошибка: случайное использование режима 'w' (перезапись) приведёт к потере данных. Решение: явно указывать 'a' или флаг FILE_APPEND.
Как записать массив данных в CSV-файл?
Для записи табличных данных в формате CSV используется функция fputcsv. Она автоматически экранирует разделители и строки.
<?php
$rows = [
['Name', 'Age', 'City'],
['Alice', 30, 'Moscow'],
['Bob', 25, 'Kazan']
];
$handle = fopen('users.csv', 'w');
foreach ($rows as $row) {
fputcsv($handle, $row);
}
fclose($handle);
echo "CSV файл создан.";
?>
Проблемы: неверная локаль (разделитель может быть запятой или точкой с запятой), отсутствие транзакций при частичной записи. Решение: явно задавать разделитель через третий параметр fputcsv, использовать временный файл с последующим переименованием.
Как записать бинарные данные (изображение, архив)?
Для бинарных данных файл открывается в режиме 'wb' (binary write), чтобы избежать преобразования концов строк. file_put_contents также подходит, так как по умолчанию работает в бинарном режиме.
<?php
$binaryData = file_get_contents('source.png'); // читаем бинарный файл
file_put_contents('copy.png', $binaryData); // записываем копию
?>
Ошибка: открытие текстового режима 'w' на Windows может приводить к замене символа новой строки (\n -> \r\n). Решение: всегда использовать 'b' в режиме для бинарных данных ('wb', 'ab').
Как записать файл с блокировкой от одновременного доступа?
Для конкурентной записи применяется flock() с исключительной блокировкой (LOCK_EX). file_put_contents может принимать флаг LOCK_EX.
<?php
// С блокировкой через file_put_contents
file_put_contents('shared.txt', "Безопасные данные.\n", FILE_APPEND | LOCK_EX);
// С блокировкой через fopen/flock
$handle = fopen('shared.txt', 'a');
if (flock($handle, LOCK_EX)) {
fwrite($handle, "Данные под блокировкой.\n");
flock($handle, LOCK_UN); // снятие блокировки
}
fclose($handle);
?>
Проблема: блокировка не работает на некоторых файловых системах (NFS), ожидание блокировки может быть бесконечным. Решение: использовать таймауты или альтернативные механизмы (базы данных, очереди).
Как записать файл с использованием объектно-ориентированного подхода?
Класс SplFileObject предоставляет объектный интерфейс для работы с файлами. Метод fwrite() аналогичен стандартному.
<?php
$file = new SplFileObject('newfile.txt', 'w');
$file->fwrite("Объектная запись.\n");
$file = null; // файл автоматически закрывается
?>
Ошибка: забыть сбросить буфер (нет явного fflush()) - данные могут остаться в памяти. Решение: вызвать fflush() или уничтожить объект.
Расширенные примеры записи в файл
<?php
// Пример 1: file_put_contents с флагом LOCK_EX и проверкой
$data = "Важные данные.\n";
$result = file_put_contents('lock_example.txt', $data, LOCK_EX);
if ($result === false) {
echo "Ошибка записи.";
} else {
echo "Записано $result байт.";
}
?>
Записано 17 байт.
<?php
// Пример 2: запись массива строк с помощью fwrite в цикле
$lines = ['Строка 1', 'Строка 2', 'Строка 3'];
$handle = fopen('lines.txt', 'w');
if ($handle) {
foreach ($lines as $line) {
fwrite($handle, $line . PHP_EOL);
}
fclose($handle);
}
?>
(Файл lines.txt содержит: Строка 1\nСтрока 2\nСтрока 3\n)
<?php
// Пример 3: запись CSV с пользовательским разделителем и экранированием
$data = [
['product', 'price'],
['Coffee', '250.50'],
['Tea', '150,00'] // запятая внутри значения
];
$handle = fopen('products.csv', 'w');
foreach ($data as $row) {
fputcsv($handle, $row, ';', '"');
}
fclose($handle);
?>
(products.csv): product;price Coffee;250.50 Tea;"150,00"
<?php
// Пример 4: запись бинарного файла (изображения) с буферизацией
$src = 'image.jpg';
$dst = 'image_copy.jpg';
$srcHandle = fopen($src, 'rb');
$dstHandle = fopen($dst, 'wb');
if ($srcHandle && $dstHandle) {
while (!feof($srcHandle)) {
$chunk = fread($srcHandle, 8192);
fwrite($dstHandle, $chunk);
}
fclose($srcHandle);
fclose($dstHandle);
echo "Копия создана.";
} else {
echo "Ошибка открытия файла.";
}
?>
Копия создана. (image_copy.jpg идентичен исходному)
<?php
// Пример 5: обработка ошибок записи с is_writable и try-catch
$filename = '/var/log/app.log';
if (!is_writable(dirname($filename))) {
echo "Каталог не доступен для записи.";
exit;
}
try {
$bytes = file_put_contents($filename, "Лог-запись.\n");
if ($bytes === false) {
throw new Exception("Ошибка записи.");
}
} catch (Exception $e) {
echo "Ошибка: " . $e->getMessage();
}
?>
(если каталог доступен, запись успешна; иначе выводится сообщение об ошибке)
<?php
// Пример 6: использование SplFileObject::fwrite с принудительным сбросом
$file = new SplFileObject('objects.txt', 'w');
$file->fwrite("Первая строка.\n");
$file->fflush(); // сброс буфера
$file->fwrite("Вторая строка.\n");
$file = null; // закрытие
?>
(objects.txt содержит две строки)