Поврежденный ZipArchive после setContent () в php symfony - PullRequest
1 голос
/ 04 августа 2011

У меня очень странное поведение при отправке zip-архива, содержащего файлы любого типа в symfony.Проблема в том, что 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;

Теперь вот чтостранный.С временным zip-файлом в / tmp все в порядке.Я могу извлечь его без проблем.Но файл, который браузер отправляет мне, поврежден.Когда я открываю их оба в шестнадцатеричном редакторе, первые несколько байтов выглядят так:

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 в браузер.

Ответы [ 3 ]

2 голосов
/ 04 августа 2011

0A - символ новой строки. Убедитесь, что нет новой строки перед тегом <?php всех задействованных файлов, и нет новой строки после тега ?> (если вы не пропустите закрывающий тег, что рекомендуется).
Наиболее вероятным виновником является action.class.php действия загрузки.

1 голос
/ 04 августа 2011

У меня была та же самая проблема в Symfony несколько дней назад, и проблема для меня заключалась в том, что в мой ответ просочился дополнительный символ (пробел в моем случае). Вместо возврата sfView :: NONE; что за счастье, если в конце добавить кубик? Попробуйте это:

//make sure toolbar is disabled just to be extra safe
sfConfig::set('sf_web_debug', false);

$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()->setHttpHeader('Content-Type', 'application/zip');
$this->getResponse()->setHttpHeader('Content-Disposition', 'attachment; filename=archive.zip');

// Unlock session in order to prevent php session warnings
$this->getUser()->shutdown();

// Send http headers to user client
$this->getResponse()->sendHttpHeaders();

echo file_get_contents($tmpFileName);

die;
0 голосов
/ 04 августа 2011

Вот как я это делаю:

// Unlock php session
$this->getUser()->shutdown();

// Send the response
$response->sendHttpHeaders();
$response->setContent(readfile(utf8_decode($tmpFileName)));
$response->sendContent();

return sfView::NONE;

Вероятно, ошибка спецификации .

...