Пытался изолировать, проверив эти сценарии:
- Разные изображения
- Разные папки
- Разные пользователи
- Разные сегменты S3
- Различные серверы — промежуточный и рабочий — проблема в следующем. происходит как при
- нехватке памяти (хранилище и ОЗУ), так и при проблемах с разрешениями файлов, поскольку заданные
URL-адреса доступны и достаточно места для хранения и памяти
на серверах
Конечно, эту ошибку можно исправить. Но это не поможет пользователю загрузить более 40 файлов, даже если их больше.
- Возможно ли, что процесс перешел к заполнению массива $ImagesZip до загрузки файлов?
- Если да, то почему каждый раз происходит сбой ровно после 40 файлов? Файлы могут быть разных размеров, а некоторые могут занять больше или меньше времени в зависимости от их размера.
Вот ниже очищенный код:
public function downloadZip(Request $request) {
$reqdata = $request->all();
$ordref = @$reqdata['ordref'];
$usrnumber = @$reqdata['usrnumber'];
if (!$ordref || !$usrnumber) {
//check if parameters passed valid
echo json_encode($data);
exit();
}
$this->db = DB::table("orders AS o");
$details = $this->db->select("o.photos", "o.ref", "o.id", "o.folder_id", "o.price","o.is_download")
->where(....)
->first();
if (!$details) {
return redirect("/");
}
//check if json is valid
$images = $this->processphotos($details->photos);
// find photo ids from DB
....
....
$dbimages = $this->getimagesbyids($imageids);
$imageNames = [];
foreach ($dbimages as $item) {
$thumbName = $item->imgurl;
array_push($imageNames, array('image' => $thumbName, 'category' => $item->category, 'id' => $item->id));
}
if (!$imageNames) {
//return No images found error.
}
$zipimages = [];
$public_dir = public_path() . DIRECTORY_SEPARATOR . 'downloads' . DIRECTORY_SEPARATOR;
$zipimagesarray = array();
$imagepatharray = explode("/", $imageNames[0]['image']);
$imagename = end($imagepatharray);
$ctr = 100;
foreach ($imageNames as $row) {
$imgtype = 'jpg';
$prefix = $usrnumber.'_';
$imagename = $prefix . $ctr . $imgtype;
$signedurl = $this->getpresignedurl($row['image']);
@ File::copy($signedurl, $public_dir . $imagename);
array_push($zipimagesarray, array('path' => $public_dir, "image" => $imagename));
$ctr++;
}
$imageZip = [];
$certZip = [];
foreach ($zipimagesarray as $imagePublic) {
$path = explode(DIRECTORY_SEPARATOR,$imagePublic['path']);
$zipImage = $imagePublic['path'] . $imagePublic['image'];
array_push($imageZip, $zipImage);
}
try {
$zipName = $usrnumber . date('G:i:s') . ".zip";
Zipper::make(public_path('downloadOrder/' . $zipName))->add($imageZip)->close();
File::delete($imageZip);
$file = "/download/" . $zipName;
$data['result'] = array();
$data['result'] = url('/') . $file ;
$data['statusCode'] = 200;
$data['hasError'] = false;
$data['message'] = "Images retrieval is successful.";
return response($data)->header('Content-Type', 'application/json');
} catch (\Exception $ex) {
$data['result'] = array();
$data['statusCode'] = 400;
$data['hasError'] = true;
$data['message'] = "Unable to download the zip file. Please retry on a high speed internet connection or contact support, if issue persists!";
Log::error("Api::downloadZip - orderId: " . $data['Message'] . " " . $ex->getMessage());
return response($data)->header('Content-Type', 'application/json');
}
}
и
function getpresignedurl($key, $s3Client = null) {
$s3_env = [];
$Bucket = "xxxxx";
if (is_null($s3Client)) {
$s3_env = array('region' => config('aws.AWS_REGION'),
'credentials' => ['key' => config('aws.AWS_ACCESS_KEY_ID'), 'secret' => config('aws.AWS_SECRET_ACCESS_KEY')]);
$s3Client = \App::make('aws')->createClient('s3', $s3_env);
}
//Creating a presigned URL
$cmd = $s3Client->getCommand('GetObject', [
'Bucket' => $Bucket,
'Key' => $key
]);
$request = $s3Client->createPresignedRequest($cmd, '+30 minutes');
$signedurl = (string) $request->getUri();
return $signedurl;
}
Подробнее здесь: https://stackoverflow.com/questions/789 ... is-failing
Мобильная версия