keboola / php-csv

CSV reader/writer
MIT License
135 stars 35 forks source link

cannot properly parse tsv #35

Open ondrejhlavacek opened 6 years ago

ondrejhlavacek commented 6 years ago

php-csv says this file has only one line

image

demonstrated in #34

ondrejhlavacek commented 6 years ago

vrtám se v tom dál, vypadá to, že za to může enclosure chr(0): https://github.com/keboola/php-csv/blob/d80c54000a2dd7fd3e0acf97ddf69322dbd06645/src/CsvReader.php#L153

image

null char enclosure

        $fh = fopen($filenameFrom, "r");
        while ($parsed = fgetcsv($fh, null, "\t", chr(0))) {
            var_dump($parsed);
        }
array(6) {
  [0]=>
  string(3) "218"
  [1]=>
  string(1) "0"
  [2]=>
  string(1) " "
  [3]=>
  string(1) " "
  [4]=>
  string(1) " "
  [5]=>
  string(18) "?
219 0                
"
}

no enclosure

        $fh = fopen($filenameFrom, "r");
        while ($parsed = fgetcsv($fh, null, "\t")) {
            var_dump($parsed);
        }
array(6) {
  [0]=>
  string(3) "218"
  [1]=>
  string(1) "0"
  [2]=>
  string(1) " "
  [3]=>
  string(1) " "
  [4]=>
  string(1) " "
  [5]=>
  string(1) " "
}
array(6) {
  [0]=>
  string(3) "219"
  [1]=>
  string(1) "0"
  [2]=>
  string(1) " "
  [3]=>
  string(1) " "
  [4]=>
  string(1) " "
  [5]=>
  string(1) " "
}
ondrejhlavacek commented 6 years ago

když skript rozdělím na fgets a str_getcsv, tak to produkuje podobně divnou chybu

        $fh = fopen($filenameFrom, "r");
        while ($line = fgets($fh)) {
            var_dump($line);
            var_dump(str_getcsv($line, "\t", chr(0)));
        }
        fclose($fh);
array(6) {
  [0]=>
  string(3) "218"
  [1]=>
  string(1) "0"
  [2]=>
  string(1) " "
  [3]=>
  string(1) " "
  [4]=>
  string(1) " "
  [5]=>
  string(3) "?
"
}
string(15) "219 0                
"
array(6) {
  [0]=>
  string(3) "219"
  [1]=>
  string(1) "0"
  [2]=>
  string(1) " "
  [3]=>
  string(1) " "
  [4]=>
  string(1) " "
  [5]=>
  string(3) "
"
}

jsou tam divný ty newliny a otazníky v posledních prvích polí řádků

ondrejhlavacek commented 6 years ago

str_getcsv umí v argumentech použít prázdný stringy, tj. nemusel by se používat chr(0) hack

        $fh = fopen($filenameFrom, "r");
        while ($line = fgets($fh)) {
            var_dump($line);
            var_dump(str_getcsv($line, "\t", "", ""));
        }
        fclose($fh);
string(15) "218 0                
"
array(6) {
  [0]=>
  string(3) "218"
  [1]=>
  string(1) "0"
  [2]=>
  string(1) " "
  [3]=>
  string(1) " "
  [4]=>
  string(1) " "
  [5]=>
  string(1) " "
}
string(15) "219 0                
"
array(6) {
  [0]=>
  string(3) "219"
  [1]=>
  string(1) "0"
  [2]=>
  string(1) " "
  [3]=>
  string(1) " "
  [4]=>
  string(1) " "
  [5]=>
  string(1) " "
}
ondrejhlavacek commented 6 years ago

možná by to celý stálo za report do php bugtrackeru?

Halama commented 6 years ago

jenže fgets použít nejde protože čte po řádcích a v csv můžeš mít newlines libovolně kombinované (cr, cr lf, lf) uvnitř dat. A fgetcsv nebere prázdný string jako enclosure.

jinak tech bůgu je tam hlášených několik, např. https://bugs.php.net/bug.php?id=51496

Halama commented 6 years ago

https://csv.thephpleague.com/9.0/interoperability/rfc4180-field/ tady je to taky linkované a nějak to zkouší fixovat. Ale naše testovací CSV to moc nedalo https://keboola.slack.com/archives/C02C3GZUS/p1518859662000040

Halama commented 6 years ago

V tom testu ale testuješ csv který nemá enclosure ani escape. To nikdy nemůže spolehlivě fungovat.

Halama commented 6 years ago

Pokud tomu nastavím enclosure na " jede to v pohodě.

Halama commented 6 years ago

Chtělo by to větší sample kde to způsobovalo problém.

ondrejhlavacek commented 6 years ago

Tady je celý - https://connection.eu-central-1.keboola.com/admin/projects/154/storage#/file-uploads?q=id:4711176

ondrejhlavacek commented 6 years ago

Zkusím do té konfigurace narvat " jako enclosure, jestli to projde

ondrejhlavacek commented 6 years ago

Jo, prošlo! OMG, se s tím seru celej den :-(

Halama commented 6 years ago

Zaleží ale co pak je v tom CSV dál. Jestli nemá enclousure a najednou se někde v datech " objeví tak se to rozbije. Pokud ale vědí že jsou to např. jenom čísla tak je to cajk.

ondrejhlavacek commented 6 years ago

V současanejch datech to nebylo, takže snad cajk!