it seems I have a problem with the ";" delimiter. Here's my csv file:
First Name;Last Name;Email;Age
Julie;Brown;[email protected];52
Dan;Wong;[email protected];19
Tim;Hortons;[email protected];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;[email protected];52
1 champs à la ligne 3:
Dan;Wong;[email protected];19
1 champs à la ligne 4:
Tim;Hortons;[email protected];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
[email protected]
52
4 champs à la ligne 3:
Dan
Wong
[email protected]
19
4 champs à la ligne 4:
Tim
Hortons
[email protected]
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";
}
}
}