Skip to content

Instantly share code, notes, and snippets.

@rseon
Last active May 6, 2021 07:38
Show Gist options
  • Save rseon/7d5da04e6838a2d85271d9fb899f385c to your computer and use it in GitHub Desktop.
Save rseon/7d5da04e6838a2d85271d9fb899f385c to your computer and use it in GitHub Desktop.
Smart way to read and write a CSV file.
<?php
/**
* Create and read CSV file.
*
* @example Create CSV from array :
* $csv = new Csv;
* $csv->setUtf8(true);
* $csv->setHeader(['col_1', 'col_2']);
* $csv->addRow(['val_1_1', 'val_2_1']);
* $csv->addRow(['val_1_2', 'val_2_2']);
* $csv->save('/path/to/file.csv');
* // echo $csv;
*
* @example Read CSV to array :
* $csv = new Csv;
* $csv->open('/path/to/file.csv');
* $datas = $csv->getArray();
*
* @author Definima <[email protected]>
* @link https://definima.com
* @copyright 2018 Definima
*/
class Csv {
private $_delimiter;
private $_enclosure;
private $_utf8 = false;
private $_header = [];
private $_rows = [];
private $_csv = '';
const NEW_LINE = "\n";
const UTF8_BOM = "\xEF\xBB\xBF";
const MIME_TYPE = 'application/vnd.ms-excel';
/**
* Csv constructor.
* @param string $delimiter
* @param string $enclosure
*/
public function __construct($delimiter = ';', $enclosure = '"') {
$this->_delimiter = $delimiter;
$this->_enclosure = $enclosure;
return $this;
}
/**
* Create first line for columns names
* @param array $header
* @return $this
*/
public function setHeader(array $header) {
$this->_header = $header;
return $this;
}
/**
* Get columns names
* @return array
*/
public function getHeader() {
return $this->_header;
}
/**
* Add new row with $cols.
* @param array $cols
* @return $this
*/
public function addRow(array $cols) {
$this->_rows[] = $cols;
return $this;
}
/**
* Add or not UTF-8 BOM
* @param $flag
* @return $this
*/
public function setUtf8($flag) {
$this->_utf8 = $flag;
return $this;
}
/**
* Convert associative array to string
* @return $this
*/
public function convert() {
$length = (-1 * strlen($this->_delimiter));
if($this->_utf8 !== false) {
$this->_csv = self::UTF8_BOM;
}
if($this->_header) {
foreach($this->_header as $colname) {
$this->_csv .= $this->_enclosure . $colname . $this->_enclosure . $this->_delimiter;
}
$this->_csv = substr($this->_csv, 0, $length);
$this->_csv .= self::NEW_LINE;
}
foreach($this->_rows as $line) {
foreach($line as $col) {
$this->_csv .= $this->_enclosure . $col . $this->_enclosure . $this->_delimiter;
}
$this->_csv = substr($this->_csv, 0, $length);
$this->_csv .= self::NEW_LINE;
}
unset($length);
return $this;
}
/**
* Get CSV to string
* @return string
*/
public function getString() {
$this->convert();
return $this->_csv;
}
/**
* Get CSV to associative array
* @return array
*/
public function getArray() {
$lines = [];
if(is_array($this->_header) && is_array($this->_rows)) {
foreach($this->_rows as $i => $line) {
foreach($line as $col => $value) {
$key = isset($this->_header[$col]) ? $this->_header[$col] : $col;
$lines[$i][$key] = trim($value);
unset($key);
}
}
return $lines;
}
return $this->_rows;
}
/**
* To display CSV.
* @return string
*/
public function __toString() {
return $this->getString();
}
/**
* Save CSV into file.
* @param $file
* @param string $mode
* @return bool|int
*/
public function save($file, $mode = 'w') {
$length = 0;
if($file && ($handle = fopen($file, $mode)) !== false) {
$length = fwrite($handle, $this->getString());
fclose($handle);
}
return $length;
}
/**
* Open and convert content of CSV to associative array
* @param $file
* @param bool $has_header
* @return $this
*/
public function open($file, $has_header = true) {
$this->_rows = [];
if(($handle = fopen($file, 'r')) !== false) {
$i = 0;
while(($data = fgetcsv($handle, 0, ';')) !== false) {
if($has_header && $i++ == 0) {
$this->setHeader($data);
continue;
}
$this->_rows[] = array_map('trim', $data);
}
fclose($handle);
}
unset($handle);
return $this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment