it seems I have a problem with the ";" delimiter. Here's my csv file:
First Name;Last Name;Email;Age
Julie;Brown;julie@example.com;52
Dan;Wong;dan@example.com;19
Tim;Hortons;tim@example.com;27
and my PHP code:
$row = 1;
if (($handle = fopen("upload/".$_FILES['fichier']['name'], "r")) !== FALSE) {
while (($data = fgetcsv($handle, ";")) !== FALSE) {
$num = count($data);
echo "<p> $num champs à la ligne $row: <br /></p>\n";
$row++;
for ($c=0; $c < $num; $c++) {
echo $data[$c] . "<br />\n";
}
}
fclose($handle);
}
and I have this out put:
1 champs à la ligne 1:
First Name;Last Name;Email;Age
1 champs à la ligne 2:
Julie;Brown;julie@example.com;52
1 champs à la ligne 3:
Dan;Wong;dan@example.com;19
1 champs à la ligne 4:
Tim;Hortons;tim@example.com;27
instead of something like this when I use the ',' delimiter
4 champs à la ligne 1:
First Name
Last Name
Email
Age
Besides, I want to know if it is possible to have various delimiters. Because I want to display csv files uploaded by users and I don't want to force them to use one predetermined delimiter.
Thanks
The second parameter is the length, so your fgetcsv should be
fgetcsv($handle, 0, ';');
Resulting in
4 champs à la ligne 1:
First Name
Last Name
Email
Age
4 champs à la ligne 2:
Julie
Brown
julie@example.com
52
4 champs à la ligne 3:
Dan
Wong
dan@example.com
19
4 champs à la ligne 4:
Tim
Hortons
tim@example.com
27
As for your second question on variable delimiters. By far the easiest method would allow the user to define which delimiter to use on the upload form, possibly using a select element of acceptable delimiters and then use it when reading the csv.
For Example
function filter_delimiter($v) {
return in_array($v, [',', ';'], true) ? $v : null;
}
// validate $_POST['delimiter'];
$delimiter = filter_input(INPUT_POST, 'delimiter', FILTER_CALLBACK, ['options' => 'filter_delimiter']);
if (!$delimiter) {
$delimiter = ';';
// optionally redirect to form error message
}
Alternatively parse the lines to determine the appropriate delimiter.
// use absolute path
$filename = __DIR__ . '/upload/' . $_FILES['fichier']['name'];
if (false !== ($handle = fopen($filename, 'r'))) {
$content = fread($handle, filesize($filename));
fclose($handle);
// count the delimiters
$semiColons = substr_count($content, ';');
$commas = substr_count($content, ',');
// read each row
$rows = str_getcsv($content, "\n");
$rowCount = count($rows);
$delimiter = null;
foreach ($rows as $line => $row) {
// check the delimiters
if (!isset($delimiter)) {
/*
determine if the delimiter total divided by the number
of rows matches the delimiters found on this row
and use it to parse the columns
*/
if ($semiColons > 0 && $semiColons / $rowCount === substr_count($row, ';')) {
$delimiter = ';';
} elseif ($commas > 0 && $commas / $rowCount === substr_count($row, ',')) {
$delimiter = ',';
}
}
// read the columns using the detected delimiter
// otherwise use a default if a delimiter could not be determined
$columns = str_getcsv($row, $delimiter ? : ';');
echo "<p>$rowCount champs à la ligne " . ($line + 1) . "</p>\n";
foreach ($columns as $column) {
echo $column . "<br/>\n";
}
}
}