De archivos PHP ilegible después de ser descargado
-
27-09-2019 - |
Pregunta
Hola tengo un script que crea un archivo y lo almacena en el servidor. El archivo está codificado en UTF-8 y es un tipo de archivo XML para el software CMAP.
Si i abrir el archivo directamente desde el servidor entonces no hay problema y el archivo se puede leer.
Me estoy forzando una descarga de este archivo cuando un usuario va a una URL específica. Después de dicha descarga, el archivo no se puede leer por el software CMAP. Tengo que ir a mi editor de texto (Notepad ++) y cambiar la codificación de UTF-8 a UTF-8 sin BOM.
¿Estoy enviando las cabeceras equivocadas? Se php haciendo algo para el archivo cuando se está descargando él?
Cualquier consejo sobre esto sería muy apreciada.
Saludos De Drew
editar
Lo sentimos, hay una gran cantidad de código implicado en un par de diferentes clases. He incluido el código que estoy utilizando para enviar el archivo al navegador:
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");
}
Si se requiere el código que genera el XML (utilizando XMLWriter) i Publicación de que también.
editar
Como solicitó aquí está el código donde se está produciendo el xml - es en otra clase:
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());
}
Solución
Usted debe agregar dos cosas importantes:
- Comprueba si la cabecera HTTP no se ha enviado todavía, y
- asegurarse de que no hay más salida que la de
readfile
.
Así que trate esto:
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;
}