为什么这个PHP发送文件会损坏数据?

为什么这个PHP发送文件会损坏数据?,php,zend-framework,Php,Zend Framework,我有一个简单的项目,它在服务器上存储一个文件。当有人想要下载文件时,我必须通过一个中间控制器(Zend framework)来传递请求,以对文件提供一些保护 当有人请求该文件时,该文件将下载到客户端浏览器,然而,在我的所有测试中,该文件总是会被损坏(尽管它的大小与字节大小相符)。有人能告诉我我做错了什么吗 public function downloadAction() { $this->_helper->layout->disableLayout(); $t

我有一个简单的项目,它在服务器上存储一个文件。当有人想要下载文件时,我必须通过一个中间控制器(Zend framework)来传递请求,以对文件提供一些保护

当有人请求该文件时,该文件将下载到客户端浏览器,然而,在我的所有测试中,该文件总是会被损坏(尽管它的大小与字节大小相符)。有人能告诉我我做错了什么吗

 public function downloadAction() {
    $this->_helper->layout->disableLayout();
    $this->_helper->viewRenderer->setNoRender(true);

    $files = new Application_Model_DbTable_Files();

    $file = $files->getFileForDownload($this->_getParam('id'), Zend_Auth::getInstance()->getIdentity()->id);

    $config = Zend_Registry::get('config');

    $this->_helper->layout->disableLayout();
    $this->_helper->viewRenderer->setNoRender();


    if (file_exists($config['mindful']['path'] . $file)) {
        $this->getResponse()->setHeader('Content-type', 'application/octet-stream');
        $this->getResponse()->setHeader('Content-Disposition', 'inline; filename=' . basename($file), false);
        $this->getResponse()->setBody(readfile($config['mindful']['path'] . $file));
    }
}
正如您所看到的,我已经用Zend方法和标准PHP进行了尝试。这两个都给了我相同的结果

提前感谢您的帮助


Rick

在许多框架上,可能导致文件下载出现问题的一件事是丢失,这些问题通常发生在PHP的?>之后,并最终发送意外的\n数据。这些\n在您发送HTML时完全无害,但会损坏任何其他文件

PHP脚本不需要您关闭PHP标记,不关闭它始终是一种很好的做法。例外情况是当您使用PHP模板(在视图中)时,您显然必须关闭它们

  • 删除您正在访问的控制器(包括控制器)使用的所有型号和组件的?>标签

  • 请确保没有输入,否则会导致许多框架上的文件下载出现问题的一件事是丢失,这些问题通常发生在PHP的?>之后,并最终发送意外的\n数据。这些\n在您发送HTML时完全无害,但会损坏任何其他文件

    PHP脚本不需要您关闭PHP标记,不关闭它始终是一种很好的做法。例外情况是当您使用PHP模板(在视图中)时,您显然必须关闭它们

    • 删除您正在访问的控制器(包括控制器)使用的所有型号和组件的?>标签

    • 确保在读取文件不返回文件内容之前没有输入,它会立即输出文件内容。返回值是字节数,因此当前将其附加到响应正文中。这可能是导致腐败的原因

      您可以继续使用
      readfile
      ,方法是先发送标题,然后直接调用它:

      $this->getResponse()->setHeader('Content-type', 'application/octet-stream');
      $this->getResponse()->setHeader('Content-Disposition', 'inline; filename=' . basename($file), false);
      $this->getResponse()->sendHeaders();
      
      readfile($config['mindful']['path'] . $file);
      
      或者,如果文件非常小,您可以坚持当前的方法,使用
      file\u get\u contents

      $this->getResponse()->setBody(file_get_contents($config['mindful']['path'] . $file));
      
      请注意,这两种方法都不提供任何缓存(例如,如果从标头开始修改,则进行处理)


      你也可以考虑使用X-sEdfile,它对内存更友好,并且可以为你处理缓存头。

      <代码>代码> RealFrase>代码>不返回文件内容,它立即输出。返回值是字节数,因此当前将其附加到响应正文中。这可能是导致腐败的原因

      您可以继续使用
      readfile
      ,方法是先发送标题,然后直接调用它:

      $this->getResponse()->setHeader('Content-type', 'application/octet-stream');
      $this->getResponse()->setHeader('Content-Disposition', 'inline; filename=' . basename($file), false);
      $this->getResponse()->sendHeaders();
      
      readfile($config['mindful']['path'] . $file);
      
      或者,如果文件非常小,您可以坚持当前的方法,使用
      file\u get\u contents

      $this->getResponse()->setBody(file_get_contents($config['mindful']['path'] . $file));
      
      请注意,这两种方法都不提供任何缓存(例如,如果从标头开始修改,则进行处理)


      你也可以考虑使用X-sEdfile,它对内存更友好,并且会为你处理缓存头。

      嗯,可能是字符编码问题。你如何确定文件已损坏?它们是什么类型的文件?如何损坏?您是否对这两个文件进行了字节比较?嗯,可能是字符编码问题?您如何确定文件已损坏?它们是什么类型的文件?如何损坏?你对这两个文件做过字节比较吗?文件内容绝对是最好的选择。这不是解决方案,但确实克服了我遇到的发送限制问题。文件内容绝对是解决方法。这不是解决方案,但确实克服了我遇到的发送限制问题。搞定了!在我钉上它之前,它是一些空白!在我的面前是一片空白