Skip to content

Instantly share code, notes, and snippets.

@julp
Last active October 2, 2019 17:29
Show Gist options
  • Save julp/5529e8fe125b15774f2887a5ae9a2cbf to your computer and use it in GitHub Desktop.
Save julp/5529e8fe125b15774f2887a5ae9a2cbf to your computer and use it in GitHub Desktop.
[OC] Import de CSV
<?php
# https://openclassrooms.com/forum/sujet/import-de-fichier-csv
const FIELD_SEPARATOR = ',';
# le jeu de caractère de ce script
# TODO: virer le modificateur u des regexp s'il n'est pas en UTF-8
const CHARSET = 'UTF-8';
const PATTERNS = [
'lastName' => '/^(?:votre nom|nom)/i',
'zipcode' => '/^(?:secteur|commune|Dans quelle zone géographique habitez-vous)/ui',
'birthday' => '/^(?:votre date de naissance|Date de naissance|En quelle année êtes-vous née?)/ui',
'gender' => '/^(?:votre sexe|sexe)/i',
'phoneNumber' => '/^(?:votre numéro de téléphone|Téléphone|n° de téléphone)/ui',
'employment' => "/^(?:votre profession|votre métier|profession|métier|secteur d'activité|dans quel(?:\(s\))? secteur(?:\(s\))? d'activité(?:\(s\))? exercez-vous cette activité)/ui",
'email' => '/^(?:votre adresse e-mail|votre adresse mail|votre mail|votre email|e-mail|mail)/i',
'ratings' => '/^appréciation/ui',
'comments' => '/^commentaires?/i',
];
# NOTE: vrai si on ne trouve aucun octet >= 0x80
function is_ascii(string $string): bool {
return !preg_match('/[^\x00-\x7F]/', $string);
}
# NOTE: vrai si on trouve au moins un caractère (valide) codé sur [2;4] octets
function is_utf8(string $string): bool {
return preg_match('~(?:'
. '[\xC2-\xDF][\x80-\xBF]' // non-overlong 2-byte
. '|\xE0[\xA0-\xBF][\x80-\xBF]' // excluding overlongs
. '|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}' // straight 3-byte
. '|\xED[\x80-\x9F][\x80-\xBF]' // excluding surrogates
. '|\xF0[\x90-\xBF][\x80-\xBF]{2}' // planes 1-3
. '|[\xF1-\xF3][\x80-\xBF]{3}' // planes 4-15
. '|\xF4[\x80-\x8F][\x80-\xBF]{2}' // plane 16
. ')~xs', $string);
}
$headers = [];
$identified_charset = NULL;
if(FALSE !== ($handle = fopen(__DIR__ . '/file.csv', 'r'))) {
# recherche d'un BOM
if ("\xEF\xBB\xBF" == fread($handle, 3)) {
$identified_charset = 'UTF-8';
} else {
rewind($handle);
}
# on lit la première ligne pour extraire les entêtes
foreach (fgetcsv($handle, 1000, FIELD_SEPARATOR) as $key => $header) {
if (!$identified_charset && !is_ascii($header)) {
$identified_charset = is_utf8($header) ? 'UTF-8' : 'CP1252';
}
if ($identified_charset) {
$header = iconv($identified_charset, CHARSET, $header);
}
foreach (PATTERNS as $symbol => $pattern) {
if (!in_array($symbol, $headers) && preg_match($pattern, $header)) {
$headers[$key] = $symbol;
break;
}
}
}
if (!$identified_charset) {
throw new Exception("Il n'a pas été possible de déterminer le jeu de caractères du fichier");
}
# on parcourt le restant du CSV (lignes >= 2)
while ($line = fgetcsv($handle, 1000, FIELD_SEPARATOR)) {
$line = array_combine($headers, array_intersect_key($line, $headers)); # on réécrit/réindexe le tableau avec nos clés internes
$line = array_map(function ($v) use($identified_charset) { return iconv($identified_charset, CHARSET, $v); }, $line);
var_dump($line);
}
fclose($handle);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment