【问题标题】:Uploading to S3 with Laravel Intervention image returns boolean and not path使用 Laravel 干预图像上传到 S3 返回布尔值而不是路径
【发布时间】:2019-11-09 02:47:23
【问题描述】:

我在 Laravel 中上传图片时遇到问题。有时图像需要重新定向 - 使用干预图像执行此操作时,它只返回一个布尔值而不是 s3 中图像的路径。在没有干预图像的情况下使用它可以正常工作

我试过 exif 读取数据并使用imagerotate 无济于事,它出错了

我运行以下

$image = $request->file('photo');
$path = \Storage::disk('s3')->put('users/'.\Auth::id().'/posts', $image, 'public');
dd($path); // /users/1/posts/39grjigrje.jpg

$path 变量很棒,它是 s3 路径,但是正在运行:

$image = $request->file('photo');
$image = \Image::make($image);
$image->orientate();
$path = \Storage::disk('s3')->put('users/'.\Auth::id().'/posts', $image, 'public');
dd($path); // true

$path 变量只是一个布尔值,不会返回存储的文件路径

我希望有一条路径,例如/images/1/kfjeieuge.jpg 当我不使用干预图像时得到,当我使用干预时得到一个布尔值。

【问题讨论】:

  • 你误会了吗?也许这表明它不起作用。通常你必须将字符串存储在文件中。
  • 它目前返回 true 但是我在 s3 中看不到
  • 您可以将干预图像转换为类似->put(..., (string) $image->encode('jpg', 75), ...);的字符串
  • 那仍然返回 true?
  • @iLC,您能否确认在第一种情况下文件是否也确实已上传? $path = \Storage::disk('s3')->put('users/'.\Auth::id().'/posts', $image, 'public');

标签: php laravel amazon-s3 intervention


【解决方案1】:

几年前我也遇到过同样的问题。我通过以下步骤解决了这个问题:

1.您可能需要在对图像进行干预操作后对其进行编码。 要实现编码,请参阅有关流方法的文档:Create encoded image stream

以给定格式和给定图像质量对当前图像进行编码,并根据图像数据创建新的 PSR-7 流。

$image = Image::make(request()->file('image'))->orientate()->encode('jpg');

2.然后用流存储起来

$path = Storage::disk('s3')->put('users/'.\Auth::id().'/posts', $image->stream(),'public');

这应该可以实现您的目标。

【讨论】:

  • 这样做仍然返回 1
【解决方案2】:

在第一个例子中:

$image = $request->file('photo');
$path = \Storage::disk('s3')->put('users/'.\Auth::id().'/posts', $image, 
'public');

$request->file('photo') 文件将返回 Illuminate\Http\UploadedFile 类的实例。你可以在这里查看文档link

正如 Tarun 所说,put 方法检查 Illuminate\Http\UploadedFile 类的实例。所以这样的话,就会上传成功了。

在第二个例子中:

$image = $request->file('photo');
$image = \Image::make($image); //here
$image->orientate();
$path = \Storage::disk('s3')->put('users/' . \Auth::id() . '/posts', $image, 'public');

您正在用实例 Image 类(第二行)覆盖 $image 变量。这是错误的。您需要传递 Stream 或文件。

试试下面的代码:

$image = $request->file('photo');
$image = \Image::make($image); //here
$image->orientate()->encode('jpg');
$filename = time() . '.jpg';
$path = \Storage::disk('s3')->put('users/' . \Auth::id() . '/posts/'.$filename, $image->getEncoded(), 'public');

【讨论】:

    【解决方案3】:

    您可以按照以下链接中的说明解决它

    https://laracasts.com/discuss/channels/laravel/saving-an-intervention-image-instance-into-amazon-s3

    $path = \Storage::disk('s3')->put('users/'.\Auth::id().'/posts', $image->stream()->__toString(), 'public');
    

    更新:7 月 5 日

    如果你查看源代码,它应该只返回 bool

    https://github.com/laravel/framework/blob/c7bdf66062af3c63648f7c29591476e6db92c885/src/Illuminate/Filesystem/FilesystemAdapter.php#L192

    /**
         * Write the contents of a file.
         *
         * @param  string  $path
         * @param  string|resource  $contents
         * @param  mixed  $options
         * @return bool
         */
        public function put($path, $contents, $options = [])
        {
            $options = is_string($options)
                         ? ['visibility' => $options]
                         : (array) $options;
            // If the given contents is actually a file or uploaded file instance than we will
            // automatically store the file using a stream. This provides a convenient path
            // for the developer to store streams without managing them manually in code.
            if ($contents instanceof File ||
                $contents instanceof UploadedFile) {
                return $this->putFile($path, $contents, $options);
            }
            return is_resource($contents)
                    ? $this->driver->putStream($path, $contents, $options)
                    : $this->driver->put($path, $contents, $options);
        }
    

    如您所见,Streamfile 的处理方式不同

    理想的做法是使用url函数来获取url

    Storage::disk('s3')->url($filename)
    

    【讨论】:

    • 这只是返回 true
    • @iLC 是的,如果一切顺利,它确实返回 true。但是它保存了图片吗? Turan 是对的,您需要对图像进行字符串化才能在 S3 上保存对象。如果你在 tinker 中运行 \Storage::allDirectories('users');,你会看到什么?如果您什么也没看到,则 IAM 设置有问题。
    【解决方案4】:

    试试这个

    $image = \Image::make($request->file('photo')->getRealpath());
    $image->orientate();
    
    
    $image->encode('jpg');
     OR
    $image->response('jpg', 100);
    
    
    $path = \Storage::disk('s3')->put('users/'.\Auth::id().'/posts', $image, 'public');
    

    【讨论】:

      猜你喜欢
      • 2021-12-12
      • 2014-06-05
      • 2023-03-10
      • 1970-01-01
      • 2017-04-22
      • 2020-02-13
      • 1970-01-01
      • 1970-01-01
      • 2020-01-25
      相关资源
      最近更新 更多