【问题标题】:PHP File unreadable after being downloadedPHP文件下载后不可读
【发布时间】:2010-04-18 16:40:08
【问题描述】:

您好,我有一个创建文件并将其存储在服务器上的脚本。该文件采用UTF-8编码,是cmap软件的一种xml文件。

如果我直接从服务器打开文件,则没有问题,可以读取文件。

当用户转到特定网址时,我强制下载此文件。下载后,cmap 软件无法读取该文件。我必须进入我的文本编辑器 (notepad++) 并将编码从 UTF-8 更改为 UTF-8 而不使用 BOM。

我是否发送了错误的标头? php在下载文件时是否对文件进行了处理?

对此的任何建议将不胜感激。

干杯 画了

编辑

抱歉,有很多代码涉及到几个不同的类。我已经包含了用于将文件发送到浏览器的代码:

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");
}

如果需要生成 xml(使用 XMLWriter)的代码,我也可以发布。

编辑

这里要求的是生成 xml 的代码 - 它在另一个类中:

        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());
    }

【问题讨论】:

  • 你需要展示一些源代码。
  • 你需要展示更多的源代码。 :) 即创建export.cxl的代码

标签: php encoding header byte-order-mark


【解决方案1】:

你应该添加两个重要的东西:

  1. 测试HTTP头是否还没有发送,并且
  2. 确保输出不超过readfile 之一。

所以试试这个:

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;
}

【讨论】:

  • 非常感谢,成功了!我今天在这个问题上花了大约 4 个小时!我曾尝试检查是否已发送标头,但这不是问题 - 解决了它的是干净的缓冲区。我不知道实际的问题是什么,但我真的很高兴它现在正在工作。您是否建议在发送文件以供下载时始终包含该代码?
  • 你拯救了我的一天!出于某种原因,我的图像将 DL 编码为 UTF-8 并在前面添加了一个选项卡,这一切都解决了!谢谢。
猜你喜欢
  • 1970-01-01
  • 2013-07-02
  • 1970-01-01
  • 2021-12-13
  • 2012-04-17
  • 2012-10-25
  • 2012-09-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多