str_getcsv()
Функция PHP str_getcsv(): синтаксис, параметры, примеры, разбор многострочного CSV и распространённые ошибки.
Функция str_getcsv() разбирает одну строку текста в формате CSV (значения, разделённые запятыми) и возвращает её поля в виде плоского массива. Это аналог fgetcsv(), работающий в памяти: вместо чтения строки из открытого файлового дескриптора она принимает уже имеющуюся строку — строку из формы, одну строку из ответа API или один элемент массива, который вы сами разбили.
Поскольку реальный CSV сложнее, чем кажется (поля могут быть заключены в кавычки, содержать запятые или разделители), str_getcsv() почти всегда предпочтительнее простого explode(',', $line), который ломается на любой экранированной запятой.
Синтаксис
str_getcsv(
string $string,
string $separator = ",",
string $enclosure = "\"",
string $escape = "\\"
): array| Параметр | Обязателен | Описание |
|---|---|---|
$string | Да | CSV-строка для разбора. |
$separator | Нет | Разделитель полей — один символ. По умолчанию ,. |
$enclosure | Нет | Символ, обрамляющий поля, содержащие разделитель, кавычки или переносы строк. По умолчанию ". |
$escape | Нет | Экранирующий символ. По умолчанию \. Передайте "", чтобы отключить фирменное экранирование PHP (рекомендуется для строгого CSV по RFC 4180). |
Функция всегда возвращает массив. Пустое поле становится пустой строкой (""); полностью пустая входная строка возвращает [null].
Базовый пример
Вывод:
Array
(
[0] => John
[1] => Doe
[2] => 25
)Каждое значение, разделённое запятой, становится одним элементом с индексом от 0.
Поля в кавычках и встроенные запятые
Именно здесь str_getcsv() демонстрирует свою ценность. Поле, заключённое в двойные кавычки, может содержать разделитель без разбиения:
<?php
$input = '"Doe, John","New York, NY",25';
$array = str_getcsv($input);
print_r($array);
?>Вывод:
Array
(
[0] => Doe, John
[1] => New York, NY
[2] => 25
)Обрамляющие кавычки удаляются, а запятые внутри них остаются частью данных. explode(',', $input) в этом случае ошибочно вернул бы пять элементов.
Использование другого разделителя и ограничителя
Многие «CSV»-файлы на самом деле используют точку с запятой или табуляцию в качестве разделителя. Переопределите второй и третий аргументы в соответствии с форматом:
<?php
$input = "'Jane Doe';'Berlin';30";
$array = str_getcsv($input, ';', "'");
print_r($array);
?>Вывод:
Array
(
[0] => Jane Doe
[1] => Berlin
[2] => 30
)Для строк с табуляцией в качестве разделителя используйте "\t".
Разбор многострочной CSV-строки
str_getcsv() разбирает одну строку за раз. Чтобы преобразовать целый CSV-документ в строки, сначала разбейте его на строки, а затем передайте каждую через функцию. Использование array_map() делает это компактным:
<?php
$csv = "name,city,age\nJohn,Boston,25\nJane,Berlin,30";
$rows = array_map('str_getcsv', explode("\n", $csv));
print_r($rows);
?>Вывод:
Array
(
[0] => Array
(
[0] => name
[1] => city
[2] => age
)
[1] => Array
(
[0] => John
[1] => Boston
[2] => 25
)
[2] => Array
(
[0] => Jane
[1] => Berlin
[2] => 30
)
)Примечание:
explode("\n", ...)— это простое разбиение. Если файл использует окончания строк Windows (\r\n) или поля содержат переносы строк внутри кавычек, предпочтительнее читать файл с помощьюfgetcsv()в цикле — он обрабатывает эти случаи нативно.
Сопоставление строк с заголовком
Распространённый паттерн — использовать первую строку как ключи и формировать ассоциативные массивы с помощью array_combine():
<?php
$lines = ['name,city,age', 'John,Boston,25', 'Jane,Berlin,30'];
$header = str_getcsv(array_shift($lines));
$people = [];
foreach ($lines as $line) {
$people[] = array_combine($header, str_getcsv($line));
}
print_r($people[0]);
?>Вывод:
Array
(
[name] => John
[city] => Boston
[age] => 25
)Распространённые ошибки
- Только одна строка. Передача многострочной строки обрабатывает её всю как одну запись, поэтому всегда разбивайте на строки перед разбором.
- Экранирующий символ удивляет. Стандартное для PHP экранирование через
\не соответствует стандарту. Для данных по RFC 4180 (где"экранируется удвоением, как""), передайтеescape: "", чтобы обратные слеши не поглощались. - Числа остаются строками. Каждое поле возвращается как строка (
"25", а не25). Явно приводите к нужному типу, если нужны числа. - Завершающий перенос строки. Строка с завершающим
\nможет привести к появлению пустого последнего поля; при необходимости предварительно обрежьте входные данные.
Связанные функции
fgetcsv()— читает и разбирает CSV-строку непосредственно из файлового дескриптора.fputcsv()— записывает массив в файл как CSV-строку (обратная операция).explode()— разбивает строку по разделителю, когда нет полей в кавычках.file_get_contents()— загружает CSV-файл в строку для передачи вstr_getcsv().