-1

I have a csv file where fields are separated by semicolons. Inside each field we can have comma (decimal separator for numbers in italy is comma). a sample data is:

15/01/2021;15/01/2021;ADDEBITO SDD;PAGAMENTO NEXI 8000640000030620818186 NEXI S.P.A. CORSO SEMP - ADDE BITO SPESE CARTA DI CREDITO ESTRATTO CONTO DEL : 31/ 12/2020 - UNCRITMMXXX IT500040000004107060966;1.501,2;;Uscita;

I explode this line by semicolon and then build a table row out of it:

while (($line = fgetcsv($f)) !== false) { 
    $row = $line[0];
    $cells = explode(";",$row);
    echo "<tr>";
    foreach ($cells as $cell) {
        echo "<td>";
        echo htmlspecialchars($cell);
        echo "</td>";
        $cur_col_num+=1;
    }
    echo "</tr>\n";

The issue I have is that the string "1.501,2" is echoed as 1.501 loosing the decimals. If the source is "1501.2" this is echoed correctly as "1501.2". How do I keep the decimal if the separator is a comma? I have no control over the content of the csv that is coming from different sources and so I need to handle both situations.

EDIT: after some more tests I realized that actually for any line containg the comma it stops processing the line after the comma (ignoring the following fields). So in the example I never see "Uscita" in its table cell

EDIT 2: this is the output of my code on the browser for this specific line

enter image description here

Barmar
  • 741,623
  • 53
  • 500
  • 612
Lelio Faieta
  • 6,457
  • 7
  • 40
  • 74
  • 1
    CSV values that include the separator (comma) should be in quotes. You may further want to use the built-in CSV functionality in PHP that takes into account. Does this answer your question? [Is there a way to include commas in CSV columns without breaking the formatting?](https://stackoverflow.com/questions/4617935/is-there-a-way-to-include-commas-in-csv-columns-without-breaking-the-formatting) – Markus AO Feb 15 '23 at 16:32
  • Cannot reproduce with the given code. Does it show up in the source code? – brombeer Feb 15 '23 at 16:34
  • How are you setting `$row`? – Barmar Feb 15 '23 at 16:56
  • There's nothing in your code that treats comma specially. – Barmar Feb 15 '23 at 16:57
  • @barmar `while (($line = fgetcsv($f)) !== false) { $row = $line[0];` – Lelio Faieta Feb 15 '23 at 17:32
  • @MarkusAO actually I receive the csv from different sources and want to be able to handle the situation where the comma is not wrapped in quotes. And no, the mentioned question is not answering mine because it is focused on how you build the CSV while my CSV depends on the Home banking tool the user use. Each bank will generate a different CSV and I want to build a flexible tool to load these statements in my application – Lelio Faieta Feb 15 '23 at 17:36
  • @brombeer I added the screenshot of the produced row on the browser. This is produced by this PHP code only – Lelio Faieta Feb 15 '23 at 17:39
  • `fgetcsv()` uses `,` as the field separator by default. You can tell it to use a different separator like `;` with an optional argument. – Barmar Feb 15 '23 at 17:41
  • You're setting `$row` to everything up to the first `,`. – Barmar Feb 15 '23 at 17:42
  • Eh right, so `;` is the separator. In that case, ignore my earlier notes on escaping the comma. Still, use `var_dump` to see what you actually have, and work against that until the array looks right, before trying to lay it out. As @brombeer notes, can't duplicate with the given code. Produces: `15/01/202115/01/2021ADDEBITO SDDPAGAMENTO NEXI 8000640000030620818186 NEXI S.P.A. CORSO SEMP - ADDE BITO SPESE CARTA DI CREDITO ESTRATTO CONTO DEL : 31/ 12/2020 - UNCRITMMXXX IT5000400000041070609661.501,2Uscita` – Markus AO Feb 15 '23 at 17:45
  • Why don't you use `;` as the delimiter? You would get the value "1.501,2" as a separate field in `$line` – Honk der Hase Feb 15 '23 at 18:06

1 Answers1

0

CSV means "comma separated values", so fgetcsv() splits the line at , characters by default. Your file uses ; as the field separators, so you should tell fgetcsv() to use that instead.

Then you don't need to call explode() yourself.

while ($cells = fgetcsv($f, null, ';')) {
    echo "<tr>";
    foreach ($cells as $cell) {
        echo "<td>";
        echo htmlspecialchars($cell);
        echo "</td>";
        $cur_col_num+=1;
    }
    echo "</tr>\n";
}
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
Barmar
  • 741,623
  • 53
  • 500
  • 612