【问题标题】:Resize and replace image in Laravel request在 Laravel 请求中调整图像大小和替换图像
【发布时间】:2018-10-04 23:05:02
【问题描述】:

我需要能够调整图像大小并将调整后的版本放回$request,有人知道这是否可能吗?

基本上,我继承了一些代码,其中可能包含 100 多个单独的文件上传部分,现在我的任务是调整网站上所有图像的大小(如果它们超过一定大小)。

所以我现在需要拦截应用程序上的所有图片上传,检测它们是否超过设定的大小,如果超过,则调整它们的大小。

我在网上找到的所有代码仅显示如何调整图像大小然后立即保存调整后的版本,但我需要能够调整图像大小然后将其放回$request 以由控制器处理.

图像以来自不同部分的图像数组的形式出现,因此我需要能够循环整个请求,检查任何输入是否包含/是文件,然后检查它们的大小。如果它们超过设定的大小,则调整它们的大小并在$request 中替换它们,这样当请求继续时,控制器可以正常处理图像,但它将处理新的调整大小的版本。

我尝试过调整图像大小,然后使用 laravel $request->merge() 方法,但我无法让它工作。

目前我正在调整中间件中所有图像的大小,就像这样

public function handle($request, Closure $next)
{

    foreach($request->files as $fileKey => $file){

        //Create a new array to add the newly sized images in
        $newFileArray = [];


        //Get each of the files that are being uploaded in the request, if there are no files this will just be ignored.
        foreach ($file as $key => $f) {

            if(!is_null($f)){
                $image = Image::make($f);
                if($image->height() > 500 || $image->width() > 500){
                    $image->resize(500, null, function ($constraint) {
                        $constraint->aspectRatio();
                    });
                }
                $newFileArray[$key] = $image;
            } else {
                $newFileArray[$key] = null;
            }
        }

        $request->merge([
          $fileKey => $newFileArray
        ]);

    };

    return $next($request);
}

我就是无法让它工作!

这可能吗?

编辑

在以下答案之一的 cmets 中提出了很好的建议后,我通过直接编辑临时图像文件来实现这一点,因此我不必弄乱请求,这就是我的做法。

public function handle($request, Closure $next)
{

    foreach($request->files as $fileKey => $file){

        //Get each of the files that are being uploaded in the request, if there are no files this will just be ignored.
        foreach ($file as $key => $f) {
            if(!is_null($f)){
                $image = Image::make($f->getPathName());
                if($image->height() > 500 || $image->width() > 500){
                    $image->resize(500, null, function ($constraint) {
                        $constraint->aspectRatio();
                    });
                    $image->save($f->getPathName());
                }
            }
        }

    };

    return $next($request);
}

【问题讨论】:

  • 为什么不在控制器中调整图像的大小?能够将图像传递到另一个$request 是在执行$request 之前将图像存储在某处。
  • @Lars 可能是因为他使用的是中间件架构,在这种架构中,请求会被传递到一堆请求处理程序

标签: php laravel laravel-5 laravel-request


【解决方案1】:

我刚刚读到 Laravel 使用 PSR-7 请求。

https://laravel.com/docs/5.7/requests#psr7-requests

这些是不可变的。换句话说,一旦设置,您就无法更改数据。但是,您可以做的是让它使用您的新参数创建一个新请求。

查看 PSR-7 界面,我们看到有一个方法看起来正是您所需要的:

https://github.com/php-fig/http-message/blob/master/src/ServerRequestInterface.php#L150

/**
 * Create a new instance with the specified uploaded files.
 *
 * This method MUST be implemented in such a way as to retain the
 * immutability of the message, and MUST return an instance that has the
 * updated body parameters.
 *
 * @param array $uploadedFiles An array tree of UploadedFileInterface instances.
 * @return static
 * @throws \InvalidArgumentException if an invalid structure is provided.
 */
public function withUploadedFiles(array $uploadedFiles);

所以,做你的事,创建你的数组,一旦它准备好了,像这样替换你的请求:

$request = $request->withUploadedFiles($yourNewArray);

【讨论】:

  • 那么您如何建议我将这种方法用于多维数组?正如您在我的示例中看到的那样,图像数组总是可以有不同的名称
  • 好吧,我假设你可以得到$_FILES的原始数组。处理您的图像,保存它,并替换原始路径。实际上,考虑一下,为什么不直接获取原始数组,加载并调整大小,覆盖临时存储文件夹中的原始文件,甚至不更改请求?
  • 编辑临时文件夹真是绝了!我现在将我的新代码添加到问题中,谢谢!
猜你喜欢
  • 2019-02-25
  • 2015-09-15
  • 2017-03-14
  • 1970-01-01
  • 1970-01-01
  • 2018-12-19
  • 2018-02-01
  • 2015-10-27
  • 2017-03-28
相关资源
最近更新 更多