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; } }