【问题标题】:How to fix upload image to s3 using Laravel如何使用 Laravel 修复上传图像到 s3
【发布时间】:2019-09-29 23:40:38
【问题描述】:

我尝试使用 Laravel 将图像上传到 s3,但收到运行时错误。将 Laravel 5.8、PHP7 和 API REST 与 Postman 一起使用,我通过 body base64 发送 我收到一个图片 base64,我必须上传到 s3 并获取请求 URL。

public function store(Request $request)
{
    $s3Client = new S3Client([
        'region' => 'us-east-2',
        'version' => 'latest',
        'credentials' => [
            'key' => $key,
            'secret' => $secret
        ]
    ]);
    $base64_str = substr($input['base64'], strpos($input['base64'], ",") + 1);
    $image = base64_decode($base64_str);

    $result = $s3Client->putObject([
        'Bucket' => 's3-galgun',
        'Key' => 'saraza.jpg',
        'SourceFile' => $image
    ]);

    return $this->sendResponse($result['ObjectURL'], 'message.', 'ObjectURL');
}

说:

RuntimeException: Unable to open u�Z�f�{��z���� ....

【问题讨论】:

    标签: php laravel amazon-s3


    【解决方案1】:

    您必须使用Body 而不是SourceFileSourceFile 是文件的路径,但你没有文件,你有一个 base64 编码的 img 源。这就是为什么您需要使用可以是字符串的Body。更多内容:https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putobject

    固定版本:

    public function store(Request $request)
    {
        $s3Client = new S3Client([
            'region' => 'us-east-2',
            'version' => 'latest',
            'credentials' => [
                'key' => $key,
                'secret' => $secret
            ]
        ]);
        $base64_str = substr($input['base64'], strpos($input['base64'], ",") + 1);
        $image = base64_decode($base64_str);
    
        $result = $s3Client->putObject([
            'Bucket' => 's3-galgun',
            'Key' => 'saraza.jpg',
            'Body' => $image
        ]);
    
        return $this->sendResponse($result['ObjectURL'], 'message.', 'ObjectURL');
    }
    

    【讨论】:

      【解决方案2】:

      SourceFile 参数指向要上传到 S3 的文件的路径,而不是二进制文件

      您可以使用Body参数替换SourceFile,或者将文件保存到本地临时并获取SourceFile的路径 像这样:

      public function store(Request $request)
      {
          $s3Client = new S3Client([
              'region' => 'us-east-2',
              'version' => 'latest',
              'credentials' => [
                  'key' => $key,
                  'secret' => $secret
              ]
          ]);
          $base64_str = substr($input['base64'], strpos($input['base64'], ",") + 1);
          $image = base64_decode($base64_str);
      
          Storage::disk('local')->put("/temp/saraza.jpg", $image);
      
          $result = $s3Client->putObject([
              'Bucket' => 's3-galgun',
              'Key' => 'saraza.jpg',
              'SourceFile' => Storage::disk('local')->path('/temp/saraza.jpg')
          ]);
      
          Storage::delete('/temp/saraza.jpg');
      
          return $this->sendResponse($result['ObjectURL'], 'message.', 'ObjectURL');
      }
      

      而且,如果您在 Laravel 中使用 S3,则应考虑使用 S3 文件系统驱动程序,而不是在控制器中手动访问 S3Client

      为此,请添加 S3 驱动程序 composer require league/flysystem-aws-s3-v3,将您的 S3 IAM 设置放入 .envconfig\filesystems.php

      然后更新config\filesystems中的默认文件系统,或者在使用存储Storage::disk('s3')时指明磁盘驱动

      详情见文档here

      【讨论】:

        【解决方案3】:

        上传 AWS-S3 存储中的任何文件的非常简单的方法。

        首先,检查您的 ENV 设置。

        AWS_ACCESS_KEY_ID=your key
        AWS_SECRET_ACCESS_KEY= your access key
        AWS_DEFAULT_REGION=ap-south-1
        AWS_BUCKET=your bucket name
        AWS_URL=Your URL
        

        第二个FileStorage.php

          's3' => [
                'driver' => 's3',
                'key' => env('AWS_ACCESS_KEY_ID'),
                'secret' => env('AWS_SECRET_ACCESS_KEY'),
                'region' => env('AWS_DEFAULT_REGION'),
                'bucket' => env('AWS_BUCKET'),
                'url' => env('AWS_URL'),
                //'visibility' => 'public', // do not use this line for security purpose. try to make bucket private.
            ],
        

        现在进入主代码。 从 HTML 表单上传二进制文件

         $fileName = 'sh_'.mt_rand(11111,9999).".".$imageFile->clientExtension();;
         $s3path  =  "/uploads/".$this::$SchoolCode."/";
         Storage::disk('s3')->put($s3path, file_get_contents($req->file('userDoc')));
        

        上传 Base64 文件 对于公共存储桶或如果您想保持文件公开

         $binary_data = base64_decode($file);
         Storage::disk('s3')->put($s3Path, $binary_data, 'public');
        

        对于私有存储桶或如果您想保持文件私有

           $binary_data = base64_decode($file);
           Storage::disk('s3')->put($s3Path, $binary_data);
        

        我建议您将文件保密...这是一种更安全的方式。为此,您必须使用 PreSign in URL 来访问该文件。

        对于预登录网址,请查看此帖子。 How access image in s3 bucket using pre-signed url

        【讨论】:

        • 'visibility' => 'public',是必需的。如果有人忘记了,请添加,否则您将无法获取任何上传的 ed 文件。
        • 'visibility' => 'public',在将文件公开的情况下是必需的,否则你可以离开它。在它之前你先检查你的桶的性质。
        猜你喜欢
        • 1970-01-01
        • 2020-12-23
        • 2018-01-19
        • 1970-01-01
        • 2023-03-20
        • 2018-05-12
        • 1970-01-01
        • 2014-07-13
        • 1970-01-01
        相关资源
        最近更新 更多