Blog. Just Blog

Парсер CSV-файла на PHP

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
В одном из рабочих проектов менеджеры загружают информацию в формате CSV-файлов. Все бы хорошо, но у некоторых на компьютерах установлен Microsoft Office, а у других OpenOffice. И, как выяснилось, при сохранении файлов в формате CSV, получается совершенно разный результат: OpenOffice все без исключения поля заключает в кавычки, а поделка от Microsoft делает это как-то выборочно. В некоторых случаях стандартная функция fgetcsv на таких файлах давала сбой, пришлось рисовать свой аналог.
  1. //------------------------------------------------------------
  2. // Функция парсера CSV-файла
  3. //------------------------------------------------------------
  4. // На входе: $file_name - имя файла для парсинга
  5. //           $separator - разделитель полей, по умолчанию ';'
  6. //           $quote - ограничитель строк, по умолчанию '"'
  7. // На выходе: массив значений всего файла
  8. //------------------------------------------------------------
  9. function fuck_csv($file_name$separator=';'$quote='"') {
  10.     // Загружаем файл в память целиком
  11.     $f=fopen($file_name,'r');
  12.     $str=fread($f,filesize($file_name));
  13.     fclose($f);
  14.  
  15.     // Убираем символ возврата каретки
  16.     $str=trim(str_replace("\r",'',$str))."\n";
  17.  
  18.     $parsed=Array();    // Массив всех строк
  19.     $i=0;               // Текущая позиция в файле
  20.     $quote_flag=false;  // Флаг кавычки
  21.     $line=Array();      // Массив данных одной строки
  22.     $varr='';           // Текущее значение
  23.  
  24.     while($i<=strlen($str)) {
  25.         // Окончание значения поля
  26.         if ($str[$i]==$separator && !$quote_flag) {
  27.             $varr=str_replace("\n","\r\n",$varr);
  28.             $line[]=$varr;
  29.             $varr='';
  30.         }
  31.         // Окончание строки
  32.         elseif ($str[$i]=="\n" && !$quote_flag) {
  33.             $varr=str_replace("\n","\r\n",$varr);
  34.             $line[]=$varr;
  35.             $varr='';
  36.             $parsed[]=$line;
  37.             $line=Array();
  38.         }
  39.         // Начало строки с кавычкой
  40.         elseif ($str[$i]==$quote && !$quote_flag) {
  41.             $quote_flag=true;
  42.         }
  43.         // Кавычка в строке с кавычкой
  44.         elseif ($str[$i]==$quote && $str[($i+1)]==$quote && $quote_flag) {
  45.             $varr.=$str[$i];
  46.             $i++;
  47.         }
  48.         // Конец строки с кавычкой
  49.         elseif ($str[$i]==$quote && $str[($i+1)]!=$quote && $quote_flag) {
  50.             $quote_flag=false;
  51.         }
  52.         else {
  53.             $varr.=$str[$i];
  54.         }
  55.         $i++;
  56.     }
  57.     return $parsed;
  58. }
На входе передаются три параметра: обязательный параметр $file_name - путь к CSV-файлу, необязательные параметры $separator - разделитель значений полей в строке, по умолчанию ';' и $quote - ограничитель текстовых полей, по умолчанию двойная кавычка. На выходе из функции возвращается массив с распарсенными значениями всего файла. Дополнительных проверок на существование файла и корректность его внутреннего формата не производится, можете добавить эти функции самостоятельно. Также теоретически могут возникнуть проблемы с обработкой файлов очень большого объема. На моей практике таких проблем не возникало, так что может быть это решение пригодится кому-нибудь еще.

Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 9946 | Комментариев: 10

Метки: PHP, CSV
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Александр (02.11.2016 в 02:33):
Спасибо! Решение очень помогло.
vzx (20.04.2016 в 14:17):
Отлично сработано! Респект!
Алексей (02.03.2015 в 09:16):
Огромное спасибо, дружище!

Скаченный скрипт отсюда =>http://www.php.su/articles/?cat=examples&page=045, неправильно обрабатывал некоторые строчки массива из файла csv.

Попробовал твою функцию - все стало работать нормально. Еще раз спасибо! Очень выручил!
Юрий (26.06.2012 в 13:20):
MS Office вставляет двойные кавычки перед названием только в случае, если в названии товара также есть двойные кавычки.
Дмитрий (24.05.2012 в 14:02):
Спасибо! Пригодился!
Генри (24.02.2012 в 04:35):
Интересное решение. Кстати я встречался с проблемами обработки больших фалов, но ни чего лучше не придумал как обрабатывать файл построчно, через AJAX. Иначе сервер вешается, мол долго как то там все. Но это вышло плюсом в виде строки загрузки в брузер загружающему.
Isaev (08.04.2011 в 13:22):
Python только для работы с большими числами использую...
Уж больно приятно, когда поддержка их по умолчанию ))
Больше всего в нём убивают отступы, как ограничение блоков (типа begin/end), постоянно бесит. А в общем положительный язык и возможности широкие
ManHunter (04.04.2011 в 14:52):
А я вот на Python заглядываюсь :)
Isaev (04.04.2011 в 14:51):
php нравится всё больше :)
ezfalc0n (03.04.2011 в 05:41):
Да, Дима. Самое интересное - что экспорт импорт через csv в разных продуктах от микрософт по разному ведет себя. Например экспорт из Outlook Express и импорт в Outlook 2003 адрессной книги.

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2017
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.05 сек. / MySQL: 2 (0.0026 сек.) / Память: 4.5 Mb
Наверх