Поврежденный ZipArchive после setContent () в php symfony

У меня очень странное поведение при отправке 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-архива в браузер.


person cb0    schedule 04.08.2011    source источник


Ответы (3)


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

person Maerlyn    schedule 04.08.2011
comment
Большое спасибо, это была моя проблема! - person cb0; 05.08.2011

У меня была точно такая же проблема в symfony несколько дней назад, и проблема для меня заключалась в том, что в мой ответ пробирался лишний символ (пробел в моем случае). Вместо return 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;
person Dan    schedule 04.08.2011
comment
Вместо echo вы должны readfile (); и верните sfView :: HEADER_ONLY ;. И не забудьте поставить session_write_close (); если вы не хотите блокировать своего пользователя при загрузке (PHP блокирует сеансы пользователя). - person Damien; 04.08.2011
comment
Спасибо за ответ, к сожалению, созданный zip-архив все еще поврежден. С таким же дополнительным битом в начале. :( - person cb0; 04.08.2011
comment
Что будет на выходе, если вы сделаете все, ЗА ИСКЛЮЧЕНИЕМ вывода содержимого файла? Есть ли в ответ какие-то байты? Также что произойдет, если вы сделаете md5_file архива, который сгенерирован стихами, хорошей версией zip - совпадают ли они? - person Dan; 04.08.2011
comment
@Dan Хорошая идея. После удаления содержимого файла я получаю zip-файл, содержащий ровно «0A». Дело в том, что портит файл. Хэши md5_file не совпадают! Становится еще более странным! - person cb0; 04.08.2011
comment
0A - символ перевода строки. Как-то добавляется \ n. - person Dan; 04.08.2011

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

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

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

return sfView::NONE;

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

person Damien    schedule 04.08.2011
comment
Спасибо, но это дает мне точно такую ​​же ошибку. Я в замешательстве. - person cb0; 04.08.2011