Ik heb 2 scripts waarbij uit een database met gegevens van leden een bestand gemaakt wordt om rechtstreeks te downloaden. Hiervoor wordt beroep gedaan op:
header('Content-disposition: attachment; filename = boekje.rtf;');
ofwel op:
header('Content-disposition: attachment; filename = tblleden.csv');

In het laatste geval loopt alles naar wens. In het eerste geval echter wordt er aan het begin van het bestand een BOM of "Byte order marker" toegevoegd zodat het bestand niet meer herkend wordt als rtf-bestand door MS Word of Libre Office Writer. Ik zie niet waarom er in het laatste geval niets toegevoegd wordt aan het bestand en in het eerste wel. Ik heb al geprobeerd met een tweede header:
header('Content-type:application/rtf; charset=latin1;');
maar niets helpt.

Ik heb voorlopig het probleem opgelost door het rtf-bestand naar een tijdelijk bestand te schrijven via fwrite en dat bestand dan aan te bieden voor download. fwrite genereert geen BOM.

Iemand een idee?
Het is zeer eenvoudig wat het eindproduct moet zijn: zowel csv- als rtf-bestanden zijn zuivere tekstbestanden, juist zoals ook een html- of een xml-bestand
Dan zou ik eens kijken wat gebruikelijk is qua encoding. Ook kun je in RTF zelf een character encoding specificeren en/of Unicode karakters opnemen met \u.

Hoe genereer je deze bestanden trouwens? Doe je dit on-the-fly (het script serveert direct een gegenereerd bestand) of bak je echt een bestand wat je vervolgens gebruikt? Hoe dan ook, eventuele headers in jouw PHP-script worden niet aan het bestand "gekoppeld" en gaan dus verloren. Het lijkt mij handiger dat de bestanden wat dat betreft op zichzelf staan en ofwel een standaard encoding voor dat formaat gebruiken ofwel dat er een (toegestane) encodering staat vermeld in (en wordt toegepast op) de inhoud.

Hubert Christiaen op 10/06/2020 17:19:18
zuivere tekstbestanden


Mja, maar There Ain’t No Such Thing As Plain Text.
Hubert Christiaen op 10/06/2020 11:20:13

Er is geen BOM aanwezig op mijn script.

Ik heb de gegenereerde tekst bekeken in hexadecimaal en de BOM is van de vorm EF BB BF. Dit is de vorm voor een utf-8 bestand,


Dus wel een bom :)
Gebruik een goede tekst editor om uw php bestand om te zetten naar "zonder bom"
In notepad++ karakterset ==> converteer naar utf-8 zonder BOM

Jan

Jan R op 10/06/2020 19:39:01

[quote="Hubert Christiaen op 10/06/2020 11:20:13"]
Er is geen BOM aanwezig op mijn script.

Ik heb de gegenereerde tekst bekeken in hexadecimaal en de BOM is van de vorm EF BB BF. Dit is de vorm voor een utf-8 bestand,

Dat zijn dus 2 verschillende zaken!
De BOM weghalen na het downloaden is vijgen na Pasen. De gewone bezoeker moet een bestand zonder BOM krijgen.

EF BB BF is "de BOM" in UTF8: https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8 . Als je die ziet zit er dus toch een BOM ergens in je code. Wat Jan dus bedoelt is dat je niet de gebruiker het eindproduct met Notepad++ an het knutselen moet sturen, maar dat je *zelf* aan de slag moet om toch "ergens" een BOM van een PHP bestand af te slopen.
Er zit geen BOM bij het begin van mijn script een er zit geen BOM bij het begin van de tekstconstante die het begin van de rtf-code bevat.

Als ik dezelfde code gebruik, maar de outputinstructies vervang door schrijven naar een bestand via fwrite i.p.v. via echo te schrijven naar het "scherm", dan krijg ik een bestand zonder BOM. Het is dus ergens in de keten naar de uitvoer dat er een BOM bijgevoegd wordt als ik rechtstreeks laat downloaden.

De code die gebruikt wordt voor de gegevens uit de database is windows-1252, zonder enige escaping voor accentletters en dat werkt correct (expliciet ingesteld met een mysqli_set_charset() ).

De informatie in de header-functie wordt niet doorgegeven aan het bestand maar zou normaal invloed moeten hebben op de codering waarmee naar het "scherm" geschreven en wordt. Ik heb die header-functie trouwens reeds zeer veel gebruikt om servers die zich niet houden aan de html-instructie voor het opgeven van een charset, toch tot de orde te roepen. Hier wordt er toch iets bijgevoegd dat helemaal niet hoort bij de opgegeven codering.
Heb je Rob zijn link wel gelezen. JE ZIET EEN BOM NIET. Het zijn "verborgen" code/gegevens je dient dus het aangeroepen php-bestand te verbeteren zoals ik schreef in mijn vorig antwoord. Dus niet het resultaat uit de browser maar het script zelf. Mogelijks ook andere ge-include bestanden als die er zijn.
Ik zal het even uitschrijven voor je:

//zo ziet je PHP bestand er uit
EF BB BF <?php

$rtf = '...'; //RTF data (zonder BOM)

file_put_contents($filename,$rtf); //$rtf zoals ie bedoeld is, zonder BOM

print($rtf); //je browser ontvangt nu de $rtf MET DE BOM DIE JE HIERBOVEN VOOR 
             //DE PHP-OPEN-TAG ZIET STAAN
?>

Het is dus "logisch" dat er in de RTF-als-bestand *geen* BOM zit, terwijl je 'm er in de RTF-als-een-download wel bij "krijgt". Dit is dus precies wat jij nu ziet gebeuren, en zou dus ook precies moeten "verklaren" dat je ergens in de kop van je één van je PHP scripts een BOM hebt zitten.
Jan R: "Je ziet een BOM niet"
Je kan een BOM erl zien:
- zeker als je het bestand hexadecimaal bekijkt.
- als je een editor gebruikt die weet wat een BOM is. Dan krijg je een menu-optie die je zegt dat er een BOM aanwezig is en die je eventueel toelaat om die te verwijderen.
- als je editor of tekstverwerker niet weet wat een BOM is, dan wordt die afgedrukt als niet-afdrukbaar tken of als rare tekens. In MS Word ingelezen als "tekst zonder opmaak" krijg je bv. iets als: {\rtf1

Rob Doemaarwat:
Ik gebruik de header-functie. Als je dan ook maar iets voor de openingstag "<..." zet, krijg je een fatale fout met als commentaar "Output already sent before header". Al ooit met die header-functie gewerkt?

Lees a.u.b. aandachtig wat reeds gezegd is vooraleer met simplistische verklaringen te komen.
Hé wijsneus, als je alles zo goed weet, waarom los je het zelf dan niet op?

"Misschien" (hé, ik probeer ook maar te helpen) gebeurt er iets van het volgende:

<?php

header('Weet-veel-wat: Doe-maar-wat');

include('file-met-stiekem-toch-een-BOM.php');

print($rtf);

?>

Header: werkt / geen foutmeldingen
Maar toch een BOM in je output.

Heb je misschien al de moeite genomen om gewoon eens door al je files heen te gaan (met een tooltje hè*, niet met een HEX-editor alle bestanden gaan zitten bekijken) op zoek naar die EF BB BF, in plaats van maar steeds met je voeten te gaan staan stampen, en vol te houden dat *er geen BOM in zit*?

* bijvoorbeeld in Linux:
grep -rlI $'\xEF\xBB\xBF' .
(incl de punt)

Reageren