Ziel

Für den Bild-Upload werden wir im ersten Teil das Backend mit Laravel 9 implementieren.

Voraussetzungen

Eine funktionierende Laravel 9 Installation.

Projekt und Datenbank erstellen

Als erstes legen wir einen neuen Projektordner image-upload an:

				
					~/projects$ mkdir image-upload
				
			

Danach wechseln wir in das neue Verzeichnis:

				
					~/projects$ cd image-upload
				
			

Hier erstellen wir ein neues Laravel-Projekt im Ordner backend:

				
					~/projects/image-upload$ laravel new backend
				
			

Die Projektstruktur sieht anschließend so aus:

Bild 1: Projektstruktur nach Ausführen von laravel new backend.
Bild 1: Projektstruktur nach Ausführen von laravel new backend.

Im nächsten Schritt erstellen wir eine SQLite Datenbank im backendVerzeichnis:

				
					~/projects/image-upload$ cd backend && touch database/database.sqlite
				
			
Bild 2: Neue SQLite Datenbank.
Bild 2: Neue SQLite Datenbank.

Im Anschluss muss die Datenbank noch konfiguriert werden. Dies geschieht im Ordner backend im .env-File:

.env
Vorher
				
					DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=backend
DB_USERNAME=root
DB_PASSWORD=
				
			

Dem Schlüssel DB_CONNECTIONweisen wir den Wert sqlitezu.

.env
Änderug
				
					DB_CONNECTION=sqlite

				
			

Dem Schlüssel DB_DATABASEweisen wir den Wert database/database.sqlitezu.

.env
Änderung
				
					DB_DATABASE=database/database.sqlite


				
			

Das .env -file sieht anschließend so aus:

.env
Nachher
				
					DB_CONNECTION=sqlite
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database/database.sqlite
DB_USERNAME=root
DB_PASSWORD=
				
			

Datenbank einrichten

Danach erstellen wir eine neue Migration:

				
					~/projects/image-upload/backend$ php artisan make:migration create_image_table

				
			

Die neue Migration befindet sich im Ordner database/migrations.

Bild 3: Die neue Migrationsdatei.
Bild 3: Die neue Migrationsdatei.

Die Migrationsdatei enthält zwei Funktionen up und down. Im folgenden nehmen wir Änderungen an der upFunktion vor.

Die up Funktion sieht ursprünglich so aus:

Vorher
				
					public function up(): void
{
  Schema::create('image', function (Blueprint $table) {
  $table->id();
  $table->timestamps();
});
}
				
			

Nach Zeile 16 fügen wir die Datenbank-Spalte image_name hinzu:

Änderung
				
					$table->string('image_name');

				
			

Die Funktion up der Migrationsdatei sieht dann final so aus:

Nachher
				
					public function up(): void
{
  Schema::create('image', function (Blueprint $table) {
  $table->id();
  $table->timestamps();
  $table->string('image_name');
});
}
				
			

Im Anschluss können wir die Migration ausführen:

				
					~/projects/image-upload/backend$ php artisan migrate
				
			

Image Controller erstellen

Jetzt brauchen wir noch einen Controller um Daten aus dem Request zu verarbeiten:

				
					~/projects/image-upload/backend$ php artisan make:controller ImageController
				
			

Der Controller befindet sich jetzt inapp/Http/Controllers/ImageController.php:

Bild 4: ImageController.php.
Bild 4: ImageController.php.

Der Image Controller enthält eine leere Klassendefinition:

ImageController.php
Vorher
				
					<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ImageController extends Controller
{
    //
}
				
			

Wir erstellen nun eine neue FunktionsaveImage, die den Request aus dem Frontend verarbeitet:

ImageController.php
Änderung
				
					/**
 * @param Request $request
 */
public function saveImage(Request $request)
{
    $image = $request->file("image");
    $image_name = $request->file("image")->getClientOriginalName();
    
    // Delete old image if it already exists before uploading new image
    // https://laravel.com/docs/9.x/filesystem#delete-a-directory
    if (Storage::exists($image_name)) {
        Storage::delete($image_name);
    }

    // Delete old database entries
    // https://laravel.com/docs/9.x/queries#delete-statements
    DB::table("image")
        ->where("image_name", "=", $image_name)
        ->delete();

    // Upload file to local file system
    // https://laravel.com/docs/9.x/filesystem#file-uploads
    if ($image) {
        Storage::putFileAs(
            "public/",
            new File($image->getRealPath()),
            $image_name);

        // Insert image entry to database
        DB::table("image")
            ->insert([
                "image_name" => $image_name
            ]);
    }
}
				
			

Der komplette ImageController sieht abschließend aus wie folgt:

ImageController.php
Nachher
				
					<?php

namespace App\Http\Controllers;

use Illuminate\Http\File;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

class ImageController extends Controller
{
    /**
     * @param Request $request
     */
    public function saveImage(Request $request)
    {
        $image = $request->file("image");
        $image_name = $request->file("image")->getClientOriginalName();
        
        // Delete old image if it already exists before uploading new image
        // https://laravel.com/docs/9.x/filesystem#delete-a-directory
        if (Storage::exists($image_name)) {
            Storage::delete($image_name);
        }

        // Delete old database entries
        // https://laravel.com/docs/9.x/queries#delete-statements
        DB::table("image")
            ->where("image_name", "=", $image_name)
            ->delete();

        // Upload file to local file system 
        // https://laravel.com/docs/9.x/filesystem#file-uploads
        if ($image) {
            Storage::putFileAs(
                  "public/",
                  new File($image->getRealPath()),
                  $image_name
                );

            // Insert image to database
            DB::table("image")
                ->insert([
                    "image_name" => $image_name
                ]);
        }
    }
}
				
			

Erläuterungen zum Image Controller

In Zeile 17 wird in der Variablen $image das übermittelte Bild gespeichert:

				
					$image = $request->file("image");
				
			

In Zeile 18 wird in der Variablen $image_name der Dateiname des Bildes gespeichert:

				
					$image_name = $request->file("image")->getClientOriginalName();

				
			

In Zeile 22-24 wird das existierende Bild gelöscht, falls es bereits vorhanden ist:

				
					if (Storage::exists($image_name)) {
    Storage::delete($image_name);
}
				
			

Von Zeile 34-38 wird das Bild mit Hilfe der putFileAsMethode im Verzeichnis storage/app/public unter dem originalen Dateinamen gespeichert:

				
					Storage::putFileAs(
  "public/",
  new File($image->getRealPath()),
  $image_name
);
				
			

Von Zeile 41-46 wird der Dateiname des Bildes in der image Datenbank gespeichert:

				
					DB::table("image")
    ->insert([
        "image_name" => $image_name
    ]);
				
			

Das Backend zur Verarbeitung von eingehenden Requests ist nun eingerichtet. Als nächtes muss ein Endpunkt für die API-Route eingerichtet werden. Außerdem wird noch ein Formular im Frontend zum Bilder-Upload benötigt.

Nächster Teil
Laravel
Laravel
Bild-Upload mit Laravel
2/3: API, .env und CORS

In diesem Teil werden die API-Route sowie die Umgebungsvariablen im Backend angelegt.