Laravel 5,我的创建方法很慢,怎么能改进呢?

时间:2017-09-21 21:10:27

标签: php laravel-5 upload gallery image-uploading

对于我的网站,我想创建一个图库并上传照片。这些照片必须调整为两种格式。

我在我的控制器中构建一个方法来创建画廊,但速度非常慢并且需要太多内存。我该如何改进呢?

是否可以这样做或者需要我做一个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');
}

2 个答案:

答案 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