Открытие загруженного 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
являются:
-
*.zip
файл поврежден - используемый инструмент "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, а правила хостинга не позволяли.