laravellaravel-8

Multiple images in multiple arrays with formData in Laravel 8


I am trying to upload multiple images that I am sending from a form using formData. The form has several sections: The following example would only be 2 sections:

<form class="p-1" method="POST" enctype="multipart/form-data">
 @csrf
<div class="accordion-body">
        <input type="hidden" name="estancias[0][home_space]" value="1" />

        <div class="row align-items-center mb-3">
          <div class="col-6 col-md-3 offset-md-3">
            <label for="aparato_aa_calefaccion" class="form-label fs-4"
              >Aparato AA / Calefacción:</label
            >
          </div>
          <div class="col-6 col-md-2">
            <select
              class="form-select fs-3"
              name="estancias[0][conditions][aparato_aa_calefaccion]"
              id="aparato_aa_calefaccion"
            >
              <option value="" selected=""></option>
              <option value="1">Bien</option>
              <option value="2">Regular</option>
              <option value="3">Mal</option>
            </select>
          </div>
        </div>
        <!-- Aquí agregamos la opción para subir fotos -->
        <div class="col-12 col-md-6 offset-md-3 mt-3">
          <label for="formFileMultiple" class="form-label fs-4">Fotos:</label>
          <input
            class="form-control form-control-lg"
            type="file"
            name="estancias[0][photos][]"
            id="formFileMultiple"
            multiple=""
          />
        </div>
      </div>

      <div class="accordion-body">
        <input type="hidden" name="estancias[1][home_space]" value="2" />
        <div class="row align-items-center mb-3">
          <div class="col-6 col-md-3 offset-md-3">
            <label for="bombillas" class="form-label fs-4">Bombillas:</label>
          </div>
          <div class="col-6 col-md-2">
            <select
              class="form-select fs-3"
              name="estancias[1][conditions][bombillas]"
              id="bombillas"
            >
              <option value="" selected=""></option>
              <option value="1">Bien</option>
              <option value="2">Regular</option>
              <option value="3">Mal</option>
            </select>
          </div>
        </div>
        <div class="col-12 col-md-6 offset-md-3 mt-3">
          <label for="formFileMultiple" class="form-label fs-4">Fotos:</label>
          <input
            class="form-control form-control-lg"
            type="file"
            name="estancias[1][photos][]"
            id="formFileMultiple"
            multiple=""
          />
        </div>
      </div>
</form>

The form has more fields but I have only included the necessary ones so that the concept is understood

I also add the array that comes to the request:

request

I am trying to obtain the images to save them locally and register them in the database (using querybuilder)

public function store(Request $request)
    {
        // Devolver las URLs de los archivos almacenados
        $response = [
            'status' => 'success',
            'data' => [
                'request' => $request->all(),
                'message' => 'recibido',
            ],
        ];

        return response()->json($response, 200);

I've tried a couple of things but couldn't, thanks

I don't really understand how to treat images in Laravel


Solution

  • Ensure your filesystems.php configuration is set up to store files in the public directory:

    'disks' => [
        'public' => [
            'driver' => 'local',
            'root' => storage_path('app/public'),
            'url' => env('APP_URL').'/storage',
            'visibility' => 'public',
        ],
    ],
    

    For handling the image and saving it from the database:

    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\DB;
    use Illuminate\Support\Facades\Storage;
    
    public function store(Request $request)
    {
        $data = $request->all(); // Get all the form data
    
        // Initialize an array to store the file paths
        $filePaths = [];
    
        foreach ($data['estancias'] as $index => $estancia) {
            if (isset($estancia['photos'])) {
                foreach ($estancia['photos'] as $photo) {
                    // Store the file locally
                    $filePath = $photo->store('photos', 'public'); // Store in 'storage/app/public/photos'
    
                    // Add the file path to the array
                    $filePaths[] = [
                        'home_space' => $estancia['home_space'],
                        'file_path' => $filePath,
                        'created_at' => now(),
                        'updated_at' => now(),
                    ];
                }
            }
        }
    
        // Insert the file paths into the database
        DB::table('photos')->insert($filePaths); // here put you own table name
    
        // Respond with a success message
        $response = [
            'status' => 'success',
            'data' => [
                'request' => $request->all(),
                'message' => 'Images uploaded and saved successfully!',
            ],
        ];
    
        return response()->json($response, 200);
    }