4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

laravelで画像をs3アップロード

Last updated at Posted at 2019-08-27

s3の設定
 ユーザー追加
 グループ追加
 バケットポリシー追加
 AWSのキー取得
laravelに処理追加
 AWSのキーをララベル.envに設定
 ※ここのキーがあってること、通るキーであることを初めに検証すると早い。
 ※他の細かい処理を書こうとも、そもそもキーとかでこけてると動かない。
 

インストール

たまにメモリエラー的なの出るときあるので、その時はメモリ使用量を増やす設定入れればよし。
v2とv3のライブラリがある。
v3の時にphp7.2以上使ってねってエラー出るかもしれないので、
その時はphpのバージョンあげる。

composer require league/flysystem-aws-s3-v3 ~1.0

何が一番デバッグ早いの?

tinkerでやるか、あるいは毎度laravelでserveする。
ユーザー認証のかかってない部分にルーティング1個追加して動かしたりする。
デバッガーとか使うのがより良いんだろうけど、時間ねぇので一旦これで行く。

S3のバケット作って初期設定する

バケットポリシーは真似しながら書く
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/example-bucket-policies.html
https://qiita.com/k-staging/items/f9d00fa0bca25db31888
https://aws.amazon.com/jp/premiumsupport/knowledge-center/s3-access-denied-listobjects-sync/

アクセスポイントにも注意
https://docs.aws.amazon.com/ja_jp/general/latest/gr/rande.html#s3_region

ルーティング

こんな感じの追加する。

routes/api.php
...
Route::post('/photo', 'HogeController@uploadImage');
...

コントローラに直書き

サービス分けたりとかやりたい人は後からしてください。

HogeController.php

    // ----------------------------------------
    // S3 アップロード
    // ----------------------------------------

    /**
     * @param Request $request
     * @return JsonResponse
     */
    public function uploadImage(
        Request $request
    ): JsonResponse {

        $this->validate($request, ['upload_image' => 'required|image']);
        $image = $request->file('upload_image');
        $filename = ((string)(uniqid("img_"))) .".". $image->getClientOriginalExtension();

        $filePath = Storage::disk('s3')
                        ->putFileAs(
                            'uploads'
                            , $image
                            , $filename
                            , [
                                'visibility' => 'public',
                                'ContentType' => 'image/jpeg'
                            ]
                        );
        return response()->json($filePath);
    }

実行

関係ありそうな場所のキャッシュをクリアすること

ルータ周り
php artisan route:clear
設定周り
php artisan config:cache
php artisan serve

postmanとかでpostする。

bodyでform-dataを選んで
keyをupload_imageにしてfileで画像を選択。

http://localhost:8000/api/photo

でpostmanを実行。

スクリーンショット 2019-08-27 10.39.27.png

vue側も

panelIndexはここに書いてないけど、一応この部分は配列でクルクル回るようなコンポーネント。
1個のコンポーネントの時は削って問題なし。

<div class="large-12 medium-12 small-12 cell">
  <label>
    <input type="file" @change="onFileChange(panelIndex, $event)" />
  </label>
</div>

vueのdataにimgFileを定義。
ファイルアップロードされるとonFileChangeが走ってapiを叩きに行く。
laravelからurlが返却される。

...
     data() {
         return {
             imgFile: '',
         }
     },
...
 onFileChange(panelIndex, e){
   this.imgFile = e.target.files[0];
   
   this.submitFile(panelIndex);
 },
 submitFile(panelIndex) {
    let formData = new FormData();
    formData.append('upload_image', this.imgFile);

    axios.post( '/api/photo',
      formData,
      {
        headers: {
            'Content-Type': 'multipart/form-data'
        }
      })
      .then(response => response.data)
      .then(data => {
        this.$set(this.group.reply.panels[panelIndex], 'image_url', data.url)
      })
      .catch(function(){
        console.log('FAILURE!!');
      });
 },

その他参考

tinkerまとめ
http://kz-engineer-scrap.hatenablog.com/entry/2017/03/04/162158

https://qiita.com/D3vel0pper/items/45b2ddbfc68ee9cd7a3c
https://www.ritolab.com/entry/8
https://qiita.com/Ping/items/10ada8d069e13d729701

vueからaxiosで呼ぶ処理も書く時はここが良い。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?