通过Laravel 5.1上传图像/文件到AWS S3,不幸的是这些图像被损坏了。

3

我尝试通过Laravel 5.1将图片上传到S3,但在S3中接收到的图片被认为是损坏的,如下所示:

S3中的图片

第一步:使用Composer

  1. composer require aws/aws-sdk-php-laravel:~3.0
  2. 从Laravel 5.1供应商中打开配置文件

'region' => env('AWS_REGION', '我的区域'), 'version' => 'latest', 'ua_append' => [ 'L5MOD/' . AwsServiceProvider::VERSION, ], 'credentials' => [ 'key' => '输入您的代码', 'secret' => '输入您的代码' ], 'scheme' => 'http'

第二步

  1. 在config/app.php中添加这些行以激活类别名和提供者

Providers 'Aws\Laravel\AwsServiceProvider', Alias 'AWS' => 'Aws\Laravel\AwsFacade'

第三步

  1. set up the controller

    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    use App\Http\Requests;
    use \Auth, \Redirect, \Validator, \Input, \Session, \Response;
    use App\Http\Controllers\Controller;
    use App\Http\Requests\PhotoRequest;
    use App\Photo;
    use \Image;
    use \File;
    
    use AWS;
    
    class PhotoController extends Controller
    {
    protected   $photo;
    public function __construct(Photo $photo) {
            $this->photo = $photo;
        }   
    
    public function index()
    {
            $p = Photo::all();
            return view('photo.index')
                ->with('photos',$p);
    
    }
    
    public function create()
    {
            return view('photo.create')->with('photos',$this->_data);
    }
    
    
    /**
     * Store a newly created resource in storage.
     *
     * @return Response
     */
    public function store(PhotoRequest $request)
    {
    
         $input = Input::all();
    
            if ($this->photo->isValid($input)) {
                $img = $request->file('file');
    
                $mime = $input['file']->getMimeType();
                $fileName = time() . "." . strtolower($input['file']->getClientOriginalExtension());
    
                $image = Image::make(file_get_contents($img->getRealPath()));
                $this->upload_s3($image, $fileName, $mime, "resource/Original");
                $image->resize(400, 300);
                $this->upload_s3($image, $fileName, $mime, "resource/Thumbnail");
    
                Photo::create([
                    'title' => Input::get('title'),
                    'file' => $fileName,
                ]);
    
                Session::flash('exito', $image);
                return Redirect::route('photo.index');
            } else {
                Session::flash('error', 'Failed');
                return Redirect::back()->withInput()->withErrors($this->photo->messages);
            }
    }  
        private function upload_s3($image, $fileName, $mime, $folder) {
            $s3 = AWS::createClient('s3');
    
            try{
                 $s3->putObject(array(
                    'Bucket'      => 'mybucket',
                    'Key'         => "{$folder}/{$fileName}",
                    'Body'        => "$image",
                    'ContentType' => $mime,
                    'ACL'         => 'public-read',
    
    
                ));   
             } catch(S3Exception $e){
                echo $e->getAwsErrorCode() . "\n";
                // The bucket couldn't be created
                echo $e->getMessage() . "\n";
             }
    
        }
    
        private $_data = array();
        private $path = "img/upload/";
    

    }

第四步

  1. Set up the View in Laravel 5.1 for UI

    @extends('app')
    @section('content')
    
    <h1>Create:</h1>
    {!! Form::open(array('url' => 'photo/store', 'files' => true)) !!}
    
        <div class="form-group">
          <label for="title">Title</label>
          <input type="text" class="form-control" id="title" name="title" placeholder="Photo Title">
           <span class="help-block color-red">{!! $errors->first('title') !!}</span>
        </div>
        <div class="form-group">
          <label for="file">File</label>
          <input type="file" class="form-control" id="file" name="file">
           <span class="help-block color-red">{!! $errors->first('file') !!}</span>
        </div>
        <button type="submit" class="btn btn-default">Create</button>
    {!! Form::close() !!}
    @endsection
    
请告诉我我遗漏了什么,需要注意些什么?我已经在谷歌上搜索了许多解决方案,但即使我按照其他开发者提出的几个步骤去做,还是无法解决问题。所以,要么是我对这些功能理解不够深入,要么是我的尝试没有合适的解决方案。

你能在控制器中包含所使用的导入吗?因为在这个例子中我们看不到 Image 是什么。 - Luceos
好的,没问题。对此感到抱歉。 - Jeffrey Cheong
@Luceos,我已经包含了,不过只需点击图像链接即可查看结果。 - Jeffrey Cheong
好的,请稍等一下。 - Jeffrey Cheong
哪个包提供了Image门面? - Luceos
显示剩余3条评论
1个回答

2

现在我们知道您正在使用Intervention,使用适当的方式实例化图像对象,使用make

$image = Image::make($input['file']);

根据文档,make()方法可以接受字符串、路径以及UploadedFile对象。现在安全地将数据写入S3:
         $s3->putObject(array(
            'Bucket'      => 'mybucket',
            'Key'         => "{$folder}/{$fileName}",
            'Body'        => (string) $image->encode(),
            'ContentType' => $mime,
            'ACL'         => 'public-read',
        ));  

顺便问一下,为什么不使用Laravel自带的S3适配器呢?相关信息请参考https://laravel.com/docs/5.3/filesystem#driver-prerequisites

我使用了以下代码: $image = Image::make($input['file']); $this->upload_s3($image, $fileName, $mime, "resource/Original"); - Jeffrey Cheong
结果仍然相同,图像仍然损坏。 - Jeffrey Cheong
嗯,我想编码仍然是必需的,而且将其转换为字符串可能更明显,请参见更新的答案。 - Luceos
你刚刚救了我的命。非常感谢。你能解释一下编码部分吗?是的,我还在探索中。顺便问一下,为什么不使用Laravel自带的S3适配器来处理文件系统呢?https://laravel.com/docs/5.3/filesystem#driver-prerequisites - Jeffrey Cheong
1
很高兴它起作用了。我不是完全确定,但编码部分是输出图像的三种方式之一。如果没有输出,图像可能以原始格式保存。此外,如果你深入研究S3 API,你可能会注意到发送流的选项,如果你想使用更基于 Promise 的上传,这也可能很方便。 - Luceos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接