Last active
September 11, 2016 15:29
-
-
Save mermshaus/e9a01de0e57ac8b18306c24b69e13669 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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