大家好,我只是有一个关于最佳实践的快速问题,也许对排队和图像处理有一些帮助。
我目前在一个网站上工作,该网站允许用户一次上传超过 10 个文件,以我的经验,我只真正处理单个上传或最多 2-3 个,这个网站允许用户上传尽可能多的文件,然后执行图像处理以创建不同大小的每个图像的 3 个版本。
我的思考过程以及我是如何实现的如下。
用户去上传表单并选择了多个文件,当他们完成表单自动提交时,这些文件都是内联上传的,上传的文件直接上传到 S3 中的临时文件夹,这是因为实时环境中有多个服务器负载平衡器在他们面前,所以我担心如果我将它们全部上传到服务器然后如果我触发队列它可能会转到不正确的服务器并且找不到文件,如果有一个很好的方法来做到这一点会很棒。
提交表单时,它会向 Iron.io 上的队列发出通知,其中包含来自表单提交的数据,该数据基本上调用服务器并开始处理图像,代码如下
public function fire($job, $data)
{
set_time_limit(0);
try {
if(is_array($data)){
foreach ($data['file'] as $x => $file){ //loop through each file uploaded and now save them
if ($this->images->doesMediaExistInTemporaryFolder($file)){
if ($new_file = $this->images->getMediaFromTemporaryS3Folder($file)){
file_put_contents (app_path() . '/storage/bulk-upload/' . $file, (string) $new_file['Body']);
$record_date = false;
if ($data['date'][$x] != 'no-date'){
if ($new_file['ContentType'] == 'image/jpeg') {
$exif_data = @exif_read_data(app_path() . '/storage/bulk-upload/' . $file, 'FILE');
}
if (!empty($exif_data) && @array_key_exists('DateTime', $exif_data)){
$record_date = $exif_data['DateTime'];
} else {
$record_date = $data['date'][$x];
}
}
$created_file = new \Symfony\Component\HttpFoundation\File\UploadedFile(app_path() . '/storage/bulk-upload/' . $file, $file, $new_file['ContentType'] );
$input = array('vehicle_objectId' => $data['vehicle_objectId'], 'type' => $data['type'], 'privacy' => $data['privacy'], 'date' => $record_date);
if (file_exists(app_path() . '/storage/bulk-upload/' . $file)){
if ($record = $this->record_repository->save($input, $created_file)) {
unlink(app_path() . '/storage/bulk-upload/' . $file);
$this->images->deleteMediaFromTemporaryS3(array(array('Key' => $file )));
} else {
$data['filename'] = $file;
\Mail::send('emails.bulk-upload', $data, function($message) {
$message->to('email', 'Daniel Newns')->subject('Bulk upload save issue');
});
}
}
}
}
}
$parse = new \ParseRestClient();
$user = $parse->retrieveCurrentUser( $data['pid']);
if (isset($user->email)) {
$vehicle_url = \URL::route('vehicles.show', $data['vehicle_objectId']);
$body = "<p>Hi " . $user->username . "</p><p>Your records have all been created. View them all as part of your vehicle record <a href='" . $vehicle_url . "'>here</a></p>";
$message = array(
'to' => array(array('email' => $user->email)),
'from_email' => 'xxxxx
'from_name' => 'xxxxx'
);
$template_content = array(array("name" => "share", "content" => $body));
$response = \Email::messages()->sendTemplate('Bulk_Upload', $template_content, $message);
}
}
} catch(\Exception $e){
$message = array(
'to' => array(array('email' => 'email')),
'from_email' => 'email',
'from_name' => 'xxxxxx'
);
$content = '<p>'. $e->getMessage() . '</p>';
$content .= '<p>' . $e->getTraceAsString() . '</p>';
$template_content = array(array("name" => "share", "content" => $content));
$response = \Email::messages()->sendTemplate('Content_Share', $template_content, $message);
}
}
如您所见,它遍历从队列返回的数据并从此处遍历文件,它从 S3 中提取图像并将其存储在本地,然后检查是否设置了日期并通过该日期或 exif 计算出创建日期数据。然后它创建文件并将记录保存在 save 函数中,它执行所有需要的调整大小。
我的问题是真的有人对我如何改进这一点有任何建议,因为我偶尔会收到来自异常的电子邮件,它说它找不到某个图像,就像它没有在本地创建一样,是我在本地创建图像的方法使用file_put_contest
我应该使用的那个,或者有更好的方法让我从 S3 中提取数据并使用它。我已经放入了一些 if 语句来阻止事情通过差距等。
很高兴听到其他人对我在哪里出错以及我可以做些什么来改善这一点的想法?也许我可以存储在第一个循环中不存在的文件数组,然后再试一次,因为我认为这可能是在图像存在之前执行的代码的情况会是这种情况吗?
任何帮助将非常感激。
谢谢