File PHP illeggibile dopo essere stato scaricato
-
27-09-2019 - |
Domanda
Ciao ho uno script che crea un file e lo memorizza sul server. Il file è codificato in UTF-8 ed è una sorta di file XML per il software cmap.
Se apro il file direttamente dal server, allora non c'è nessun problema e il file può essere letto.
sto forzando il download di questo file quando un utente passa a un URL specifico. Dopo una tale download, il file è illeggibile dal software CMAP. Devo andare nel mio editor di testo (Notepad ++) e cambiare la codifica da UTF-8 a UTF-8 senza BOM.
I Am inviare le intestazioni sbagliate? È PHP facendo qualcosa per il file quando si sta scaricando vero?
Qualche consiglio su questo sarebbe davvero apprezzato.
Saluti Drew
Modifica
Siamo spiacenti, c'è un sacco di codice coinvolti in un paio di classi diverse. Ho incluso il codice che sto usando per inviare il file al browser:
function exportCMAP()
{
$serializer = new Serializer();
$serializer->serializeCmap();
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=export.cxl");
header("Content-Type: x-cmap/text-xml");
header("Content-Transfer-Encoding: binary");
readfile("temp/export.cxl");
}
Se è necessario il codice che genera il codice XML (utilizzando XMLWriter) posso inserire anche questo.
Modifica
Come richiesto ecco il codice in cui viene prodotto il xml - è in un'altra classe:
function serializeCmap()
{
$storeManager = new StoreManager();
$linkedNodes = $storeManager->getLinkedNodes();
$namespaces = Array();
$writer = new XMLWriter();
$writer->openMemory();
$writer->setIndent(4);
$writer->startDocument('1.0', 'utf-8');
$writer->startElement('cmap');
$writer->writeAttribute('xmlns', 'http://cmap.ihmc.us/xml/cmap/');
$writer->writeAttribute('dc', 'http://purl.org/dc/elements/1.1/');
$writer->startElement('res-meta');
$writer->writeElement("dc:title", "Full schema for Cmap");
$writer->writeElement("dc:description", "Description Goes Here");
$writer->endElement();
$writer->startElement('map');
$writer->startElement('concept-list');
foreach($linkedNodes['nodes'] as $node=>$id) {
$writer->startElement('concept');
$writer->writeAttribute("id", $id);
$writer->writeAttribute("label", $node);
$writer->endElement();
}
$writer->endElement();
$writer->startElement('linking-phrase-list');
foreach($linkedNodes['phrases'] as $phrase=>$id) {
$writer->startElement('linking-phrase');
$writer->writeAttribute("id", $id);
$writer->writeAttribute("label", $phrase);
$writer->endElement();
}
$writer->endElement();
$writer->startElement('connection-list');
foreach($linkedNodes['connections'] as $key=>$val) {
$writer->startElement('connection');
$writer->writeAttribute("from-id", $val['from']);
$writer->writeAttribute("to-id", $val['phrase']);
$writer->endElement();
$writer->startElement('connection');
$writer->writeAttribute("from-id", $val['phrase']);
$writer->writeAttribute("to-id", $val['to']);
$writer->endElement();
}
$writer->endElement();
$writer->endElement();
$writer->endElement();
$writer->endDocument();
file_put_contents("temp/export.cxl",$writer->outputMemory());
}
Soluzione
Si dovrebbe aggiungere due cose importanti:
- Prova se l'header HTTP non è stato ancora inviato, e
- garantire che non v'è alcuna uscita più di quella di
readfile
.
Quindi, provate questo:
function exportCMAP() {
if (headers_sent()) {
// HTTP header has already been sent
return false;
}
// clean buffer(s)
while (ob_get_level() > 0) {
ob_end_clean();
}
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=export.cxl");
header("Content-Type: x-cmap/text-xml");
header("Content-Transfer-Encoding: binary");
readfile("temp/export.cxl");
// avoid any further output
exit;
}