php symfony 中 setContent() 后 ZipArchive 损坏
在 symfony 中发送包含任何类型文件的 zip 存档时,我有一个非常奇怪的行为。 问题是我从浏览器下载的 zip 文件在文件开头包含一个额外的“位”。
这是我的代码:
$tmpFileName = tempnam("/tmp", "xb_");
$zip = new ZipArchive();
$zip->open($tmpFileName, ZipArchive::CREATE);
$zip->addFile('[directory_inside_webspace]/test.pdf', 'myTest.pdf');
$zip->close();
$this->getResponse()->clearHttpHeaders();
$this->getResponse()->setContent(file_get_contents($tmpFileName));
$this->getResponse()->setHttpHeader('Content-Type', 'application/zip');
$this->getResponse()->setHttpHeader('Content-Disposition', 'attachment; filename=archive.zip');
return sfView::NONE;
现在奇怪的是。 /tmp 下的临时 zip 文件就可以了。我可以毫无问题地提取它。 但浏览器发送给我的文件已损坏。当我在十六进制编辑器中打开它们时,前几个字节如下所示:
working file: 50 4B 03 04 14 00 00
corrupt file: 0A 50 4B 03 04 14 00 00
当我从损坏的文件中删除附加的“0A”时,我可以毫无问题地打开它。 现在它与 /tmp 中创建的 tmp 文件完全相同。
以前有人有过这样的行为吗?我被这个问题困扰了超过 4 天,但找不到错误。 我在另一个 symfony 模块中使用完全相同的代码,并且它在那里工作。有什么想法吗?
-----更新------
该问题与 zipArchive 或 setContent 无关。 我在函数的开头有一个查询。
$bill = Doctrine::getTable('Bill')->find($request->getParameter('id'));
在我的学说模型的“Bill.class.php”类中,我之前有一个空行,
<?php
因此当实例化 Bill 类时,新行将打印到屏幕上。
我只是想知道为什么 php 在将 zip 存档发送到浏览器时不给出“标头已发送”之类的错误消息。
I have a real strange behavior when sending a zip archive containing a any type of file in symfony.
The problem is that the zip file, that I download from the browser contains an extra 'bit' at the beginning of the file.
Here's my code:
$tmpFileName = tempnam("/tmp", "xb_");
$zip = new ZipArchive();
$zip->open($tmpFileName, ZipArchive::CREATE);
$zip->addFile('[directory_inside_webspace]/test.pdf', 'myTest.pdf');
$zip->close();
$this->getResponse()->clearHttpHeaders();
$this->getResponse()->setContent(file_get_contents($tmpFileName));
$this->getResponse()->setHttpHeader('Content-Type', 'application/zip');
$this->getResponse()->setHttpHeader('Content-Disposition', 'attachment; filename=archive.zip');
return sfView::NONE;
Now here's what is strange. The temporary zip file under /tmp is fine. I can extract it without any problems.
But the file the browser sends to me is corrupt. When I open both of them in hex editor, the first few bytes look like:
working file: 50 4B 03 04 14 00 00
corrupt file: 0A 50 4B 03 04 14 00 00
When I remove the addition '0A' from the corrupt file I can open it without problems.
It's now the exactly same file as the tmp file created in /tmp.
Did anyone had a behavior like this before?? I'm stucked at this problem for over 4 days now and I'm not able to find the error.
I use exactly the same code in another symfony module and it's working in there. Any ideas ?
-----Update------
The problem wasn't related to the zipArchive or setContent.
I had a query at the beginning of the function.
$bill = Doctrine::getTable('Bill')->find($request->getParameter('id'));
In the class 'Bill.class.php' in my doctrine model I had a blank line before
<?php
So when the class Bill was instantiated the new line was print to screen.
I just wonder why php doesn't give an error message like 'headers already send' when sending the zip Archive to the browser.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
0A
是换行符。确保所有涉及的文件的标记之前没有换行符,并且
?>
标记之后没有换行符(除非您省略结束标记,否则推荐)。最可能的罪魁祸首是下载操作的 actions.class.php。
0A
is a newline character. Make sure there's no newline before the<?php
tag of all the files involved, and no newline after the?>
tag (unless you omit the closing tag, which is recommended).The most probable culprit is the actions.class.php of the download action.
几天前我在 symfony 中遇到了完全相同的问题,对我来说问题是有一个额外的字符(在我的实例中是一个空格)潜入了我的响应中。而不是 return sfView::NONE;如果最后添加一个骰子会发生什么?试试这个:
I had the exact same problem in symfony a few days ago and the issue for me was there was an extra character (a space in my instance) sneaking into my response. Instead of return sfView::NONE; what happense if you add a die at the end? Try this:
我是这样做的:
这可能是一个 BOM 错误。
Here is how I do it:
It's probably a BOM error.