Reader.php 2.46 KB
<?php

namespace Hranicka\Csv;

class Reader implements \IteratorAggregate
{

	/** @var string */
	private $filePath;

	/** @var bool */
	private $hasHeaderRow;

	/** @var string */
	private $delimiter;

	/** @var string */
	private $enclosure;

	/** @var string */
	private $escape;

	/** @var resource */
	private $handler;

	/**
	 * @param string $filePath CSV file path
	 * @param bool $hasHeaderRow Is the first row header?
	 */
	public function __construct($filePath, $hasHeaderRow = TRUE)
	{
		$this->filePath = $filePath;
		$this->hasHeaderRow = $hasHeaderRow;

		$this->setup();
	}

	/**
	 * @param string $delimiter
	 * @param string $enclosure
	 * @param string $escape
	 * @return $this
	 */
	public function setup($delimiter = ';', $enclosure = '"', $escape = '\\')
	{
		$this->delimiter = $delimiter;
		$this->enclosure = $enclosure;
		$this->escape = $escape;

		return $this;
	}

	public function getIterator()
	{
		return new \ArrayIterator($this->read());
	}

	/**
	 * @return array
	 * @throws InvalidFileException
	 * @deprecated Use ::read instead.
	 */
	public function parseAll()
	{
		return $this->read();
	}

	/**
	 * @return array
	 * @throws InvalidFileException
	 */
	public function read()
	{
		$return = [];

		$this->openHandler();

		$line = 0;
		$keys = NULL;

		while (($row = $this->readRow()) !== FALSE) {
			$line++;

			if ($this->hasHeaderRow) {
				if ($keys === NULL) {
					$keys = array_values($row);
				} else {

					if (count($keys) !== count($row)) {
//                        $rowArr = [$keys, $row];
//                        echo "<pre>";
//                        var_dump($rowArr);
//                        var_dump($return);
//                        echo "</pre>";
//                        die;
						throw new InvalidFileException("Invalid columns detected on line #$line .");
                       // return $return;
					}

					$return[] = array_combine($keys, $row);
				}
			} else {
				$return[] = $row;
			}
		}

		$this->closeHandler();

		return $return;
	}

	private function openHandler()
	{
		$this->handler = fopen($this->filePath, 'r');
		if ($this->handler === FALSE) {
			throw new InvalidFileException('Cannot open the file.');
		}
	}

	private function closeHandler()
	{
		fclose($this->handler);
		$this->handler = NULL;
	}

	/**
	 * @return array|false
	 */
	private function readRow()
	{
		return fgetcsv($this->handler, NULL, $this->delimiter, $this->enclosure, $this->escape);
	}

}

class InvalidFileException extends \Exception
{

}