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.
Sja, hoe wordt het bestand gegenereerd?
En zou je niet een zwik meer headers moeten meegeven (evt. Content-Description, ik zou wellicht voor Content-Type application/octet-stream kiezen omdat je dan een download forceert, ook al is het bestandstype bekend/is er een applicatie die deze kan lezen, Content-Transfer-Encoding etc)?
Het lijkt mij echter niet dat op grond van de headers het bestand inhoudelijk wordt aangepast.
Ik zie niet waarom er in het laatste geval niets toegevoegd wordt aan het bestand en in het eerste wel.
Ben je hier geen appels met peren aan het vergelijken? Dit zijn twee verschillende bestandstypen, dus deze worden mogelijk op verschillende manieren opgebouwd, wat opnieuw de vraag doet rijzen, hoe worden deze gegenereerd?
De tekst van het bestand wordt aangemaakt via echo of printinstructies, net zoals men dat zou doen voor een tekst die op het scherm moet verschijnen. Voor het RTF-bestand begint die tekst natuurlijk met
{\rtf1
{\fonttbl{\f0 Calibri;}}
\paperw11906\paperh16838\margl1650\margr1200\margt1300\margb1100\footery560
\margmirror
\pard\qc\fs36{\b Lijst van de leden\par\par}
\trowd\trqc\cellx7020
\pard\qc\fs26 De leden die van adres veranderen, worden verzocht hiervan
\line zo spoedig mogelijk opgave te doen aan de Secretaris,
....
maar dat heeft voor de computer toch geen belang.
Zit er niet gewoon een BOM op je PHP script (dus voor de open < ? p h p)? Die komt dan voor de output die je met print() genereert. Bij een fwrite() schrijf je enkel de data weg die je bedoelt.
Bij een CSV zal dit niet zo'n probleem geven (toch een tekst formaat); bij een RTF (blijkbaar) wel.
Loop dus alle PHP files langs die je gebruikt (dus ook via-via-via include) en verwijder evt. BOM-ers.
Zit er niet gewoon een BOM op je PHP script (dus voor de open < ? p h p)? Die komt dan voor de output die je met print() genereert.
Is dat zo? Je serveert toch niet het rauwe PHP-bestand? Wordt, als het PHP-bestand een BOM heeft, deze overgenomen naar de output die de webserver produceert? o_O
[quote="Rob Doemaarwat op 09/06/2020 20:19:06"]Zit er niet gewoon een BOM op je PHP script (dus voor de open < ? p h p)? Die komt dan voor de output die je met print() genereert.
Is dat zo? ...
[/quote]
Ja, alles wat niet tussen php tags staat wordt gewoon naar de browser gestuurd (mits er nog geen headers zijn verzonden), dus ook een BOM-character.
Test.php
Hallo allemaal!
<?php
echo 'Hier zijn Bassie en Adriaan.<br><br>';
?>
Allememaggies!
Levert in de browser zoiets op als:
Hallo allemaal!
Hier zijn Bassie en Adriaan.
Allememaggies!
?
Onbekende gebruiker
10-06-2020 09:01
gewijzigd op 10-06-2020 09:09
Ik heb een soortgelijk probleem gehad. Als als je een bestand voor Office maakt dan verwacht Office een bestand met een BOM, maar de browser haalde de BOM weg bij het downloaden. In mijn geval kon ik het aan de praat krijgen door bij downloads 2x een BOM te versturen.
Er zijn verschillen in versies van Office, en misschien ook wel in browsers.
Welke versie van Office en welke browser gebruik je?
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, alhoewel er een charset=latin1 gegeven is. De conversie naar latin1 wordt correct uitgevoerd voor de verdere gegevens.
Het enige verschil tussen beide scripts is dat bij het csv script ALLE output uit een database gehaald wordt en bij het rtf script wordt gestart met een kop die als constante toegekend wordt aan een variabele. Als de broncode van het script in utf-8 is, is die tekst natuurlijk ook in utf-8. Maar omzetten van het script naar latin1 verandert niets aan de zaak en ook alles in utf-8 zetten (script en output van de database) verandert niets.
Ook een andere functie gebruiken dan echo, zoals printf, verandert niets.
Dit hangt duidelijk niet af van de browser. Testen met Chromium en Firefox geven hetzelfde resultaat. Er wordt trouwens geen iota getoond in de browser.
(Open) Office toont de broncode. Office beschouwt het bestand dus als een gewoon tekstbestand. MS Word kan er niets mee aanvangen. Het stelt voor om het bestand te openen met "Openen en herstellen", maar ook dat levert niets op.
Wat voor eisen stellen deze aan formaat, character encoding et cetera.
Het heeft geen zin om dingen aan de PHP-kant aan te passen zolang dit niet voldoet aan het formaat dat het verwerkende programma verwacht. Ga dus na wat voor standaarden werken/of in welke programma's je deze bestanden wilt gebruiken en aan welke eisen dat moet voldoen, en giet je bestanden vervolgens in dat formaat. Begin bij het einde.