| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- <?php
- /**
- * Classe simpleCSV
- *
- * Cette classe permet de manipuler des fichiers CSV, notamment pour les importer
- * et les exporter sous forme de tableaux associatifs.
- */
- class simpleCSV
- {
- /**
- * Délimiteur utilisé dans le fichier CSV.
- * @var string
- */
- private $_delimiter;
- /**
- * Caractère d'encadrement utilisé dans le fichier CSV.
- * @var string
- */
- private $_enclosure;
- /**
- * Caractère de saut de ligne utilisé dans le fichier CSV.
- * @var string
- */
- private $_linebreak;
- /**
- * Contenu du fichier CSV.
- * @var string
- */
- private $_csv = '';
- /**
- * Importe un fichier CSV ou une chaîne CSV en tableau associatif.
- *
- * @param string $filename_or_data Chemin du fichier ou contenu CSV.
- * @param bool $is_data Indique si l'entrée est une chaîne CSV (true) ou un fichier (false).
- * @param string $delimiter Délimiteur à utiliser (par défaut : auto).
- * @param string $enclosure Caractère d'encadrement à utiliser (par défaut : auto).
- * @param string $linebreak Caractère de saut de ligne à utiliser (par défaut : auto).
- * @return array Tableau associatif représentant le contenu du CSV.
- */
- public static function import($filename_or_data, $is_data = false, $delimiter = 'auto', $enclosure = 'auto', $linebreak = 'auto')
- {
- $csv = new static($delimiter, $enclosure, $linebreak);
- return $csv->toArray($filename_or_data, $is_data);
- }
- /**
- * Exporte un tableau associatif en chaîne CSV.
- *
- * @param array $items Tableau associatif à exporter.
- * @param string $delimiter Délimiteur à utiliser (par défaut : ,).
- * @param string $enclosure Caractère d'encadrement à utiliser (par défaut : ").
- * @param string $linebreak Caractère de saut de ligne à utiliser (par défaut : \r\n).
- * @return string Chaîne CSV générée.
- */
- public static function export($items, $delimiter = ',', $enclosure = '"', $linebreak = "\r\n")
- {
- $csv = new static($delimiter, $enclosure, $linebreak);
- return $csv->fromArray($items);
- }
- /**
- * Constructeur de la classe simpleCSV.
- *
- * @param string $delimiter Délimiteur à utiliser (par défaut : auto).
- * @param string $enclosure Caractère d'encadrement à utiliser (par défaut : auto).
- * @param string $linebreak Caractère de saut de ligne à utiliser (par défaut : auto).
- */
- public function __construct($delimiter = 'auto', $enclosure = 'auto', $linebreak = 'auto')
- {
- $this->_delimiter = $delimiter;
- $this->_enclosure = $enclosure;
- $this->_linebreak = $linebreak;
- }
- /**
- * Définit ou détecte automatiquement le délimiteur utilisé dans le CSV.
- *
- * @param string|bool $set Délimiteur à définir ou false pour détecter automatiquement.
- * @return string Délimiteur utilisé.
- */
- public function delimiter($set = false)
- {
- if ($set !== false) {
- return $this->_delimiter = $set;
- }
- if ($this->_delimiter === 'auto') {
- // detect delimiter
- if (strpos($this->_csv, $this->_enclosure . ',') !== false) {
- $this->_delimiter = ',';
- } else if (strpos($this->_csv, $this->_enclosure . "\t") !== false) {
- $this->_delimiter = "\t";
- } else if (strpos($this->_csv, $this->_enclosure . ';') !== false) {
- $this->_delimiter = ';';
- } else if (strpos($this->_csv, ',') !== false) {
- $this->_delimiter = ',';
- } else if (strpos($this->_csv, "\t") !== false) {
- $this->_delimiter = "\t";
- } else if (strpos($this->_csv, ';') !== false) {
- $this->_delimiter = ';';
- } else {
- $this->_delimiter = ',';
- }
- }
- return $this->_delimiter;
- }
- /**
- * Définit ou détecte automatiquement le caractère d'encadrement utilisé dans le CSV.
- *
- * @param string|bool $set Caractère d'encadrement à définir ou false pour détecter automatiquement.
- * @return string Caractère d'encadrement utilisé.
- */
- public function enclosure($set = false)
- {
- if ($set !== false) {
- return $this->_enclosure = $set;
- }
- if ($this->_enclosure === 'auto') {
- // detect quot
- if (strpos($this->_csv, '"') !== false) {
- $this->_enclosure = '"';
- } else if (strpos($this->_csv, "'") !== false) {
- $this->_enclosure = "'";
- } else {
- $this->_enclosure = '"';
- }
- }
- return $this->_enclosure;
- }
- /**
- * Définit ou détecte automatiquement le caractère de saut de ligne utilisé dans le CSV.
- *
- * @param string|bool $set Caractère de saut de ligne à définir ou false pour détecter automatiquement.
- * @return string Caractère de saut de ligne utilisé.
- */
- public function linebreak($set = false)
- {
- if ($set !== false) {
- return $this->_linebreak = $set;
- }
- if ($this->_linebreak === 'auto') {
- if (strpos($this->_csv, "\r\n") !== false) {
- $this->_linebreak = "\r\n";
- } else if (strpos($this->_csv, "\n") !== false) {
- $this->_linebreak = "\n";
- } else if (strpos($this->_csv, "\r") !== false) {
- $this->_linebreak = "\r";
- } else {
- $this->_linebreak = "\r\n";
- }
- }
- return $this->_linebreak;
- }
- /**
- * Convertit un fichier ou une chaîne CSV en tableau associatif.
- *
- * @param string $filename Chemin du fichier ou contenu CSV.
- * @param bool $is_csv_content Indique si l'entrée est une chaîne CSV (true) ou un fichier (false).
- * @return array Tableau associatif représentant le contenu du CSV.
- */
- public function toArray($filename, $is_csv_content = false)
- {
- $this->_csv = $is_csv_content ? $filename : file_get_contents($filename);
- $CSV_LINEBREAK = $this->linebreak();
- $CSV_ENCLOSURE = $this->enclosure();
- $CSV_DELIMITER = $this->delimiter();
- $r = array();
- $cnt = strlen($this->_csv);
- $esc = false;
- $i = $k = $n = 0;
- $r[$k][$n] = '';
- while ($i < $cnt) {
- $ch = $this->_csv[$i];
- $chch = ($i < $cnt - 1) ? $ch . $this->_csv[$i + 1] : $ch;
- if ($ch === $CSV_LINEBREAK) {
- if ($esc) {
- $r[$k][$n] .= $ch;
- } else {
- $k++;
- $n = 0;
- $esc = false;
- $r[$k][$n] = '';
- }
- } else if ($chch === $CSV_LINEBREAK) {
- if ($esc) {
- $r[$k][$n] .= $chch;
- } else {
- $k++;
- $n = 0;
- $esc = false;
- $r[$k][$n] = '';
- }
- $i++;
- } else if ($ch === $CSV_DELIMITER) {
- if ($esc) {
- $r[$k][$n] .= $ch;
- } else {
- $n++;
- $r[$k][$n] = '';
- $esc = false;
- }
- } else if ($chch === $CSV_ENCLOSURE . $CSV_ENCLOSURE && $esc) {
- $r[$k][$n] .= $CSV_ENCLOSURE;
- $i++;
- } elseif ($ch === $CSV_ENCLOSURE) {
- $esc = !$esc;
- } else {
- $r[$k][$n] .= $ch;
- }
- $i++;
- }
- return $r;
- }
- /**
- * Convertit un tableau associatif en chaîne CSV.
- *
- * @param array $items Tableau associatif à convertir.
- * @return string Chaîne CSV générée.
- */
- public function fromArray($items)
- {
- if (!is_array($items)) {
- trigger_error('CSV::export array required', E_USER_WARNING);
- return false;
- }
- $CSV_DELIMITER = $this->delimiter();
- $CSV_ENCLOSURE = $this->enclosure();
- $CSV_LINEBREAK = $this->linebreak();
- $result = '';
- foreach ($items as $i) {
- $line = '';
- foreach ($i as $v) {
- if (strpos($v, $CSV_ENCLOSURE) !== false) {
- $v = str_replace($CSV_ENCLOSURE, $CSV_ENCLOSURE . $CSV_ENCLOSURE, $v);
- }
- if ((strpos($v, $CSV_DELIMITER) !== false) || (strpos($v, $CSV_ENCLOSURE) !== false) || (strpos($v, $CSV_LINEBREAK) !== false)) {
- $v = $CSV_ENCLOSURE . $v . $CSV_ENCLOSURE;
- }
- $line .= $line ? $CSV_DELIMITER . $v : $v;
- }
- $result .= $result ? $CSV_LINEBREAK . $line : $line;
- }
- return $result;
- }
- }
|