Skip to content

Instantly share code, notes, and snippets.

@mermshaus
Last active September 11, 2016 15:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mermshaus/e9a01de0e57ac8b18306c24b69e13669 to your computer and use it in GitHub Desktop.
Save mermshaus/e9a01de0e57ac8b18306c24b69e13669 to your computer and use it in GitHub Desktop.
<?php
// ****************************************************************
// Please note: An improved version of the class has been added to:
//
// https://github.com/mermshaus/kaloa-filesystem
//
// The code in this Gist is deprecated.
// ****************************************************************
namespace mermshaus;
use Exception;
use LogicException;
/**
*
*/
class CsvReader
{
/**
* @var string
*/
private $filename;
/**
* @var string
*/
private $delimiter;
/**
* @var string
*/
private $enclosure;
/**
* @var string
*/
private $escape;
/**
* @var resource|null
*/
private $stream = null;
/**
* @var int
*/
private $fetchRowLineCounter = 0;
/**
* @var array
*/
private $fetchRowKeys = array();
/**
* @param string $filename
* @param string $delimiter
* @param string $enclosure
* @param string $escape
*/
public function __construct($filename, $delimiter = ',', $enclosure = '"', $escape = '\\')
{
$this->filename = $filename;
$this->delimiter = $delimiter;
$this->enclosure = $enclosure;
$this->escape = $escape;
}
/**
* @return array
*/
public function fetchAll()
{
if (!$this->fileIsOpen()) {
$this->fileOpen();
}
rewind($this->stream);
$data = array();
while ($row = fgetcsv($this->stream, 0, $this->delimiter, $this->enclosure, $this->escape)) {
$data[] = $row;
}
$this->fileClose();
return $data;
}
/**
* @param array $keys If not empty, use as array keys. Otherwise read keys
* from first line of input data
* @return array
* @throws Exception
*/
public function fetchAllAssoc(array $keys = array())
{
if (!$this->fileIsOpen()) {
$this->fileOpen();
}
rewind($this->stream);
$headerFlag = true;
$keysCount = count($keys);
if ($keysCount > 0) {
$headerFlag = false;
}
$data = array();
while ($row = fgetcsv($this->stream, 0, $this->delimiter, $this->enclosure, $this->escape)) {
if ($headerFlag) {
$headerFlag = false;
$keys = $row;
$keysCount = count($keys);
continue;
}
if (count($row) !== $keysCount) {
throw new Exception('Malformed line in CSV input');
}
$data[] = array_combine($keys, $row);
}
$this->fileClose();
return $data;
}
/**
* @param array $keys
* @return array|bool
*/
public function fetchAssoc(array $keys = array())
{
if (!$this->fileIsOpen()) {
if (0 !== $this->fetchRowLineCounter) {
throw new LogicException('Invalid state for fetchRowLineCounter Should be 0, is ' . $this->fetchRowLineCounter);
}
$this->fileOpen();
}
$headerFlag = (count($keys) === 0);
$row = fgetcsv($this->stream, 0, $this->delimiter, $this->enclosure, $this->escape);
if (!is_array($row)) {
// EOF
$this->fileClose();
return false;
}
if ($this->fetchRowLineCounter === 0) {
if ($headerFlag) {
$this->fetchRowKeys = $row;
$this->fetchRowLineCounter++;
return $this->{__FUNCTION__}($keys);
} else {
$this->fetchRowKeys = $keys;
}
}
$this->fetchRowLineCounter++;
return array_combine($this->fetchRowKeys, $row);
}
/**
*
*/
private function fileOpen()
{
if (!$this->fileIsOpen()) {
$this->stream = fopen($this->filename, 'rb');
}
}
/**
* @return bool
*/
private function fileIsOpen()
{
return is_resource($this->stream);
}
/**
*
*/
private function fileClose()
{
if ($this->fileIsOpen()) {
fclose($this->stream);
$this->fetchRowLineCounter = 0;
$this->fetchRowKeys = array();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment