forked from deblan/csv
init
This commit is contained in:
parent
98d6b8673e
commit
a0953d1b7a
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
*.swp
|
||||
tags
|
|
@ -1,4 +1,6 @@
|
|||
csv
|
||||
===
|
||||
CSV parser/generator
|
||||
====================
|
||||
|
||||
A simple PHP library to parse and generate CSV files.
|
||||
|
||||
|
||||
|
|
198
src/Deblan/Csv/Csv.php
Normal file
198
src/Deblan/Csv/Csv.php
Normal 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());
|
||||
}
|
||||
}
|
141
src/Deblan/Csv/CsvParser.php
Normal file
141
src/Deblan/Csv/CsvParser.php
Normal 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;
|
||||
}
|
||||
}
|
7
src/Deblan/Csv/Exception/CsvException.php
Normal file
7
src/Deblan/Csv/Exception/CsvException.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Deblan\Csv\Exception;
|
||||
|
||||
class CsvException extends \Exception
|
||||
{
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Deblan\Csv\Exception;
|
||||
|
||||
class CsvInvalidParameterException extends CsvException
|
||||
{
|
||||
}
|
7
src/Deblan/Csv/Exception/CsvParserException.php
Normal file
7
src/Deblan/Csv/Exception/CsvParserException.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Deblan\Csv\Exception;
|
||||
|
||||
class CsvParserException extends \Exception
|
||||
{
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Deblan\Csv\Exception;
|
||||
|
||||
class CsvParserInvalidParameterException extends CsvParserException
|
||||
{
|
||||
}
|
Loading…
Reference in a new issue