This commit is contained in:
Simon Vieille 2015-03-09 18:50:07 +01:00
parent 98d6b8673e
commit a0953d1b7a
8 changed files with 374 additions and 3 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.swp
tags

View File

@ -1,4 +1,6 @@
csv
===
CSV parser/generator
====================
A simple PHP library to parse and generate CSV files.
A simple PHP library to parse and generate CSV files.

198
src/Deblan/Csv/Csv.php Normal file
View File

@ -0,0 +1,198 @@
<?php
namespace Deblan\Csv;
use Deblan\Csv\Exception\CsvInvalidParameterException;
class Csv
{
private $delimiter;
private $enclosure;
private $escape_char;
private $endline;
private $datas;
private $legend;
private $render;
private $encoding;
private $hasLegend = false;
public function __construct($delimiter = ';', $enclosure = '"', $escape_char = '\\', $endline = "\n", $encoding = 'UTF-8')
{
$this->setDelimiter($delimiter);
$this->setEnclosure($enclosure);
$this->setEscapeChar($escape_char);
$this->setEndLine($endline);
$this->setEncoding($encoding);
$this->datas = array(0 => null);
$this->legend = array();
$this->render = "";
}
public function setFilename($v)
{
if (!is_string($v)) {
throw new CsvInvalidParameterException(sprintf('"%s" is not a valid string.', $v));
}
$this->filename = $v;
}
protected function setHasLegend($hasLegend)
{
$this->hasLegend = $hasLegend;
return $this;
}
public function getHasLegend()
{
return $this->hasLegend;
}
public function setLegend(array $values)
{
$this->setHasLegend(true);
$this->addLine($values, 0);
}
public function addLine(array $values, $key = null)
{
if ($key !== null) {
$this->datas[$key] = $values;
return true;
}
$this->datas[] = $values;
}
public function setEncoding($encoding)
{
$this->encoding = $encoding;
return $this;
}
public function getEncoding()
{
return $this->encoding;
}
public function setDelimiter($v)
{
if (!is_string($v)) {
throw new CsvInvalidParameterException(sprintf('"%s" is not a valid string.', $v));
}
$this->delimiter = $v;
}
public function setEndline($v)
{
if (!is_string($v)) {
throw new CsvInvalidParameterException(sprintf('"%s" is not a valid string.', $v));
}
$this->endline = $v;
}
public function setEnclosure($v)
{
if (!is_string($v)) {
throw new CsvInvalidParameterException(sprintf('"%s" is not a valid string.', $v));
}
$this->enclose = $v;
}
public function setEscapeChar($v)
{
if (!is_string($v)) {
throw new CsvInvalidParameterException(sprintf('"%s" is not a valid string.', $v));
}
$this->escape_char = $v;
}
public function getLegend()
{
return $this->legend;
}
public function getDatas()
{
return $this->datas;
}
public function compile()
{
$this->render = "";
if (isset($this->datas[0]) && $this->datas[0] !== null) {
$this->append($this->datasToCsvLine($this->datas[0]));
}
unset($this->datas[0]);
foreach ($this->datas as $k => $v) {
$this->append($this->datasToCsvLine($v));
}
if ($this->encoding !== 'UTF-8') {
$this->render = iconv(
mb_detect_encoding($this->render),
$this->encoding,
$this->render
);
}
return $this->render;
}
public function hasDatas()
{
return count($this->datas) > ($this->getHasLegend() ? 1 : 0);
}
protected function datasToCsvLine($datas)
{
foreach ($datas as $k => $v) {
$v = str_replace('\\', '\\\\', $v);
if ($this->enclose) {
$v = str_replace($this->enclose, '\\'.$this->enclose, $v);
} else {
$v = str_replace($this->delimiter, '\\'.$this->delimiter, $v);
}
$datas[$k] = $this->enclose.$v.$this->enclose;
}
$datas = implode($this->delimiter, $datas);
return $datas;
}
protected function append($line)
{
$this->render.= sprintf("%s%s", $line, $this->endline);
}
public function compileToFile($filename)
{
if (file_exists($filename)) {
unlink($filename);
}
file_put_contents($filename, $this->compile());
}
}

View File

@ -0,0 +1,141 @@
<?php
namespace Deblan\Csv;
use Deblan\Csv\Exception\CsvParserInvalidParameterException;
use Deblan\Csv\Exception\CsvParserException;
class CsvParser
{
private $filename;
private $delimiter;
private $enclosure;
private $escapeChar;
private $hasLegend;
private $datas = array();
private $legend = array();
private $nullValues = array();
public function __construct($filename, $delimiter = ';', $enclosure = '"', $escapeChar = '\\', $hasLegend = false, array $nullValues = array(''))
{
$this->setFilename($filename);
$this->setDelimiter($delimiter);
$this->setEnclosure($enclosure);
$this->setEscapeChar($escapeChar);
$this->setHasLegend($hasLegend);
$this->setNullValues($nullValues);
}
public function setFilename($v)
{
if (!is_string($v)) {
throw new CsvParserInvalidParameterException(sprintf('"%s" is not a valid string.', $v));
}
if (!file_exists($v)) {
throw new CsvParserException(sprintf('"%s" does not exist.', $v));
}
if (!is_readable($v)) {
throw new CsvParserException(sprintf('"%s" is not readable.', $v));
}
$this->filename = $v;
}
public function setDelimiter($v)
{
if (!is_string($v)) {
throw new CsvParserInvalidParameterException(sprintf('"%s" is not a valid string.', $v));
}
$this->delimiter = $v;
}
public function setEnclosure($v)
{
if (!is_string($v)) {
throw new CsvParserInvalidParameterException(sprintf('"%s" is not a valid string.', $v));
}
$this->enclose = $v;
}
public function setEscapeChar($v)
{
if (!is_string($v)) {
throw new CsvParserInvalidParameterException(sprintf('"%s" is not a valid string.', $v));
}
$this->escapeChar = $v;
}
public function setHasLegend($v)
{
if (!is_bool($v)) {
throw new CsvParserInvalidParameterException(sprintf('"%s" is not a valid bool.', $v));
}
$this->hasLegend = $v;
}
public function getLegend()
{
return $this->legend;
}
public function setNullValues(array $v)
{
$this->nullValues = $v;
}
/**
*
* To improve...
*
*/
protected function cleanNullValues($line)
{
return str_replace($this->nullValues, '', $line);
}
public function getDatas()
{
return $this->datas;
}
public function parse()
{
$lines = file($this->filename);
if (empty($lines)) {
return true;
}
if ($this->hasLegend) {
$this->legend = str_getcsv($lines[0], $this->delimiter, $this->enclosure, $this->escapeChar);
unset($lines[0]);
}
foreach ($lines as $l => $line) {
$datas = str_getcsv($this->cleanNullValues($line), $this->delimiter, $this->enclosure, $this->escapeChar);
if ($this->hasLegend) {
foreach ($this->legend as $k => $v) {
$datas[$v] = isset($datas[$k]) ? $datas[$k] : null;
}
}
$this->datas[] = $datas;
}
return true;
}
}

View File

@ -0,0 +1,7 @@
<?php
namespace Deblan\Csv\Exception;
class CsvException extends \Exception
{
}

View File

@ -0,0 +1,7 @@
<?php
namespace Deblan\Csv\Exception;
class CsvInvalidParameterException extends CsvException
{
}

View File

@ -0,0 +1,7 @@
<?php
namespace Deblan\Csv\Exception;
class CsvParserException extends \Exception
{
}

View File

@ -0,0 +1,7 @@
<?php
namespace Deblan\Csv\Exception;
class CsvParserInvalidParameterException extends CsvParserException
{
}