Kun siirryimme käyttämään nginx web-palvelinta Ubuntu Server käyttöjärjestelmällä, niin emme enään pystyneet tuomaan sovelluksemme tekemiä tuonti-tiedostoja kolmannen osapuolen laskutusohjelmaamme. Aiemmin sovelluksemme pyöri Windows Serverin Apachella, ja tällöin tiedostojen tuonti kolmannen osapuolen laskutusohjelmaamme toimi.
Tiedoston sisältö näyttää juuri samalta nyt ja ennen, mutta laskutusohjelma ei hyväksy tuonti tiedostoa. Vaan antaa virheeksi: "Input past end of file".
Kuitenkin laskutusohjelman saa hyväksymään tuonti-tiedoston, jos tuontitiedoston avaa wordpadissa ja sen uudelleen tallentaa täysin samalla sisällöllä, sen jälkeen tiedoston tuonti laskutusohjelmaan onnistuu oikein. Ylimääränen tallennus vaihe ei kumminkaan ole hyväksyttyä, koska tuonti-tiedostoja tuodaan laskutusohjelmaan useita päivittäin.
Sovelluksessamme tuonti tiedosto muodostetaan seuraavasti:
header('Content-type: text/plain'); header('Content-Disposition: attachment; charset=ISO-8859-1; filename="' . $filename . '"'); $utf8Data = $csvComposer->getComposedBillsData(); echo mb_convert_encoding(rtrim($utf8Data), "ISO-8859-1", "UTF-8");
Alkuperäinen $csvComposerin data on UTF-8 merkistöllä ja laskutusohjelmaa varten se tulee muuttaa eri muotoon ja kyseinen ISO-8859-1 näytti ainakin aiemmin toimivan. Olen kokeillut laittaa echon loppuun "\r" / "\r\n" tai PHP_EOL, mutta ei vaikutusta. Ilman rtrim:iäkin on kokeiltu. Olen myös kokeillut tallentaa tiedoston aluksi palvelimelle ja sitten uudelleen lukea sen ja lähettää, mutta ei vaikutusta. Content-type: text/csv on myös kokeiltu.
Olisiko ideoita mitä kokeilla? Tällä hetkellä "paras" idea, olisi lähettää luotu tiedosto aluksi windows palvelimelle ja käyttää redirectiä sen lataamiseen sieltä, joka menisi aika kikkailuksi ja ei välttämättä edes toimisi. Onhan se mahdollista että vika on myös merkistössä tai jossain muussa. Mutta edelleenkin pelkkä uudelleen tallennus wordpadilla windowsissa aina korjaa ongelman.
Ongelma syy on varmaan helppo selvittää kun tutkit mitä eroa tiedostolla ja uudelleen wordpadilla tallennetulla tiedostolla oikeastaan on.
Voin toki arvata että ongelma on jompi kumpi seuraavista:
- Käytetty rivivaihtomerkki
- Tiedoston alusta puuttuva tai siinä oleva BOM-merkki
Grez kirjoitti:
Ongelma syy on varmaan helppo selvittää kun tutkit mitä eroa tiedostolla ja uudelleen wordpadilla tallennetulla tiedostolla oikeastaan on.
Voin toki arvata että ongelma on jompi kumpi seuraavista:
- Käytetty rivivaihtomerkki
- Tiedoston alusta puuttuva tai siinä oleva BOM-merkki
Joo siihenhän sitä hääty mennä, että asentelee hex-editorin, koitin aluks lähettää sähköpostilla alkuperäisen/wordpadillä tallennetun tiedoston windows koneelta omalle macille ja vertailla, mut eihän se onnistunut :) "Files are identical" tuli. Piti sit windows koneelle asennella hex editori, niin huomas että 0D (Carriage return) puuttuu heti tiedoston ensimmäisen rivin lopusta, ja jokaisesta rivistä sen jälkeen. Käytin riveissä PHP_EOL, joten sen käyttäminen ei tässä tapauksessa ollut hyvä idea. Muutin riviloput "\r\n" ja tämän jälkeen tiedoston tuonti onnistui ongelmitta. Eli ei kannate luottaa ainakaan PHP_EOL:n toimivuuteen joka tapauksessa :) Kiitoksia vinkeistä.
Synomi kirjoitti:
Eli ei kannate luottaa ainakaan PHP_EOL:n toimivuuteen joka tapauksessa :) Kiitoksia vinkeistä.
Ei kannata käyttää sitä väärin.
The Alchemist kirjoitti:
Synomi kirjoitti:
Eli ei kannate luottaa ainakaan PHP_EOL:n toimivuuteen joka tapauksessa :) Kiitoksia vinkeistä.
Ei kannata käyttää sitä väärin.
Olisi mahdollista, että PHP tunnistaisi käyttäjän USER-AGENT:in avulla millä käyttöjärjestelmällä kävijä sivustoa selaa ja palauttaisi sopivan rivilopetuksen. Jos tällä sivustolla vois ignoorata käyttäjän, niin painasin heti kohdallasi "Ignore"-painiketta. Niin hyödyllisiä nuo kommenttisi ovat :)
No mutta oikeassahan Alchemist oli, vaikka asian ilmaisikin nuivasti.
PHP_EOL tarkoitus on kertoa, mikä ajoalustalla käytettävä rivinvaihtomerkki/-merkkiyhdistelmä on. Eli minunkin ymmärtääkseni se on toiminut tässäkin yhteydessä juuri kuten pitääkin.
Synomi kirjoitti:
Olisi mahdollista, että PHP tunnistaisi käyttäjän USER-AGENT:in avulla millä käyttöjärjestelmällä kävijä sivustoa selaa ja palauttaisi sopivan rivilopetuksen.
Kuten todettiin, PHP_EOL ei ole tuohon tarkoitukseen vaan koskee nimenomaan suoritusympäristöä. Sitä paitsi käyttöjärjestelmä ei yleensä vaikuta rivinvaihtomerkin valintaan, koska ei ole mitään käyttöjärjestelmän funktioita juuri rivinvaihtojen tunnistamiseen vaan ohjelmat itse etsivät tiedostoista rivinvaihdot.
Useat ohjelmat tunnistavat tekstitiedostosta erilaiset rivinvaihtomerkit. Jotkin ohjelmat ovat kuitenkin rajoittuneita (mm. Windowsin Muistio ainakin ennen). On myös tiedostomuotoja, joissa kuuluu käyttää tietynlaista rivinvaihtoa: esimerkiksi CSV-tiedostoissa on tapana käyttää DOS-tyylistä rivinvaihtoa (CRLF), vaikka mm. LibreOffice osaa lukea CSV-tiedostoja myös Unix-rivinvaihdoilla (LF).
Jos ei erikseen ole tiedossa muuta, nykyään voi yleensä aloittaa Unix-rivinvaihdosta ja muuttaa käytäntöä myöhemmin, jos käy ilmi, että jokin tärkeä ohjelma ei tue tätä. Kannattaa välttää tilanteesta (kuten UA-otsikosta) riippuvia temppuja, jos suinkin on olemassa ratkaisu, joka toimii joka tilanteessa.
Mainittakoon vielä, että UA-otsikkotieto on epäluotettava eikä välttämättä edes kerro käyttöjärjestelmää.
Jep tulihan se selväksi, että se toimii vaan käyttöympäristön mukaisesti eikä käyttäjän selain tai käyttöjärjestelmä siihen vaikuta. Ongelmaa etsiessä ei vaan huomioinut heti, että PHP_EOL ei olisi riittävä. Eipä ole tarvetta nyt tehdä UA:han liittyvää tarkistusta, kun käyttäjillä on käytössä sama käyttöjärjestelmä ja sovellus.
Heitin UA:han liittyvän tarkistuksen vaan vastalauseena Alchemistille, ja sen pointti oli että suurinman osan ohjelmoinnista oppii kokeilemalla, eikä kaikkea lueta dokumentaatiosta. Se että PHP_EOL ei käy tarkoitukseen, oli jo hyvin selvillä ennen hänen kommenttiaan.
Aihe on jo aika vanha, joten et voi enää vastata siihen.