Я работаю над системой в Laravel, чтобы сделать почтовый индекс с фотографиями и загрузить его потом.
Я решил, что я действительно не хочу использовать библиотеки для этого (это необходимо), поэтому я должен использовать обычный php. мой код контроллера:
public function downloadPictures()
{
$pictures = Input::get('photos');
$file_paths = array();
foreach ($pictures as $picture_id) {
$path = $this->photos->getFilepath($picture_id, 'original');
array_push($file_paths, $path);
}
$zip = new ZipArchive;
$zip->open('slike.zip', ZipArchive::CREATE);
foreach ($file_paths as $file) {
$content = file_get_contents($file);
$zip->addFromString(basename($file), $content);
}
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="'.basename($zip->filename).'"');
echo var_dump($zip);
echo basename($zip->filename);
$zip->close();
echo var_dump($zip);
echo basename($zip->filename);
}
Теперь с первой частью кода я могу сказать со 100% уверенностью, что я получаю правильные пути изображения (то есть выше //if (file_exists($file_paths ... )
комментарий, и я убедился, распечатав их и используя file_exists
)
Но потом все становится странным.
Во-первых: когда я открываю zip-файл, то протестированный мной numFiles говорит, что в нем уже 4 файла, я понятия не имею, почему.
Во-вторых: когда я печатаю ответ от этой функции контроллера в интерфейсе js (используя echo в контроллере var_dump($zip)
) я получаю свойства файла zip .. name + numFile + 4 (+4 по некоторым причинам), но когда я $zip->close()
я не могу получить доступ к свойствам.
В-третьих: заголовки перенаправления, которые я использовал обоими способами: до того, как я закрыл $ zip, и после (в настоящее время они находятся перед закрытием) ничего не делают … они должны создать форму в браузере, не так ли?
Если бы кто-то мог мне помочь, я был бы так рад. Мне нужно сделать это в воскресенье, и я возился с этим около 8 часов (это мой первый раз, когда я делаю это). Я довольно много гуглил, и это работает для других. Я использую ununtu на nginx, php v5.6, и я установил расширение php zip, и я тестирую его локально в браузере Ubuntu Mozilla.
ОБНОВЛЕНИЕ: Это не работает в Chrome, так что это не проблема Firefox.
Попробуй это:
public function downloadPictures()
{
$pictures = Input::get('photos');
$file_paths = array();
foreach ($pictures as $picture_id) {
$path = $this->photos->getFilepath($picture_id, 'original');
array_push($file_paths, $path);
}
$zip = new ZipArchive;
$zipname = 'silke.zip';
$zip->open($zipname, ZipArchive::CREATE);
foreach ($file_paths as $file) {
$content = file_get_contents($file);
$zip->addFromString(basename($file), $content);
}
header("HTTP/1.1 200 OK");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="'.$zipname.'"');
header('Content-Length: ' . filesize($zipname));
$zip->close();
readfile($zipname);
}
Наиболее важным является Content-Length
и readfile
линия.
Не повторяйте ничего другого, это повредит загрузку.
Обновить: Более самостоятельный тест:
$testData = array(
'test1.txt' => 'Test1',
'test2.txt' => 'Test2',
'test3.txt' => 'Test3',
'test4.txt' => 'Test4',
);
$zip = new ZipArchive;
$zipname = 'slike.zip';
$zip->open($zipname, ZipArchive::CREATE);
foreach ($testData as $filename => $content) {
$zip->addFromString($filename, $content);
}
header("HTTP/1.1 200 OK");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header('Content-Type: application/force-download');
header('Content-Disposition: attachment; filename="'.$zipname.'"');
header('Content-Length: ' . filesize($zipname));
$zip->close();
readfile($zipname);
Также это имеет header('Content-Type: application/force-download');
Других решений пока нет …