对于我的网站,我想创建一个图库并上传照片。这些照片必须调整为两种格式。
我在我的控制器中构建一个方法来创建画廊,但速度非常慢并且需要太多内存。我该如何改进呢?
是否可以这样做或者需要我做一个ajax调用?
public function store(GalleryCreateRequest $request)
{
//dd($request->all());
$input = $request->all();
$name = str_replace(' ', '_', $input['name']);
if (Input::file('featured_image')) {
$featured = Input::file('featured_image');
$extensieFeatured = $featured->getClientOriginalExtension();
if (!file_exists('images/'.$name)) {
mkdir('images/'.$name, 0777, true);
}
$path = 'images/'.$name;
$featuredName = str_replace(' ', '_', $input['name']) . '_featured' . '.' . $extensieFeatured;
$featured->move($path, $featuredName);
$input['featured_image'] = $featuredName;
//landcape or Portrait
list($width, $height) = getimagesize($path.'/'.$featuredName);
if ($width > $height) {
//landscape
Image::make($path.'/'.$featuredName)->resize(1500, null, function ($constraint) {
$constraint->aspectRatio();
})->save($path.'/web_'.$featuredName);
Image::make($path.'/'.$featuredName)->resize(300, null, function ($constraint) {
$constraint->aspectRatio();
})->save($path.'/thumbs_'.$featuredName);
} else {
//portrait
Image::make($path.'/'.$featuredName)->resize(null, 1500, function ($constraint) {
$constraint->aspectRatio();
})->save($path.'/web_'.$featuredName);
Image::make($path.'/'.$featuredName)->resize(null, 300, function ($constraint) {
$constraint->aspectRatio();
})->save($path.'/thumbs_'.$featuredName);
}
}
$gallery = Galleries::create($input);
$gallery->categories()->attach($request->input('categories_list'));
$files = Input::file('images');
$uploadcount = 1;
if (!file_exists('images/'.$name.'/')) {
mkdir('images/'.$name.'/', 0777, true);
}
$destinationPath = 'images/'.$name.'/';
if (!file_exists($destinationPath.'/')) {
mkdir($destinationPath.'/', 0777, true);
}
if (!file_exists($destinationPath.'/')) {
mkdir($destinationPath.'/', 0777, true);
}
foreach ($files as $file) {
$extensie = $file->getClientOriginalExtension();
$filename = str_replace(' ', '_', $input['name']) . $uploadcount . '.' . $extensie;
$file->move($destinationPath, $filename);
Photos::create(['file' => $filename, 'galleries_id' => $gallery->id]);
//landcape or Portrait
list($width, $height) = getimagesize($path.'/'.$featuredName);
if ($width > $height) {
//landscape
Image::make($destinationPath.'/'.$filename)->resize(1500, null, function ($constraint) {
$constraint->aspectRatio();
})->save($destinationPath.'/web_'.$filename);
Image::make($destinationPath.'/'.$filename)->resize(300, null, function ($constraint) {
$constraint->aspectRatio();
})->save($destinationPath.'/thumbs_'.$filename);
} else {
//portrait
Image::make($destinationPath.'/'.$filename)->resize(null, 1500, function ($constraint) {
$constraint->aspectRatio();
})->save($destinationPath.'/web_'.$filename);
Image::make($destinationPath.'/'.$filename)->resize(null, 300, function ($constraint) {
$constraint->aspectRatio();
})->save($destinationPath.'/thumbs_'.$filename);
}
$uploadcount++;
}
Session::flash('created_galleries', 'The Gallery has been created with ' . $uploadcount . ' images');
return redirect('/admin/galleries');
}
答案 0 :(得分:0)
如果您循环浏览许多大型图像并处理它们,那么无论如何都可能是一个耗时且占用大量内存的过程。为此使用AJAX请求确实有意义。您可能也有兴趣使用laravel' queue system。
答案 1 :(得分:0)
您需要考虑一些性能问题,
异步作业:
对于将大文件上传到云端存储或发送电子邮件等耗时的工作,我们使用Asynchronous jobs。
限制上传大小:
在简单的场景中,您的代码应该可以正常工作,但问题是当用户上传大文件时。显然,它应该首先在服务器级别处理,而不是代码级别。
<强>建议:强>
public function submit(Request $request)
{
$input = $request->all();
$name = str_replace(' ', '_', $input['name']);
//if (Input::file('featured_image')) {
// When you already has access to request why requesting again using a proxy call throught Input Facade
if ($request->hasFile('featured_image')) {
$featured = $request->file('featured_image');
$extensieFeatured = $featured->getClientOriginalExtension();
// Since you're not using else
// Mean directory is either there already or you're creating it.
// in both cases $request->file()->move() should help
/*if (!file_exists('images/' . $name)) {
mkdir('images/' . $name, 0777, true);
}*/
$path = 'images/' . $name;
$featuredName = str_replace(' ', '_', $input['name']) . '_featured' . '.' . $extensieFeatured;
$featured->move($path, $featuredName);
$input['featured_image'] = $featuredName;
//landcape or Portrait
// reading a file at disk is 0.2 ms to 10 ms when you already have a file in memory why reading it again.
//list($width, $height) = getimagesize($path . '/' . $featuredName);
$image = Image::make($featured);
if ($featured->width > $featured->height) {
//landscape
$image->resize(1500, null, function ($constraint) {
$constraint->aspectRatio();
})->save($path . '/web_' . $featuredName);
$image->resize(300, null, function ($constraint) {
$constraint->aspectRatio();
})->save($path . '/thumbs_' . $featuredName);
} else {
//portrait
$image->resize(null, 1500, function ($constraint) {
$constraint->aspectRatio();
})->save($path . '/web_' . $featuredName);
$image->resize(null, 300, function ($constraint) {
$constraint->aspectRatio();
})->save($path . '/thumbs_' . $featuredName);
}
}
$gallery = Galleries::create($input);
$gallery->categories()->attach($request->input('categories_list'));
$files = $request->file('images');
$uploadcount = 1;
// You don't need to check this.
// since you're creating directories, mean www-data has the access to the file system
// so laravel UploadedFile can handle this.
/*if (!file_exists('images/' . $name . '/')) {
mkdir('images/' . $name . '/', 0777, true);
}*/
$destinationPath = 'images/' . $name . '/';
// You don't need this.
/*if (!file_exists($destinationPath . '/')) {
mkdir($destinationPath . '/', 0777, true);
}*/
// not even this.
/*if (!file_exists($destinationPath . '/')) {
mkdir($destinationPath . '/', 0777, true);
}*/
foreach ($files as $file) {
$extensie = $file->getClientOriginalExtension();
$filename = str_replace(' ', '_', $input['name']) . $uploadcount . '.' . $extensie;
$file->move($destinationPath, $filename);
Photos::create(['file' => $filename, 'galleries_id' => $gallery->id]);
// You can repeat the above procedure again here.
//landcape or Portrait
list($width, $height) = getimagesize($path . '/' . $featuredName);
if ($width > $height) {
//landscape
Image::make($destinationPath . '/' . $filename)->resize(1500, null, function ($constraint) {
$constraint->aspectRatio();
})->save($destinationPath . '/web_' . $filename);
Image::make($destinationPath . '/' . $filename)->resize(300, null, function ($constraint) {
$constraint->aspectRatio();
})->save($destinationPath . '/thumbs_' . $filename);
} else {
//portrait
Image::make($destinationPath . '/' . $filename)->resize(null, 1500, function ($constraint) {
$constraint->aspectRatio();
})->save($destinationPath . '/web_' . $filename);
Image::make($destinationPath . '/' . $filename)->resize(null, 300, function ($constraint) {
$constraint->aspectRatio();
})->save($destinationPath . '/thumbs_' . $filename);
}
$uploadcount++;
}
Session::flash('created_galleries', 'The Gallery has been created with ' . $uploadcount . ' images');
return redirect('/admin/galleries');
}
建议:
不要写密集(函数内部代码太多)控制器,尝试使用SOA(面向服务的体系结构)和SOLID原则。查看Lucid