Введение в библиотеку league/csv для PHP
Библиотека league/csv — это мощный и удобный инструмент для работы с CSV (Comma-Separated Values) файлами в PHP. Она предоставляет разработчикам простой, но гибкий API для чтения, записи, обработки и преобразования CSV данных. В отличие от встроенных PHP функций (fgetcsv, fputcsv), league/csv предлагает объектно-ориентированный подход, поддержку различных диалектов CSV, работу с BOM (Byte Order Mark), обработку больших файлов через итераторы и множество других полезных возможностей.
Эта библиотека является частью экосистемы The League of Extraordinary Packages и считается стандартом де-факто для работы с CSV в PHP. Она активно поддерживается, имеет отличную документацию и покрыта тестами.
Зачем нужна league/csv?
- Упрощение работы с CSV: Вместо ручного управления файловыми указателями и циклами, вы работаете с понятными объектами и методами.
- Безопасность: Библиотека корректно обрабатывает экранирование символов, кавычки и переносы строк внутри полей.
- Гибкость: Поддержка различных разделителей (запятая, точка с запятой, табуляция), символов экранирования и строковых ограничителей.
- Производительность: Использование генераторов (
yield) позволяет обрабатывать файлы любого размера без загрузки всего содержимого в память. - Функциональность: Встроенные методы для конвертации в JSON, HTML, XML, сортировки, фильтрации и преобразования столбцов.
Установка библиотеки
Установка league/csv производится через Composer — менеджер зависимостей для PHP. Убедитесь, что Composer установлен в вашей системе.
Откройте терминал в корневой директории вашего проекта и выполните команду:
composer require league/csv
После успешной установки, в вашем проекте появится папка vendor и файл composer.json / composer.lock. Для подключения библиотеки в PHP-скрипте используйте стандартный автозагрузчик Composer:
require 'vendor/autoload.php';
use League\Csv\Reader;
use League\Csv\Writer;
use League\Csv\Statement;
Быстрый старт с примером кода
Давайте создадим простой CSV-файл, запишем в него данные, а затем прочитаем их.
Пример 1: Запись данных в CSV
<?php
require 'vendor/autoload.php';
use League\Csv\Writer;
// Создаем объект Writer
$writer = Writer::createFromPath('users.csv', 'w+');
// Вставляем заголовки
$writer->insertOne(['ID', 'Имя', 'Email']);
// Вставляем несколько строк данных
$writer->insertAll([
[1, 'Иван Иванов', 'ivan@example.com'],
[2, 'Петр Петров', 'petr@example.com'],
[3, 'Анна Смирнова', 'anna@example.com'],
]);
echo "Файл users.csv успешно создан!";
?>
Пример 2: Чтение данных из CSV
<?php
require 'vendor/autoload.php';
use League\Csv\Reader;
// Создаем объект Reader
$reader = Reader::createFromPath('users.csv', 'r');
$reader->setHeaderOffset(0); // Указываем, что первая строка - это заголовки
// Получаем все записи в виде ассоциативных массивов
$records = $reader->getRecords();
foreach ($records as $record) {
echo "ID: " . $record['ID'] . ", Имя: " . $record['Имя'] . ", Email: " . $record['Email'] . "<br>";
}
?>
Основные методы и функции библиотеки league/csv
Рассмотрим ключевые методы, которые предоставляет библиотека для работы с CSV.
1. Reader::createFromPath() и Writer::createFromPath()
Что делает: Создает объект Reader или Writer для работы с файлом по указанному пути.
Параметры:
$path(string): Путь к файлу.$open_mode(string): Режим открытия файла (например, 'r' для чтения, 'w+' для записи).$context(resource|null): Потоковый контекст (необязательно).
Пример:
$reader = Reader::createFromPath('/path/to/file.csv', 'r');
$writer = Writer::createFromPath('/path/to/new_file.csv', 'w+');
2. Reader::createFromString() и Writer::createFromString()
Что делает: Создает объект для работы с CSV данными, находящимися в строковой переменной, а не в файле.
Параметры:
$content(string): Строка с CSV-данными.
Пример:
$csvContent = "Name,Age\nJohn,30\nJane,25";
$reader = Reader::createFromString($csvContent);
$records = $reader->getRecords();
foreach ($records as $record) {
print_r($record);
}
3. setDelimiter()
Что делает: Устанавливает разделитель полей (по умолчанию запятая). Полезно для TSV (табуляция) или других форматов.
Параметры:
$delimiter(string): Символ-разделитель (например, ';', "\t").
Пример:
$reader = Reader::createFromPath('data.tsv');
$reader->setDelimiter("\t"); // Устанавливаем табуляцию как разделитель
4. setEnclosure()
Что делает: Устанавливает символ, который используется для обрамления полей (по умолчанию двойные кавычки '"').
Параметры:
$enclosure(string): Символ обрамления.
Пример:
$reader->setEnclosure("'"); // Использовать одинарные кавычки для обрамления полей
5. setHeaderOffset()
Что делает: Указывает, какая строка (по индексу, начиная с 0) является строкой заголовков. После этого getRecords() будет возвращать ассоциативные массивы.
Параметры:
$offset(int|null): Индекс строки заголовка.nullотключает режим заголовков.
Пример:
$reader->setHeaderOffset(0); // Первая строка - заголовки
foreach ($reader->getRecords() as $record) {
echo $record['Name']; // Обращаемся по имени столбца
}
6. getRecords()
Что делает: Возвращает генератор (Generator), который позволяет итерироваться по всем записям CSV. Экономит память при работе с большими файлами.
Параметры:
- Нет обязательных параметров. Можно передать массив имен столбцов для фильтрации.
Пример:
foreach ($reader->getRecords() as $index => $record) {
echo "Строка $index: " . implode(', ', $record) . "\n";
}
7. insertOne()
Что делает: Вставляет одну строку в CSV-файл (объект Writer).
Параметры:
$record(array): Массив значений для одной строки.
Пример:
$writer->insertOne(['2024', 'Май', 'Продажи']);
8. insertAll()
Что делает: Вставляет множество строк из итерируемого источника (массива, генератора).
Параметры:
$records(iterable): Итерируемый объект или массив массивов.
Пример:
$rows = [
['Product', 'Price'],
['Laptop', 1200],
['Mouse', 25],
];
$writer->insertAll($rows);
9. Statement::process()
Что делает: Позволяет применять фильтрацию, сортировку и лимиты к записям перед их получением. Это мощный инструмент для построения запросов к CSV.
Параметры:
$records(TabularDataReader): Объект Reader.
Пример:
use League\Csv\Statement;
$stmt = (new Statement())
->offset(10) // Пропустить первые 10 записей
->limit(20) // Взять следующие 20 записей
->orderBy(function (array $rowA, array $rowB) {
return strcmp($rowA['Name'], $rowB['Name']); // Сортировка по имени
});
$records = $stmt->process($reader);
foreach ($records as $record) {
// Обработка
}
10. addFormatter()
Что делает: Добавляет форматтер, который может изменять каждую запись при чтении (например, преобразовывать типы данных).
Параметры:
$callable(callable): Функция, которая принимает массив записи и возвращает измененный массив.
Пример:
$reader->addFormatter(function (array $row) {
$row['Price'] = (float) $row['Price']; // Преобразуем цену в число с плавающей точкой
return $row;
});
11. addValidator()
Что делает: Добавляет валидатор, который проверяет каждую запись. Если валидатор возвращает false, запись пропускается.
Параметры:
$callable(callable): Функция-валидатор, принимает массив записи и возвращаетbool.
Пример:
$reader->addValidator(function (array $row) {
return filter_var($row['Email'], FILTER_VALIDATE_EMAIL) !== false; // Только валидные email
});
12. output()
Что делает: Отправляет CSV-контент непосредственно в браузер для скачивания. Устанавливает правильные HTTP-заголовки.
Параметры:
$filename(string): Имя файла для скачивания.$path(string): Путь к CSV-файлу (опционально).
Пример:
$writer->output('export.csv'); // Инициирует скачивание файла
Реальный практический пример использования
Представим задачу: у нас есть CSV-файл с заказами