Методы работы с текстовыми строками в файлах через PHP

Раздел: Программирование на PHP -> Обработка строк

Основные способы работы со строками в файлах PHP

Базовый метод: file_put_contents и file_get_contents

Как быстро записать строку в файл и прочитать её целиком?

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

<?php
$filename = 'message.txt';
$data = "Привет, мир!\nВторая строка.";
file_put_contents($filename, $data);
$result = file_get_contents($filename);
echo $result;
?>

Результат выполнения: на экран будет выведена строка "Привет, мир!" и "Вторая строка." каждая с новой строки.

Пояснения:

1. file_put_contents автоматически открывает файл на запись, записывает строку и закрывает. Если файла нет, он создается. Если файл существует, по умолчанию перезаписывается. Для добавления данных используется флаг FILE_APPEND.

2. file_get_contents читает все содержимое файла в виде строки. Удобно для конфигурационных файлов, шаблонов и т.п.

Возможные проблемы:

Недостаток памяти при очень больших файлах (сотни мегабайт). Решение: использовать построчное чтение fgets.

Ошибка доступа (Permission denied). Решение: проверить права на директорию, выставить chmod 755 или 644.

Нельзя работать с бинарными данными (например, изображениями) без дополнительной настройки, но file_get_contents поддерживает бинарный режим.

Когда применять:

Сохранение коротких текстов, настроек, результатов работы скрипта в виде строки. Быстрое копирование содержимого файла.

Вариант 1: Построчная обработка через fopen, fgets, fwrite

Как обработать большой файл, не загружая его целиком в память?

Для файлов размером более 10-20 МБ лучше использовать построчное чтение. Функция fopen открывает файл и возвращает указатель. fgets читает одну строку (до символа новой строки или указанной длины).

<?php
$handle = fopen('bigfile.log', 'r');
if ($handle) {
    $output = fopen('filtered.log', 'w');
    while (($buffer = fgets($handle, 4096)) !== false) {
        // фильтрация: сохраняем только строки, содержащие слово "ERROR"
        if (strpos($buffer, 'ERROR') !== false) {
            fwrite($output, $buffer);
        }
    }
    fclose($handle);
    fclose($output);
}
?>

Пояснения:

fopen('bigfile.log', 'r') открывает файл только для чтения. Второй аргумент 'r' означает чтение с начала файла.

Цикл while читает строки по очереди. Как только fgets возвращает false, файл заканчивается. Важно использовать !== false, так как пустая строка (например, конец файла) может быть false при ошибках.

fwrite записывает строку в выходной файл. Каждый вызов fgets читает следующую строку.

Типичные ошибки:

Забыть закрыть файл через fclose - утечка ресурсов.

Неправильный режим открытия: 'w' удалит существующее содержимое. Для добавления используйте 'a'.

Если файл очень большой, fgets может вернуть false не только при конце файла, но и при ошибке. Лучше проверять feof.

Когда применять:

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

Вариант 2: Чтение фиксированного количества байт через fread

Как прочитать из файла ровно N байт или заданный фрагмент?

Функция fread($handle, $length) читает $length байт из файла. Полезна для бинарных файлов (изображения, архивы) или когда нужно прочитать фиксированный заголовок.

<?php
$file = fopen('image.jpg', 'rb'); // двоичный режим
$header = fread($file, 4); // читаем первые 4 байта (сигнатура JPEG: 0xFF 0xD8 0xFF 0xE0)
echo bin2hex($header); // выводим в шестнадцатеричном виде
fclose($file);
?>

Результат: например, ffd8ffe0 - начало JPEG.

Пояснения:

Режим 'rb' указывает на чтение в двоичном режиме (для Windows актуально, чтобы не преобразовывать переводы строк).

fread может прочитать меньше байт, чем запрошено, если достигнут конец файла. Необходимо проверять длину прочитанного через strlen($header).

Проблемы:

При использовании fread для текстового файла (без 'b') на Windows символы \r\n могут быть преобразованы, что исказит длину. Решение: всегда указывать 'b' для бинарных файлов.

Неверный указатель при открытии файла - проверить на false.

Когда применять:

Чтение заголовков файлов, работа с бинарными протоколами, разбор структурированных данных фиксированной длины.

Вариант 3: Преобразование файла в массив строк через file()

Как получить массив строк файла для последующей обработки?

Функция file($filename) считывает все строки файла в массив. Может быть полезна для небольших конфигурационных или текстовых файлов, когда нужен произвольный доступ по номеру строки.

<?php
$lines = file('config.ini', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $num => $line) {
    echo "Строка " . ($num+1) . ": " . htmlspecialchars($line) . "<br>\n";
}
?>

Результат: вывод каждой строки с номером, пустые строки пропущены.

Пояснения:

Флаг FILE_IGNORE_NEW_LINES удаляет символы новой строки из каждого элемента массива.

FILE_SKIP_EMPTY_LINES пропускает пустые строки (строки, состоящие только из символов перевода).

Проблемы:

При больших файлах массив может занять много памяти. Решение: использовать построчное чтение.

Строки могут содержать бинарные символы, которые испортят вывод. Рекомендуется использовать htmlspecialchars при выводе.

Когда применять:

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

Расширенные примеры работы со строками в файлах PHP

Пример 1: Запись и чтение CSV с помощью fputcsv и fgetcsv

Пример
<?php
$data = [
    ['Имя', 'Возраст', 'Город'],
    ['Иван', 25, 'Москва'],
    ['Мария', 30, 'Санкт-Петербург']
];
$file = fopen('users.csv', 'w');
foreach ($data as $row) {
    fputcsv($file, $row);
}
fclose($file);

// чтение
$file = fopen('users.csv', 'r');
while (($row = fgetcsv($file)) !== false) {
    print_r($row);
}
fclose($file);
?>
Array ( [0] => Имя [1] => Возраст [2] => Город )
Array ( [0] => Иван [1] => 25 [2] => Москва )
Array ( [0] => Мария [1] => 30 [2] => Санкт-Петербург )

Данный пример показывает, как записать двумерный массив в CSV-файл и затем прочитать его обратно. fputcsv автоматически экранирует поля и разделяет их запятой. fgetcsv разбирает строку на массив. Важно: при чтении рекомендуется проверять, что строка не пустая.

Пример 2: Поиск и замена с регулярными выражениями в файле

Пример
<?php
$source = fopen('source.txt', 'r');
$target = fopen('target.txt', 'w');
while (($line = fgets($source)) !== false) {
    // Замена всех дат формата 2023-01-01 на 01.01.2023
    $line = preg_replace('/(\d{4})-(\d{2})-(\d{2})/', '$3.$2.$1', $line);
    fwrite($target, $line);
}
fclose($source);
fclose($target);
echo "Готово";
?>

Предположим, файл source.txt содержит строку "Файл создан 2023-01-01.". После выполнения в target.txt будет "Файл создан 01.01.2023.". Регулярное выражение захватывает год, месяц и день, а замена переставляет их. Построчная обработка позволяет работать с файлами любого размера.

Пример 3: Использование fscanf для разбора структурированных строк

Пример
<?php
$file = fopen('data.txt', 'r');
while ($fields = fscanf($file, "ID: %d, Name: %s")) {
    list($id, $name) = $fields;
    echo "ID=$id, Name=$name\n";
}
fclose($file);
?>
ID=1, Name=Alice
ID=2, Name=Bob

Функция fscanf считывает строку и разбирает её по заданному формату. В примере файл data.txt содержит строки "ID: 1, Name: Alice" и т.д. Формат задаёт, что ожидается целое число (%d) после "ID: " и строка (%s) после "Name: ". Такой подход удобен для log-файлов с фиксированной структурой.

Пример 4: Разбиение большого файла на части по N строк

Пример
<?php
$source = fopen('big.txt', 'r');
$part = 1;
$maxLines = 100;
$lineCount = 0;
$handle = null;
while (($line = fgets($source)) !== false) {
    if ($lineCount % $maxLines == 0) {
        if ($handle) fclose($handle);
        $handle = fopen("part_$part.txt", 'w');
        $part++;
    }
    fwrite($handle, $line);
    $lineCount++;
}
fclose($handle);
fclose($source);
?>

Результат: файлы part_1.txt, part_2.txt и т.д., каждый содержит не более 100 строк. Алгоритм: отслеживается количество прочитанных строк; когда остаток от деления на 100 равен нулю, открывается новый выходной файл. Такой метод позволяет обрабатывать файл без загрузки в память целиком.

Строки в файле PHP - comments

En
Php строки в файле (php)