PHP

Парсер 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 - ограничитель текстовых полей, по умолчанию двойная кавычка. На выходе из функции возвращается массив с распарсенными значениями всего файла. Дополнительных проверок на существование файла и корректность его внутреннего формата не производится, можете добавить эти функции самостоятельно. Также теоретически могут возникнуть проблемы с обработкой файлов очень большого объема. На моей практике таких проблем не возникало, так что может быть это решение пригодится кому-нибудь еще.
Теги:
Парсер, CSV, файл
Добавлено: 21 Сентября 2013 02:28:11 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...