Creating a user update profile in Laravel 11 application in which you can change username, email, password, mobile number, profile picture, etc. is a very common requirement in Laravel web applications.
Let’s start to build user update profile feature in laravel applications:
Step 1 – Set Up Laravel 11
Start by installing Laravel 11 using composer command:
composer create-project --prefer-dist laravel/laravel BootStrapAuth
Step 2 – Set Up Database
Edit .env
file and configure database in it:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=your_database_username
DB_PASSWORD=your_database_password
Step 3 – Install Laravel UI
Run the following command to install Laravel UI, it provides a way to scaffold authentication:
composer require laravel/ui
Step 4 – Generate Authentication Scaffolding
Run the Laravel UI command to generate authentication scaffolding with Bootstrap styling:
php artisan ui bootstrap --auth
npm install && npm run dev
Step 5 – Create Migration
Create a migration file to add fields in database table:
php artisan make:migration add_new_fields_users
Edit database/migrations/_add_new_fields_users.php
file, and add the following code in 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::table('users', function (Blueprint $table) {
$table->string('avatar')->nullable();
$table->string('phone')->nullable();
$table->string('city')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn(['avatar', 'phone', 'city']);
});
}
}
Run the migration command to create tables for authentication in database:
php artisan migrate
Step 6 – Update User Model
Edit app/Models/User.php
file, and add the following properties in it:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'password',
'avatar',
'phone',
'city',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
Step 7 – Create Routes
Create routes in routes/web.php
file to handle update user profile requests:
<?php
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Route::get('/profile', [App\Http\Controllers\ProfileController::class, 'index'])->name('user.profile');
Route::post('/profile', [App\Http\Controllers\ProfileController::class, 'store'])->name('user.profile.store');
Step 8 – Create Controller
Run the following command to create a controller file that manage update user profile logic in it:
app/Http/Controllers/ProfileController.php
Edit app/Http/Controllers/ProfileController.php
file, and implement update user profile method in it:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Hash;
class ProfileController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* @return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
return view('profile');
}
/**
* Write code on Method
*
* @return response()
*/
public function store(Request $request)
{
$request->validate([
'name' => 'required',
'email' => 'required',
'confirm_password' => 'required_with:password|same:password',
'avatar' => 'image',
]);
$input = $request->all();
if ($request->hasFile('avatar')) {
$avatarName = time().'.'.$request->avatar->getClientOriginalExtension();
$request->avatar->move(public_path('avatars'), $avatarName);
$input['avatar'] = $avatarName;
} else {
unset($input['avatar']);
}
if ($request->filled('password')) {
$input['password'] = Hash::make($input['password']);
} else {
unset($input['password']);
}
auth()->user()->update($input);
return back()->with('success', 'Profile updated successfully.');
}
}
Step 9 – Create Blade File
Create profile.blade.php
file in resources/views directory, and add the following view code in it:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-12">
<div class="card">
<div class="card-header">{{ __('Profile') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('user.profile.store') }}" enctype="multipart/form-data">
@csrf
@if (session('success'))
<div class="alert alert-success" role="alert" class="text-danger">
{{ session('success') }}
</div>
@endif
<div class="row">
<div class="mb-3 col-md-6">
<label for="name" class="form-label">Avatar: </label>
<input id="avatar" type="file" class="form-control @error('avatar') is-invalid @enderror" name="avatar" value="{{ old('avatar') }}" autocomplete="avatar">
@error('avatar')
<span role="alert" class="text-danger">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="mb-3 col-md-6">
<img src="/avatars/{{ auth()->user()->avatar }}" style="width:80px;margin-top: 10px;">
</div>
</div>
<div class="row">
<div class="mb-3 col-md-6">
<label for="name" class="form-label">Name: </label>
<input class="form-control" type="text" id="name" name="name" value="{{ auth()->user()->name }}" autofocus="" >
@error('name')
<span role="alert" class="text-danger">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="mb-3 col-md-6">
<label for="email" class="form-label">Email: </label>
<input class="form-control" type="text" id="email" name="email" value="{{ auth()->user()->email }}" autofocus="" >
@error('email')
<span role="alert" class="text-danger">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row">
<div class="mb-3 col-md-6">
<label for="password" class="form-label">Password: </label>
<input class="form-control" type="password" id="password" name="password" autofocus="" >
@error('password')
<span role="alert" class="text-danger">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="mb-3 col-md-6">
<label for="confirm_password" class="form-label">Confirm Password: </label>
<input class="form-control" type="password" id="confirm_password" name="confirm_password" autofocus="" >
@error('confirm_password')
<span role="alert" class="text-danger">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row">
<div class="mb-3 col-md-6">
<label for="phone" class="form-label">Phone: </label>
<input class="form-control" type="text" id="phone" name="phone" value="{{ auth()->user()->phone }}" autofocus="" >
@error('phone')
<span role="alert" class="text-danger">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="mb-3 col-md-6">
<label for="city" class="form-label">City: </label>
<input class="form-control" type="text" id="city" name="city" value="{{ auth()->user()->city }}" autofocus="" >
@error('city')
<span role="alert" class="text-danger">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-0">
<div class="col-md-12 offset-md-5">
<button type="submit" class="btn btn-primary">
{{ __('Upload Profile') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
And edit resources/views/layouts/app.blade.php
file, and update profile link in it:
...
<!-- Right Side Of Navbar -->
<ul class="navbar-nav ms-auto">
<!-- Authentication Links -->
@guest
@if (Route::has('login'))
<li class="nav-item">
<a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
</li>
@endif
@if (Route::has('register'))
<li class="nav-item">
<a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
</li>
@endif
@else
<li class="nav-item dropdown">
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
<img src="/avatars/{{ Auth::user()->avatar }}" style="width: 30px; border-radius: 10%">
{{ Auth::user()->name }}
</a>
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<a href="{{ route('user.profile') }}" class="dropdown-item">Profile</a>
<a class="dropdown-item" href="{{ route('logout') }}"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
{{ __('Logout') }}
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
@csrf
</form>
</div>
</li>
@endguest
</ul>
Step 10 – Test
Run the following command to start application server:
php artisan serve
Hit http://127.0.0.1:8000/
url on browser for testing: