In this article I am going to show you how to upload image / file in Laravel 10 projects.
For this topic, you will learn a full CRUD operation example in Laravel, you can also find the CRUD operation I published on this website, but without image upload / file upload functionality.
If you are facing with a challenge that does not requires file upload, check it out here.
Step 1: Install Laravel 10
For this mini project I will work on a blog that would have title, description, image, created_at, and updated_at fields.
Firstly, we need to install Laravel 10 project by the following command.
composer create-project laravel/laravel blog --prefer-dist
Step 2: Connect Database with Laravel
At this step, set up your database configurations.
Go to your project root directory open .env file and change the following properties according your database settings.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=blog
DB_USERNAME=root
DB_PASSWORD=
Step 3: Create a migration file
Now, create a migration file to generate a table for our project by migrating.
Use the below command to create a migration file
php artisan make:migration create_blog_table
This command will create a migration file into “database/migrations” directory, find the migration file which contains create_blog_table term in it’s name.
Then, open the migration file and paste the following codes into it.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('blog', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description');
$table->string('image');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('blog');
}
};
Save your migration file, and run the below command to create the table for our project.
php artisan migrate
If you have made any changes on previous migration files, and you want to replace the changes with previous one, use the below command.
php artisan migrate:refresh
This command will refresh your migration.
After you are done with database stuff, now it’s time to create our controller, mode, and views.
Step 4: Create BlogController
What do controllers do? Well, controllers are responsible for handling group of request logics.
To handle requests, like reading, writing, updating, and so on.
To create a controller in Laravel 10 we will use the following command.
php artisan make:controller BlogController
The above mentioned command will create a file into “app/Http/Controllers” directory.
Open the mentioned file and past the following codes into it.
<?php
namespace App\Http\Controllers;
use App\Models\Blog;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class BlogController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(): View
{
$blogs = Blog::latest()->paginate(5);
return view('blogs.index', compact('blogs'))
->with('i', (request()->input('page', 1) - 1) * 5);
}
/**
* Show the form for creating a new resource.
*/
public function create(): View
{
return view('blogs.create');
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request): RedirectResponse
{
$request->validate([
'title' => 'required',
'description' => 'required',
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
$imageName = time() . '.' . $request->image->extension();
$request->image->move(public_path('images'), $imageName);
$imgPath = "images/" . $imageName;
$data = array(
'title' => $request->title,
'image' => $imgPath,
'description' => $request->description
);
Blog::create($data);
return redirect()->route('blogs.index')
->with('success', 'Blog article created successfully.');
}
/**
* Display the specified resource.
*/
public function show(Blog $blog): View
{
return view('blogs.show', compact('blog'));
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Blog $blog): View
{
return view('blogs.edit', compact('blog'));
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, blog $blog): RedirectResponse
{
$request->validate([
'title' => 'required',
'description' => 'required',
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
$imageName = time() . '.' . $request->image->extension();
$request->image->move(public_path('images'), $imageName);
$imgPath = "images/" . $imageName;
$data = array(
'title' => $request->title,
'image' => $imgPath,
'description' => $request->description
);
$blog->update($data);
return redirect()->route('blogs.index')
->with('success', 'blog updated successfully');
}
/**
* Remove the specified resource from storage.
*/
public function destroy(blog $blog): RedirectResponse
{
$blog->delete();
return redirect()->route('blogs.index')
->with('success', 'blog article deleted successfully');
}
}
Step 5: Create Route files
For routing of Image / File upload in Laravel 10 you need to update your route files from “routes/web.php” file in your Laravel 10 root directory.
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\BlogController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/
Route::resource('blogs', BlogController::class);
Step 5: Create Views
layout.php
<!DOCTYPE html>
<html>
<head>
<title>Laravel 10 CRUD Application - ItSolutionStuff.com</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
@yield('content')
</div>
</body>
</html>
index.php
@extends('blogs.layout')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Laravel 10 CRUD Example</h2>
</div>
<div class="pull-right">
<a class="btn btn-success" href="{{ route('blogs.create') }}"> Create New blog</a>
</div>
</div>
</div>
@if ($message = Session::get('success'))
<div class="alert alert-success">
<p>{{ $message }}</p>
</div>
@endif
<table class="table table-bordered">
<tr>
<th>No</th>
<th>Title</th>
<th>description</th>
<th>Date Added</th>
<th width="280px">Action</th>
</tr>
@foreach ($blogs as $blog)
<tr>
<td>{{ ++$i }}</td>
<td>{{ $blog->title }}</td>
<td>{{ $blog->description }}</td>
<td>{{ $blog->created_at }}</td>
<td>
<form action="{{ route('blogs.destroy',$blog->id) }}" method="POST">
<a class="btn btn-info" href="{{ route('blogs.show',$blog->id) }}">Show</a>
<a class="btn btn-primary" href="{{ route('blogs.edit',$blog->id) }}">Edit</a>
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
@endforeach
</table>
{!! $blogs->links() !!}
@endsection
create.php
@extends('blogs.layout')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2 class="inline">Add New blog <a class="btn btn-primary inline" href="{{ route('blogs.index') }}"> Back</a></h2>
</div>
</div>
</div>
@if ($errors->any())
<div class="alert alert-danger">
<strong>Opps!</strong> You are missing something out.<br><br>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('blogs.store') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Title:</strong>
<input type="text" name="title" class="form-control" placeholder="Title">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>image:</strong>
<input type="file" name="image" class="form-control" placeholder="Title">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Description:</strong>
<textarea class="form-control" style="height:150px" name="description" placeholder="Descriptions"></textarea>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 ">
<button type="submit" class="btn btn-primary">Save</button>
</div>
</div>
</form>
@endsection
show.php
@extends('blogs.layout')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2> Show Product</h2>
</div>
<div class="pull-right">
<a class="btn btn-primary" href="{{ route('blogs.index') }}"> Back</a>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Title:</strong>
{{ $blog->title }}
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>image:</strong><br>
<img src=" {{asset($blog->image) }}" height="300px" width="450px">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Description:</strong>
{{ $blog->description }}
</div>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Published on:</strong>
{{ $blog->created_at }}
</div>
</div>
</div>
@endsection
edit.php
@extends('blogs.layout')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Edit blog <a class="btn btn-primary" href="{{ route('blogs.index') }}"> Back</a></h2>
</div>
</div>
</div>
@if ($errors->any())
<div class="alert alert-danger">
<strong>Opps!</strong> It looks like you are missing something out.<br><br>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('blogs.update',$blog->id) }}" method="POST" enctype="multipart/form-data">
@csrf
@method('PUT')
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Title:</strong>
<input type="text" name="title" value="{{ $blog->title }}" class="form-control" placeholder="Title">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Image:</strong>
<input type="file" name="image" class="form-control">
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Description:</strong>
<textarea class="form-control" style="height:150px" name="description" placeholder="Detail">{{ $blog->description }}</textarea>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<button type="submit" class="btn btn-primary">Update</button>
</div>
</div>
</form>
@endsection
Step7: Final Step
You are done!
Now start your Laravel project by below command
php artisan serve
visit the below link and see the result.
http://localhost:8000/blogs
Hope you have learned something new about Image / File upload in Laravel 10 and thanks for reading.
Please comment your questions in the comment box bellow
2 thoughts on “Image / File upload in Laravel 10”