Парсер CSV-файла на PHP
В одном из рабочих проектов менеджеры загружают информацию в формате CSV-файлов. Все бы хорошо, но у некоторых на компьютерах установлен Microsoft Office, а у других OpenOffice. И, как выяснилось, при сохранении файлов в формате CSV, получается совершенно разный результат: OpenOffice все без исключения поля заключает в кавычки, а поделка от Microsoft делает это как-то выборочно. В некоторых случаях стандартная функция
fgetcsv на таких файлах давала сбой, пришлось рисовать свой аналог.
//------------------------------------------------------------
// Функция парсера CSV-файла
//------------------------------------------------------------
// На входе: $file_name - имя файла для парсинга
// $separator - разделитель полей, по умолчанию ';'
// $quote - ограничитель строк, по умолчанию '"'
// На выходе: массив значений всего файла
//------------------------------------------------------------
function fuck_csv($file_name, $separator=';', $quote='"') {
// Загружаем файл в память целиком
$f=fopen($file_name,'r');
$str=fread($f,filesize($file_name));
fclose($f);
// Убираем символ возврата каретки
$str=trim(str_replace("\r",'',$str))."\n";
$parsed=Array(); // Массив всех строк
$i=0; // Текущая позиция в файле
$quote_flag=false; // Флаг кавычки
$line=Array(); // Массив данных одной строки
$varr=''; // Текущее значение
while($i<=strlen($str)) {
// Окончание значения поля
if ($str[$i]==$separator && !$quote_flag) {
$varr=str_replace("\n","\r\n",$varr);
$line[]=$varr;
$varr='';
}
// Окончание строки
elseif ($str[$i]=="\n" && !$quote_flag) {
$varr=str_replace("\n","\r\n",$varr);
$line[]=$varr;
$varr='';
$parsed[]=$line;
$line=Array();
}
// Начало строки с кавычкой
elseif ($str[$i]==$quote && !$quote_flag) {
$quote_flag=true;
}
// Кавычка в строке с кавычкой
elseif ($str[$i]==$quote && $str[($i+1)]==$quote && $quote_flag) {
$varr.=$str[$i];
$i++;
}
// Конец строки с кавычкой
elseif ($str[$i]==$quote && $str[($i+1)]!=$quote && $quote_flag) {
$quote_flag=false;
}
else {
$varr.=$str[$i];
}
$i++;
}
return $parsed;
}
На входе передаются три параметра: обязательный параметр $file_name - путь к CSV-файлу, необязательные параметры $separator - разделитель значений полей в строке, по умолчанию ';' и $quote - ограничитель текстовых полей, по умолчанию двойная кавычка. На выходе из функции возвращается массив с распарсенными значениями всего файла. Дополнительных проверок на существование файла и корректность его внутреннего формата не производится, можете добавить эти функции самостоятельно. Также теоретически могут возникнуть проблемы с обработкой файлов очень большого объема. На моей практике таких проблем не возникало, так что может быть это решение пригодится кому-нибудь еще.
Комментарии:
Нету комментариев для вывода...