<?php
class Xsv implements Iterator {
/**
* @var xsv file name
*/
protected $filePath;
/**
* @var field separator
*/
protected $separator;
protected $fileHandler;
protected $line;
protected $values;
protected $columns;
protected $key;
function __construct($filePath, $separator) {
$this->filePath = $filePath;
$this->separator = $separator;
$this->fileHandler = fopen($filePath, "r");
$this->rewind($this->fileHandler);
}
function __destruct() {
fclose($this->fileHandler);
}
protected function readAndSetLine() {
if (FALSE == ($line = fgets($this->fileHandler))) {
if (!feof($this->fileHandler)) {
throw new Exception("file read exception!");
}
return $this->line = null;
}
return $this->line = rtrim($line);
}
protected function setValues(array $items) {
$this->values = array();
foreach ($this->columns as $key => $column) {
$this->values[$column] = $items[$key];
}
}
function current() {
return $this->line == FALSE ? null : $this->values;
}
function key() {
return $this->key;
}
function next() {
if ($this->readAndSetLine() == null) {
// end of file
$this->key = null;
$this->values = null;
return;
}
$items = explode($this->separator, $this->line);
if ($this->columns == null) {
$this->columns = $items;
$this->key = 0;
return;
}
$this->setValues($items);
++$this->key;
}
function rewind() {
rewind($this->fileHandler);
$this->columns = null;
$this->key = null;
$this->next();
$this->next();
}
function valid() {
return $this->line !== null;
}
}
class Tsv extends Xsv {
function __construct($filePath) {
parent::__construct($filePath, "t");
}
}
class Csv extends Xsv {
function __construct($filePath) {
parent::__construct($filePath, ",");
}
}
class XsvFactory {
static function createXsv($filePath) {
switch (strtolower(substr($filePath, -3))) {
case "csv":
return new Csv($filePath);
case "tsv":
return new Tsv($filePath);
default:
throw new Exception("File format is invalid ${$filePath}.");
}
}
}