Goal

In Image upload with Laravel 1/3: Laravel backend we will create a Laravel 9 backend for the image upload.

Prerequisites

A working Laravel 9 installation.

Create project and database

First we will create a new project folder image-upload:

				
					~/projects$ mkdir image-upload
				
			

After that we change to the new directory:

				
					~/projects$ cd image-upload
				
			

Here we create a new laravel project in the folder backend:

				
					~/projects/image-upload$ laravel new backend
				
			

The project structure looks like this now:

Image 1: Project structure after executinglaravel new backend.
Image 1: Project structure after executinglaravel new backend.

In the next step we will create an SQLite database in the backend folder:

				
					~/projects/image-upload$ cd backend && touch database/database.sqlite
				
			
Image 2: New SQLite database.
Image 2: New SQLite database.

In the following we will configure the database. This will happen in the folder backend in the .env-File:

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

For the key DB_CONNECTION we assign the value sqlite.

.env
Change
				
					DB_CONNECTION=sqlite

				
			

For the key DB_DATABASE we assign the value database/database.sqlite.

.env
Change
				
					DB_DATABASE=database/database.sqlite


				
			

The .env -file finally looks like this:

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

Configure database

After that we we will create a new Migration:

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

				
			

The new migration is located in the folder database/migrations.

Image 3: The new migration file.
Image 3: The new migration file.

The migration file contains two functions up and down. In the following we will make changes to the upfunction.

The up function originally looks like this:

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

After line 16 we will insert the database column image_name :

Change
				
					$table->string('image_name');

				
			

The function up of the migration file looks eventually like this:

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

In the following we can run the migration:

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

Create image controller

Now we need a Controller to handle data from the Request:

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

The Controller is now located in app/Http/Controllers/ImageController.php:

Image 4: ImageController.php.
Image 4: ImageController.php.

The Image Controller contains an empty class declaration:

ImageController.php
Before
				
					<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ImageController extends Controller
{
    //
}
				
			

We create a new function saveImage, handling the Request coming from the frontend:

ImageController.php
Change
				
					/**
 * @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
            ]);
    }
}
				
			

The entire ImageController looks as follows:

ImageController.php
After
				
					<?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
                ]);
        }
    }
}
				
			

Explanation for the Image Controller

The transferred image gets saved in line In line 17 in the variable $image:

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

In line 18 the file name of the image is saved in the variable $image_name:

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

				
			

If the image already exists it will be deleted in line 22-24:

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

From lines 34-38 the image gets saved with the help of putFileAs method in the directory named after it’s original file name storage/app/public:

				
					Storage::putFileAs(
  "public/",
  new File($image->getRealPath()),
  $image_name
);
				
			
From line 41 to line 46 the image file name is saved in the image database:
				
					DB::table("image")
    ->insert([
        "image_name" => $image_name
    ]);
				
			
Next part
laravel logo
Laravel
Image upload with Laravel
2/3: API, .env and CORS
In this section we will implement the API route and the environment variables in the backend.