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:
Im nächsten Schritt erstellen wir eine SQLite Datenbank im backend
Verzeichnis:
~/projects/image-upload$ cd backend && touch database/database.sqlite
Im Anschluss muss die Datenbank noch konfiguriert werden. Dies geschieht im Ordner backend
im .env
-File:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=backend
DB_USERNAME=root
DB_PASSWORD=
Dem Schlüssel DB_CONNECTION
weisen wir den Wert sqlite
zu.
DB_CONNECTION=sqlite
Dem Schlüssel DB_DATABASE
weisen wir den Wert database/database.sqlite
zu.
DB_DATABASE=database/database.sqlite
Das .env
-file sieht anschließend so aus:
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
.
Die Migrationsdatei enthält zwei Funktionen up
und down
. Im folgenden nehmen wir Änderungen an der up
Funktion vor.
Die up
Funktion sieht ursprünglich so aus:
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:
$table->string('image_name');
Die Funktion up
der Migrationsdatei sieht dann final so aus:
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
:
Der Image Controller enthält eine leere Klassendefinition:
Wir erstellen nun eine neue FunktionsaveImage
, die den Request aus dem Frontend verarbeitet:
/**
* @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:
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 putFileAs
Methode 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.
In diesem Teil werden die API-Route sowie die Umgebungsvariablen im Backend angelegt.