Открытие загруженного zip-файла создает файл cpgz?

Если я сделаю URL для почтового файла href ссылки и нажмите на ссылку, мой zip-файл будет загружен, и при открытии он получит содержимое, как я ожидаю.

Вот этот HTML:

<a href="http://mysite.com/uploads/my-archive.zip">download zip</a>

Проблема в том, что я хотел бы, чтобы ссылка указывала на мое приложение, чтобы я мог определить, авторизован ли пользователь для доступа к этому zip-файлу.

поэтому я хотел бы, чтобы мой HTML был таким:

 <a href="/canDownload">download zip</a> 

и мой PHP для /canDownload страница:

//business logic to determine if user can download

if($yesCanDownload){

$archive='https://mysite.com/uploads/my-archive.zip';
header("Content-Type: application/zip");
header("Content-Disposition: attachment; filename=".basename($archive));
header("Content-Length: ".filesize($archive));
ob_clean();
flush();
echo readfile("$archive");
}   

Итак, я думаю, что проблема связана с header() код, но я пробовал кучу вещей, связанных с этим на основе различных предложений Google и других SO, и ни одна из них не работает.

Если вы ответите на мой вопрос, скорее всего, вы тоже можете ответить на этот вопрос: ZIP-файл с PHP приводит к появлению файла cpgz после извлечения

6 ответов

Решение

Хорошо, я ответил на свой вопрос.

Основная проблема, которую я изначально не прояснил, заключалась в том, что файл не был расположен на моем сервере приложений. Это было в ведре Amazon AWS s3. Вот почему я использовал полный URL в своем вопросе, http://mysite... а не просто путь к файлу на сервере. Как выясняется fopen() Можно открыть URL-адреса (все "объекты" S3 Bucket, ака файлы, URL-адреса), так что это то, что я сделал.

Вот мой окончательный код:

$zip= "http://mysite.com/uploads/my-archive.zip"; // my Amazon AWS s3 url
header("Content-Type: archive/zip"); // works with "application/zip" too
header("Content-Disposition: attachment; filename='my-archive.zip"); // what you want to call the downloaded zip file, can be different from what is in the s3 bucket   
$zip = fopen($zip,"r"); // open the zip file
echo fpassthru($zip); // deliver the zip file
exit(); //non-essential

Ответ в моем случае заключался в том, что перед readfile() выводилась пустая строка.

Итак, я добавил:

ob_end_clean ();

ReadFile($ файла);

Но вам, вероятно, следует искать место, где эта строка выводится в вашем коде.

Документация PHP для readfile говорит, что он выведет содержимое файла и вернет int.

Итак, твой код, echo readfile("$archive");будет эхо $archive (кстати, двойные кавычки здесь не имеют смысла; вы должны удалить их), и ТОГДА выведите int это возвращается. То есть ваша строка должна быть: readfile($archive);

Кроме того, вы должны использовать локальный путь (не ссылка http: //) к архиву.

Итого:

if($yesCanDownload){
    $archive='/path/to/my-archive.zip';
    header("Content-Type: application/zip");
    header("Content-Disposition: attachment; filename=".basename($archive));
    header("Content-Length: ".filesize($archive));
    ob_clean();
    flush();
    readfile($archive);
}

Наконец, если это не работает, убедитесь, что filesize($archive) возвращает точную длину файла.

Другой возможный ответ я нашел После долгих поисков я обнаружил, что две возможные причины *.zip "расстегнуть молнию" на *.zip.cpgz являются:

  1. *.zip файл поврежден
  2. используемый инструмент "unzip" не может обрабатывать>2 ГБ файлов

Будучи пользователем Mac, вторая причина была причиной моей проблемы с разархивированием файла: стандартным инструментом Mac OS является Archive Utility, и он, очевидно, не может обрабатывать файлы размером более 2 ГБ. (Для меня рассматриваемый файл представлял собой распбированный образ диска размером 4 Гб.)

В итоге я использовал виртуальную машину Debian, уже существующую в Virtual Box на моем Mac. unzip 6.0 на Debian 8.2 не было проблем с разархивированием архива.

Вы передаете URL readfile() лайк:

$archive = 'https://mysite.com/uploads/my-archive.zip';

Пока вы должны передать путь на сервер, например:

$archive = '/uploads/my-archive.zip';

Предполагая, что файл находится в папке загрузки.

Дополнительно попробуйте следующие заголовки:

header("Content-type: application/octet-stream"); 
header("Content-disposition: attachment; filename=file.zip");  

В моем случае я пытался создать файл в каталоге выше public_html, а правила хостинга не позволяли.

Другие вопросы по тегам