Observer in Laravel - Laravel Advanced Topics - Beyond the documentation
Today, we'll learn a beautiful feature of Laravel PHP Framework - Model Observer. Let's dive into this quickly.
What is Observer
Observer is an event listening class that will listen and can do action of any changes of that regarding Model.
That means, when we need to do something after a Model changes or after a model event occurs. Then, we can use Observer to listen to that change and can do any database operation easily with that model. It's super useful for big projects, where you need to do many stuffs after a model is being created.
How to create an Observer in Laravel
Observer can be created very easily with an Artisan command. Like, we want to create an UserObserver
, which will listen to any changes on User
Model.
// Demo to Create a UserObserver for User Model
php artisan make:observer UserObserver --model=User
So, here we're giving an Observer name and specifying which Model it will listen. In the above case, it will create an UserObserver
and will listen any changes on User
Model.
How is an Observer class look like
This will create a fresh UserObserver
in app/Observers/UserObserver.php
. Let's take a look at the UserObserver
class.
<?php
namespace App\Observers;
use App\Models\User;
class UserObserver
{
/**
* Handle the User "created" event.
*
* @param \App\Models\User $user
* @return void
*/
public function created(User $user)
{
//
}
/**
* Handle the User "updated" event.
*
* @param \App\Models\User $user
* @return void
*/
public function updated(User $user)
{
//
}
/**
* Handle the User "deleted" event.
*
* @param \App\Models\User $user
* @return void
*/
public function deleted(User $user)
{
//
}
/**
* Handle the User "restored" event.
*
* @param \App\Models\User $user
* @return void
*/
public function restored(User $user)
{
//
}
/**
* Handle the User "force deleted" event.
*
* @param \App\Models\User $user
* @return void
*/
public function forceDeleted(User $user)
{
//
}
}
Look, there are some functions like created
, updated
and so all. It's self-explanatory in the class name by itself.
For example - created
will be called when Modal User
is being created.
How many events in an Observer class
Observer class actually has more events, not only limited to the above events. Let's grab the default of here.
created
- When a modal is created, this function will be called simultaneously. For example, when an$user->save();
function will be called, A user will saved and then it will come here withUser
model in it's$use
r variable. So, we can get access the last changed model data here. Like, we can get$user->name
here easily and also can modify and re-save the data again and do whatever we want with that data.updated
- Called when a model is being updated. For example, when called the above function -save()
andupdate()
, this event will fired.$user = User::find(1);
$user->save()
;- or,
User::where()->update([//...]);
deleted
- It's self-explanatory, when a delete() function will called on any model, it will be fired up.restored
- It's used when we useSoftDelete
in our model. When we use trash system of data in our model, this will be fired up after a restore of a specific modal data.forceDeleted
- It'll be fired up, when we useforceDelete()
function on any model.
These are by default event. There's more we can get in Laravel observer. Let's grab them all.
creating
created
saving
saved
deleting
deleted
updating
updated
restoring
restored
forceDeleted
retreived
And I think, these functions are self-explanatory to self-learn.
Next,
We need to register this observer in EventServiceProvider
class inside the boot()
function of app/Providers/EventServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;
// Import the classes
use App\Models\User;
use App\Observers\UserObserver;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
];
/**
* Register any events for your application.
*
* @return void
*/
public function boot()
{
User::observe(UserObserver::class); // Use Here
}
}
That's done. Our User
model is now registered to UserObserver. UserObserver
can detect everything and can take action of User
model.
How to use Observer in a real-life project
Problem 1:
We need to add a Mr
text before user's name when registered. Like after saved to database, we will update user name to something else.
It's very simple to do that.Here is our created()
function inside UserObserver
.
/**
* Handle the User "created" event.
*
* @param \App\Models\User $user
* @return void
*/
public function created(User $user)
{
$user->name = "Mr. " . $user->name;
$user->save();
}
So, to test it, create a User model. I'll use tinker commands to do that.
Open tinker terminal -
php artisan tinker
Now, save a new user.
$user = new User();
$user->name = "Akash";
$user->email = "akash@gmail.com";
$user->password = Hash::make('123456');
$user->save();
Now check the database. Name
is not Akash
. Name is - modified to Mr. Akash
.
That's pretty awesome, right.
Problem 2:
Assume, we're using Facebook. Where every time User updated his profile picture, a new post creates. And we can see that on post feed wall.
So, we'll implement these things here.
- We'll create a user, and it would create a Post also with user ID and data
- We'll update a user, and it would create another post with updated information
First, Change Our UserObserver
to this, so that we could add new Post after created()
and updated()
event.
<?php
namespace App\Observers;
use App\Models\Post;
use App\Models\User;
class UserObserver
{
/**
* Handle the User "created" event.
*
* @param \App\Models\User $user
* @return void
*/
public function created(User $user)
{
// $user->name = "Mr. " . $user->name;
// $user->save();
$title = 'New User ' . $user->name . ' Created successfully';
$description = 'New User ' . $user->name . ' Created. Created - ' . $user->created_at->diffForHumans();
Post::create([
'title' => $title,
'description' => $description,
'user_id' => $user->id,
'category_id' => 1
]);
}
/**
* Handle the User "updated" event.
*
* @param \App\Models\User $user
* @return void
*/
public function updated(User $user)
{
$title = 'User ' . $user->name . ' Updated successfully';
$description = 'User ' . $user->name . ' Updated. Updated time - ' . $user->updated_at->diffForHumans();
Post::create([
'title' => $title,
'description' => $description,
'user_id' => $user->id,
'category_id' => 1,
]);
}
/**
* Handle the User "deleted" event.
*
* @param \App\Models\User $user
* @return void
*/
public function deleted(User $user)
{
//
}
/**
* Handle the User "restored" event.
*
* @param \App\Models\User $user
* @return void
*/
public function restored(User $user)
{
//
}
/**
* Handle the User "force deleted" event.
*
* @param \App\Models\User $user
* @return void
*/
public function forceDeleted(User $user)
{
//
}
}
Before running Artisan command insert, let's check our Post model class to accept fillable property.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = [
'title',
'description',
'category_id',
'user_id'
];
}
Great, all set up is done. Now just do some artisan command to check if Our desired posts added or not -
php artisan tinker;
// Create New User
$user = new User();
$user->name = "Fabliha";
$user->email = "fabliha@gmail.com";
$user->password = Hash::make('123456');
$user->save();
// Update a User
$user = User::orderBy('id', 'desc')->first();
$user->name = "Fabliha Afia";
$user->save();
Great, now check the database, or do the artisan command to check the last posts -
php artisan tinker;
// Get last two latest post
Post::orderBy('id', 'desc')->limit(2)->get();
=> Illuminate\Database\Eloquent\Collection {#4136
all: [
App\Models\Post {#3412
id: 20002,
title: "User Fabliha Afia Updated successfully",
description: "User Fabliha Afia Updated. Updated time - 1 second ago",
user_id: 1004,
category_id: 1,
created_at: "2021-07-13 03:58:38",
updated_at: "2021-07-13 03:58:38",
},
App\Models\Post {#4345
id: 20001,
title: "New User Afia Created successfully",
description: "New User Afia Created. Created - 1 second ago",
user_id: 1004,
category_id: 1,
created_at: "2021-07-13 03:53:59",
updated_at: "2021-07-13 03:53:59",
},
],
}
Wow, we've added some posts based on this. And we can do many things in this observer.
I think it's pretty enough to start your advanced implementation using Laravel observer.
Next, Documented on Laravel
Scenario 1:
If we want to make a model and don't need to do any action on Observer, then we could use simply saveQuietly()
function.
$user = User::findOrFail(1);
$user->name = 'Updated User';
$user->saveQuietly();
Scenario 2:
We want to run our Sales Transaction's observer after getting a valid commit() of Laravel Transaction
<?php
namespace App\Observers;
use App\Models\Transaction;
class TransactionObserver
{
/**
* Handle events after all transactions are committed.
*
* @var bool
*/
public $afterCommit = true;
/**
* Handle the User "created" event.
*
* @param \App\Models\Transaction $transaction
* @return void
*/
public function created(Transaction $transaction)
{
//
}
}
Laravel Observer Docs - https://laravel.com/docs/8.x/eloquent#observers
You can do the following things on Laravel Model Observer.
- Can Make a Log table where you would log of every activity of your site. After anything happens to model, you'll store that in Log. So, that you could make a log system easily with this.
- Sometimes, we need to process data after it's insertion on database.
- Like, we have some transactions and we would put total transaction amount to another Ledger balance of accounting. Then we could do it here. So transaction functionality could separate from Ledger Logic.
- We would update
deleted_by
,updated_by
property of any model by using this.
Download Github Source Code - https://github.com/ManiruzzamanAkash/Laravel-Advanced-Topics/tree/observer-example
Thanks for staying with me about learning of Laravel Observer's advanced topic discussion.
Popular Tutorials
All Tutorials in this playlist
Popular Tutorials
Categories
-
Artificial Intelligence (AI)
11
-
Bash Scripting
1
-
Bootstrap CSS
0
-
C Programming
14
-
C#
0
-
ChatGPT
1
-
Code Editor
2
-
Computer Engineering
3
-
CSS
28
-
Data Structure and Algorithm
18
-
Design Pattern in PHP
2
-
Design Patterns - Clean Code
1
-
E-Book
1
-
Git Commands
1
-
HTML
19
-
Interview Prepration
2
-
Java Programming
0
-
JavaScript
12
-
Laravel PHP Framework
37
-
Mysql
1
-
Node JS
1
-
Online Business
0
-
PHP
28
-
Programming
8
-
Python
12
-
React Js
19
-
React Native
1
-
Redux
2
-
Rust Programming
15
-
SEO - Search Engine Optimization
1
-
Tailwind CSS
1
-
Typescript
10
-
Uncategorized
0
-
Vue JS
1
-
Windows Operating system
1
-
Woocommerce
1
-
WordPress Development
2
Tags
- Artificial Intelligence (AI)
- Bash Scripting
- Business
- C
- C Programming
- C-sharp programming
- C++
- Code Editor
- Computer Engineering
- CSS
- Data Structure and Algorithm
- Database
- Design pattern
- Express JS
- git
- Git Commands
- github
- HTML
- Java
- JavaScript
- Laravel
- Mathematics
- MongoDB
- Mysql
- Node JS
- PHP
- Programming
- Python
- React Js
- Redux
- Rust Programming Language
- SEO
- TypeScript
- Vue JS
- Windows terminal
- Woocommerce
- WordPress
- WordPress Plugin Development