🙆‍♀️

Vue.jsから複数の画像をLaravelに送り保存する

2021/08/23に公開

複数の画像を一度にアップロードしたい場合があると思います。
Laravel×Vue.jsで実際に試してみたので、メモがてら残しておきたいと思います。

まずは、画像をアップロードするところのHTMLです

<template>
  <div v-for="(file, index) in files">
    <label>ファイルを選択する</label>
    <input type="file" @change="onFileChange($event, file, index)")/>
  </div>
  
  <button @click="upload">送信</button>
</template>

<script>
export default {
  data() {
    return {
      files: []
    }
  },
  methods: {
    upload() {
      // ヘッダー定義
      const config = {
        headers: {
          'content-type': 'multipart/form-data'
        }
      };
      
      let formData = new FormData();
      let requestFiles = this.files.filter((file) => file) // ファイルがあるものだけを取得
      requestFiles.forEach((file, index) => {
        formData.append('files[' + index + ']', file) // formDataに追加していく
      })
      axios.post(`/api/image`, formData , config).then(rs => {
        console.log(rs.data)
      })
    }
  }
}

ポイントは formData を用意して、そこに画像を突っ込んでいくことなのですが、
複数画像をアップロードする場合は、今回はパラメータの名前をfilesにしているので files という配列に画像を入れていって、filesをformDataにセットします。

ちなみに、なんかうまくいっているような気がしないなーという場合はformDataの中身をこれで出力することができます

console.log(...formData.entries());

Laravel側このようにします。

public function postFiles(Request $request) 
{
    $files = request()->file('files');
    
    foreach ($files as $index => $image) {
        $path = Storage::disk("public")->putFile('file', $image);
        $imagePath = "/storage/$path";
	.
	.
	.
    }
}

ポイントは、 vueから送られてきたfilesを取得します。その後foreachで回しながら画像を1つずつStorageに入れてパスを取得します。

このあとはそのパスをDBに入れたりすればOKです。

これで複数画像のアップロードが出来ました、
デフォルトでは、
php.iniの設定でマックスで2MBまでしかファイルをアップロードできないので、2MB以上ファイルをアップロードしたい場合は、php.iniの設定を変えてサーバーをリスタートしてみてください。

Discussion