У меня есть приложение, которое позволяет пользователям загружать несколько файлов из корзины S3 через экземпляр EC2 в одну zip-папку.
Процесс работает нормально, однако я хотел бы, чтобы система создавала папку для каждого пользователя, когда они хотят загружать файлы, а затем файлы загружаются в эту папку, а затем помещаются в zip-папку в папке пользователя, а затем эта zip-папка загружена.
Файлы загружаются в эту папку нормально, и они также правильно архивируются, но моя проблема в том, что он не загружает zip-файл из папки пользователя, а загрузка отображается как пустой zip-файл.
Ниже приведен мой код для загрузки всего:
mkdir($userId);
$allName = $vshort . "v" . $number . "_All.zip";
$allName = str_replace(" ", "_", $allName);
if (isset($_POST['downloadAll']))
{
$zip = new ZipArchive();
$zip->open("{$userId}/{$allName}", ZipArchive::CREATE);
$s3->registerStreamWrapper();
foreach ($items as $item)
{
$fid = $item->item_file_id;
$file = ItemFile::locateId($fid);
$a = $file[0]->item_file_type;
$b = $file[0]->item_file_app;
$c = $file[0]->item_file_name;
$fileName = $a . "/" . $b . "/" . $c;
$download = $s3->getCommand('GetObject', [
'Bucket' => AWS_BUCKET,
'Key' => $fileName
]);
$streamFile = $c;
$user = User::locate($_SESSION['email']);
$uid = $user->user_id;
$cid = $user->user_company_id;
$history = new History();
$history->insert($fid, $uid, $cid);
$req = $s3->createPresignedRequest($download, '+1 minutes');
$link = (string)$req->getUri();
$stream = file_get_contents($link);
header($_SERVER["SERVER_PROTOCOL"] . " 200 OK");
header("Cache-Control: public"); // needed for internet explorer
header("Content-Type: application/'$a'");
header("Content-Disposition: attachment; filename='$c'");
file_put_contents($streamFile, $stream);
$zip->addFile($streamFile);
$downArray[] = $streamFile;
}
$zip->close();
$dLink = "https://mywebsite/" . $userId . "/" . $allName;
$size = filesize($allName);
header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=$allName");
header("Content-length: " . $size);
header("Expires: 0");
ob_end_clean();
stream_context_set_default([
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
]
]);
readfile($dLink);
unlink($allName);
foreach ($downArray as $down)
{
unlink($down);
}
}
Я чувствую, что это как-то связано с моими заголовками, но я не уверен, любая помощь будет принята с благодарностью.
ПРИМЕЧАНИЕ. Я буду удалять папку, как только пользователь покинет страницу.
Ниже то, что я вижу на веб-сервере.

Папка "6" - это идентификатор пользователя, о котором идет речь.






Похоже, вы вызываете readfile () по ссылке для скачивания ($ dLink), которая будет обслуживать файл через HTTP. Вероятно, вы хотели вызвать readfile для $ allName, пути файловой системы к тому же файлу. Я предполагаю, что ваш http-запрос к $ dLink почему-то не работает. Кроме того, вы mkdir ($ userId), но никогда не используете этот каталог.
Кроме того, похоже, ваша переменная $ allName содержит базовое имя zip-файла (например, myzip-v-20_ALL.zip). Я бы порекомендовал открыть ваш zip-файл, указав полный путь к вашему каталогу данных, чтобы вы разделяли файловую систему и пути http.
$allNameFilesystem = "{$userId}/{$allName}";
$allNameHttp = "https://mywebsite/{$userId}{$allName}";
// ...
$zip->open($allNameFilesystem, ZipArchive::CREATE);
// ...
// The download link is $allNameHttp
То есть, если вам действительно нужен http-путь. В этом случае, если вы измените readfile для использования пути к файловой системе, вы действительно больше не будете использовать путь http в своем коде.
Думаю, тогда у вашего кода может быть больше проблем. userId может быть неопределенным. Попробуйте добавить error_reporting (E_ALL); ini_set ('display_errors', истина); над сценарием. Таким образом вы сможете увидеть уведомления и предупреждения об аллергии и понять, что происходит на самом деле.
ошибки не отображаются, и папка создается, см. прикрепленный PNG
Я пробовал это, и у меня все еще возникает та же проблема, и теперь файлы создаются в корневой папке, а не в папке пользователя.