Чтение данных из CSV

В данной статье мы рассмотрим как прочитать CSV-файл и работать с данными как в CMS Битрикс, так и на чистом PHP.

Как это делается в Битриксе

В Битриксе есть довольно старый класс CCSVData – он позволяет читать данные из файла, а также записывать их.

Использование этого класса можно встретить в коде экспорта фидов CSV-формата

Пример чтения файла:

<?
$csvFile = new \CCSVData('R', true);
$csvFile->LoadFile($_SERVER['DOCUMENT_ROOT'] . '/prog.csv');
$csvFile->SetDelimiter(';');
while ($row = $csvFile->Fetch())
{
\Bitrix\Main\Diag\Debug::dump($row);
}

Пример записи данных в файл:

<?
$csvFile = new \CCSVData('R', true);
$csvFile->SetDelimiter(';');
$fileName = $_SERVER['DOCUMENT_ROOT'] . '/prog.csv';
// первая строка с названиями колонок
$csvFile->SaveFile($fileName, [
'One', 'Two', 'Three'
]);
// запись данных строки
$csvFile->SaveFile($fileName, [
'1', '2', '3'
]);

Как это делается на чистом PHP

Здесь мы приведем класс, который облегчит чтение из CSV-файла. Записывать, к сожалению, его еще не научили.

Листинг класса:

<?php
class CsvParser
{
protected $handle;
protected $header;
public function open($file, $header = true)
{
$this->handle = fopen($file, 'r');
if (!$this->handle)
{
throw new RuntimeException('Файл недоступен для чтения ' . $file);
}
if ($header)
{
$this->header = fgetcsv($this->handle);
}
return $this;
}
public function parse()
{
$arData = [];
if (!$this->handle)
{
throw new RuntimeException('Файл не открыт!');
}
while (($data = fgetcsv($this->handle)) !== false)
{
if ($this->header)
{
$data = array_combine($this->header, $data);
}
$arData[] = $data;
}
return $arData;
}
public function __destruct()
{
$this->close();
}
public function close()
{
if ($this->handle)
{
fclose($this->handle);
$this->handle = null;
}
}
}

Пример работы с классом:

<?
require_once 'csvfile.php';
$file = 'programs.csv';
$data = (new CsvParser())->open($file)->parse();
foreach ($data as $datum) {
// ...
}