āĻĒā§āϰāĻļā§āύ 1: GET āĻāĻŦāĻ POST āĻāϰ āĻŽāϧā§āϝ⧠āĻĒāĻžāϰā§āĻĨāĻā§āϝ āĻā§?
āĻāϤā§āϤāϰ:
GET: āĻāĻāĻāϰāĻāϞ āĻāϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻĄā§āĻāĻž āĻĒāĻžāĻ āĻžāϝāĻŧ, āϏāĻžāϧāĻžāϰāĻŖāϤ āĻĄā§āĻāĻž āĻĒāĻĄāĻŧāĻžāϰ āĻāύā§āϝāĨ¤
POST: body āĻāϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻĄā§āĻāĻž āĻĒāĻžāĻ āĻžāϝāĻŧ, āϏāĻžāϧāĻžāϰāĻŖāϤ āύāϤā§āύ āĻĄā§āĻāĻž āϤā§āϰāĻŋ āĻŦāĻž āϏāĻžāĻŦāĻŽāĻŋāĻ āĻāϰāĻžāϰ āĻāύā§āϝāĨ¤
āĻĒā§āϰāĻļā§āύ ⧍: āĻāĻĒāύāĻŋ āĻā§āĻāĻžāĻŦā§ Laravel-āĻ Route Model Binding
āĻāĻŽāĻĒā§āϞāĻŋāĻŽā§āύā§āĻ āĻāϰāĻŦā§āύ? āĻāĻāĻāĻŋ āĻāĻĻāĻžāĻšāϰāĻŖ āĻĻāĻŋāϤ⧠āĻĒāĻžāϰā§āύ āĻāĻŋ?
āĻāϤā§āϤāϰ:
Laravel-āĻ Route Model Binding
āĻāĻŽāύ āĻāĻāĻāĻŋ āĻĢāĻŋāĻāĻžāϰ āϝāĻž āĻ
āĻā§āĻŽā§āĻāĻŋāĻāĻāĻžāĻŦā§ URI-āϤ⧠āĻĻā§āĻā§āĻž ID āĻŦāĻž slug āĻ
āύā§āϝāĻžā§ā§ āϏāĻāĻļā§āϞāĻŋāώā§āĻ āĻŽāĻĄā§āϞā§āϰ āĻāύāϏā§āĻā§āϝāĻžāύā§āϏ āĻā§āĻāĻā§ āĻāύ⧠āĻāύā§āĻā§āϰā§āϞāĻžāϰ⧠āĻĒāĻžāϏ āĻāϰ⧠āĻĻā§ā§āĨ¤ āĻāϤ⧠āĻāϰ⧠āĻāϞāĻžāĻĻāĻž āĻāϰ⧠find() āĻŦāĻž where()
āĻŽā§āĻĨāĻĄ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻšā§ āύāĻžāĨ¤
Laravel-āĻ āĻĻā§āĻ āϧāϰāύā§āϰ Route Model Binding āĻāĻā§:
Implicit Binding (āϏā§āĻŦā§āĻāĻā§āϰāĻŋā§)
Explicit Binding (āϏā§āĻĒāώā§āĻāĻāĻžāĻŦā§)
â āĻāĻĻāĻžāĻšāϰāĻŖ: Implicit Route Model Binding
āϧāϰāĻž āϝāĻžāĻ, āĻāĻŽāĻžāĻĻā§āϰ āĻāĻāĻāĻŋ Post
āĻŽāĻĄā§āϞ āĻāĻā§āĨ¤
đ¸ Route:
use App\Models\Post;
Route::get('/posts/{post}', [PostController::class, 'show']);
āĻāĻāĻžāύ⧠{post}
āĻšāϞ route parameter āĻāĻŦāĻ Laravel āĻŦā§āĻā§ āύāĻŋāĻŦā§ āϝ⧠āĻāĻāĻŋ App\Models\Post
āĻŽāĻĄā§āϞ āĻāϰ instanceāĨ¤
đ¸ Controller:
public function show(Post $post)
{
return view('posts.show', compact('post'));
}
āĻāĻāĻžāύ⧠$post
āĻ
āĻā§āĻŽā§āĻāĻŋāĻāĻāĻžāĻŦā§ āĻāĻ ID āĻ
āύā§āϝāĻžā§ā§ āĻĄāĻžāĻāĻžāĻŦā§āĻ āĻĨā§āĻā§ āĻā§āĻāĻā§ āĻāύāĻž āĻšāĻŦā§āĨ¤ āϝāĻĻāĻŋ ID āĻŽā§āϞ⧠āύāĻž, āϤāĻžāĻšāϞ⧠404 error āĻĻā§āĻā§āĻž āĻšāĻŦā§āĨ¤
â āĻāĻĻāĻžāĻšāϰāĻŖ: Explicit Route Model Binding
āĻāĻāĻŋ āϤāĻāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āĻšā§ āϝāĻāύ āĻāĻĒāύāĻŋ default key (ID) āĻāĻžā§āĻž āĻ
āύā§āϝ āĻāĻŋāĻā§ āĻĻāĻŋā§ā§ āĻā§āĻāĻāϤ⧠āĻāĻžāύ, āϝā§āĻŽāύ slug
āĨ¤
đ¸ RouteServiceProvider:
use App\Models\Post;
use Illuminate\Support\Facades\Route;
public function boot()
{
Route::bind('post', function ($value) {
return Post::where('slug', $value)->firstOrFail();
});
}
đ¸ Route:
Route::get('/posts/{post}', [PostController::class, 'show']);
đ¸ Controller:
public function show(Post $post)
{
return view('posts.show', compact('post'));
}
āĻāĻāĻžāύ⧠route āĻāϰ {post}
āĻ
āĻāĻļāĻāĻž āĻĻāĻŋā§ā§ slug
āĻ
āύā§āϏāĻžāϰ⧠post āĻĒāĻžāĻā§āĻž āϝāĻžāĻŦā§āĨ¤
đ āĻāĻĒāϏāĻāĻšāĻžāϰ:
Route Model Binding Laravel-āĻ āĻā§āĻĄāĻā§ āĻĒāϰāĻŋāώā§āĻāĻžāϰ āĻ āĻā§āĻ āϰāĻžāĻā§ āĻāĻŦāĻ āĻŦā§āĻāĻžāϰ āĻĒāĻžāϰāĻĢāϰā§āĻŽā§āύā§āϏ āύāĻŋāĻļā§āĻāĻŋāϤ āĻāϰā§āĨ¤ Implicit binding āϏāĻšāĻ āĻāĻŦāĻ āĻĻā§āϰā§āϤ, āĻāϰ explicit binding āĻāĻžāϏā§āĻāĻŽ āĻĢāĻŋāϞā§āĻĄā§āϰ āĻāύā§āϝ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻšā§āĨ¤
āĻĒā§āϰāĻļā§āύ ā§Š: Laravel-āĻāϰ Eloquent ORM-āĻ Eager Loading āĻā§? āĻāĻāĻŋ Lazy Loading āĻĨā§āĻā§ āĻā§āĻāĻžāĻŦā§ āĻāϞāĻžāĻĻāĻž? N+1 āϏāĻŽāϏā§āϝāĻž āĻā§, āĻāĻāĻŋ āĻā§āύ āĻšā§ āĻāĻŦāĻ āĻāĻŋāĻāĻžāĻŦā§ āĻāĻāĻŋ āϏāĻŽāĻžāϧāĻžāύ āĻāϰāĻŦā§āύ?
āĻāϤā§āϤāϰ:
â Eager Loading āĻā§?
Eager Loading āĻšāϞ Eloquent ORM-āĻāϰ āĻāĻāĻāĻŋ āĻā§āĻāύāĻŋāĻ āϝāĻž āϏāĻŽā§āĻĒāϰā§āĻāĻŋāϤ āĻŽāĻĄā§āϞā§āϰ āĻĄā§āĻāĻž āĻāĻā§āĻ (āĻāĻāϏāĻžāĻĨā§) āϞā§āĻĄ āĻāϰ⧠āĻāύā§, āϝāĻžāϤ⧠āĻ āϤāĻŋāϰāĻŋāĻā§āϤ query āύāĻž āĻāϞā§āĨ¤
đ¸ āϏāĻžāϧāĻžāϰāĻŖāĻāĻžāĻŦā§, āĻāĻŽāϰāĻž with()
āĻŽā§āĻĨāĻĄ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠eager loading āĻāϰāĻŋāĨ¤
đĸ āĻāĻĻāĻžāĻšāϰāĻŖ:
$users = User::with('posts')->get();
āĻāĻ āĻā§āώā§āϤā§āϰā§, āĻĒā§āϰāϤāĻŋāĻāĻŋ User
āĻāϰ āϏāĻžāĻĨā§ āϏāĻŽā§āĻĒāϰā§āĻāĻŋāϤ Post
āĻā§āϞā§āĻ āĻāĻāϏāĻžāĻĨā§ āĻāĻāĻāĻŋ āĻāϞāĻžāĻĻāĻž query āĻĻāĻŋā§ā§ āĻāĻā§āĻ āϞā§āĻĄ āĻšā§ā§ āϝāĻžāĻŦā§āĨ¤ āĻāϤ⧠performance āĻāĻžāϞ⧠āĻšā§āĨ¤
â Lazy Loading āĻā§?
Lazy Loading āĻŽāĻžāύ⧠āĻšāϞ, āϝāĻāύ āĻŽā§āϞ āĻŽāĻĄā§āϞ āϞā§āĻĄ āĻšā§ āϤāĻāύ āĻļā§āϧā§āĻŽāĻžāϤā§āϰ āĻŽā§āϞ āĻĄā§āĻāĻž āϞā§āĻĄ āĻšā§āĨ¤ āĻāĻŋāύā§āϤ⧠āϝāĻāύ āϏāĻŽā§āĻĒāϰā§āĻāĻŋāϤ āĻĄā§āĻāĻž āĻāĻā§āϏā§āϏ āĻāϰāĻž āĻšā§, āϤāĻāύ āĻāϞāĻžāĻĻāĻž āĻāϰ⧠query āĻāϞā§āĨ¤
đ´ āĻāĻĻāĻžāĻšāϰāĻŖ:
$users = User::all();
foreach ($users as $user) {
echo $user->posts; // āĻĒā§āϰāϤāĻŋāĻŦāĻžāϰ āĻāĻāĻžāύ⧠āĻāϞāĻžāĻĻāĻž query āĻāϞāĻŦā§
}
āĻāĻ āĻā§āώā§āϤā§āϰā§, āĻĒā§āϰāĻĨāĻŽā§ āϏāĻŦ User
āϞā§āĻĄ āĻšāĻā§āĻā§, āϤāĻžāϰāĻĒāϰ āĻĒā§āϰāϤāĻŋāĻāĻŋ User
āĻāϰ āĻāύā§āϝ posts āϞā§āĻĄ āĻāϰāϤ⧠āĻāϞāĻžāĻĻāĻž āĻāϞāĻžāĻĻāĻž query āĻāϞāĻŦā§āĨ¤ āĻāĻāĻžāĻā§āĻ āĻŦāϞ⧠N+1 problemāĨ¤
â N+1 Problem āĻā§?
N+1 Problem āϤāĻāύ āĻšā§, āϝāĻāύ āĻāĻĒāύāĻŋ āĻāĻāĻāĻŋ āĻŽā§āϞ āĻŽāĻĄā§āϞ (āϝā§āĻŽāύ User
) āϞā§āĻĄ āĻāϰā§āύ āĻāĻŦāĻ āĻĒā§āϰāϤāĻŋāĻāĻŋ instance āĻāϰ āĻāύā§āϝ āϏāĻŽā§āĻĒāϰā§āĻāĻŋāϤ āĻŽāĻĄā§āϞ (āϝā§āĻŽāύ Post
) āĻāϞāĻžāĻĻāĻž āĻāϰ⧠āϞā§āĻĄ āĻšā§āĨ¤
đ¸ āĻāĻĻāĻžāĻšāϰāĻŖ:
$users = User::all(); // 1 query
foreach ($users as $user) {
$user->posts; // āĻĒā§āϰāϤāĻŋāĻāĻŋ user āĻāϰ āĻāύā§āϝ 1 āĻāϰ⧠query = N query
}
āĻŽā§āĻ query = 1 (User) + N (Posts) = N+1
āĻāĻ āϏāĻŽāϏā§āϝāĻž performance āĻāĻŽāĻŋā§ā§ āĻĻā§ā§āĨ¤
â
āϏāĻŽāĻžāϧāĻžāύ: Eager Loading āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ
$users = User::with('posts')->get(); // 2āĻāĻŋ query-āϤā§āĻ āĻāĻžāĻ āĻļā§āώ
- ā§§āĻāĻŋ query āĻĻāĻŋā§ā§ āϏāĻŦ
User
āĻāύāĻž āĻšā§āĨ¤ - ⧍⧠query āĻĻāĻŋā§ā§ āϏāĻŦ
posts
āĻāύāĻž āĻšā§ āϝā§āĻā§āϞ⧠āĻ āϏāĻŦ user-āĻāϰāĨ¤
đ§ Tips:
- multiple relation eager load āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ:
Post::with(['user', 'comments'])->get();
- nested relation eager load āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ:
User::with('posts.comments')->get();
đ āϏāĻāĻā§āώā§āĻĒā§ āĻĒāĻžāϰā§āĻĨāĻā§āϝ:
āĻĒā§āϰāĻļā§āύ 4: Laravel-āĻ Accessor āĻāĻŦāĻ Mutator āĻā§ āĻāĻŦāĻ āĻāĻā§āϞ⧠āĻā§āĻāĻžāĻŦā§ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āĻšāϝāĻŧ?
āĻāϤā§āϤāϰ:
-
Accessor: āĻŽāĻĄā§āϞ āĻĨā§āĻā§
āĻĄā§āĻāĻž āĻĒāĻĄāĻŧāĻžāϰ āĻāĻā§
āĻĄā§āĻāĻž āĻĒā§āϰāϏā§āϏ āĻāϰā§āĨ¤ -
Mutator: āĻŽāĻĄā§āϞā§
āĻĄā§āĻāĻž āϏā§āĻ āĻāϰāĻžāϰ āĻāĻā§
āĻĒā§āϰāϏā§āϏ āĻāϰā§āĨ¤
// Accessor
public function getFullNameAttribute()
{
return $this->first_name . ' ' . $this->last_name;
}
// Mutator
public function setPasswordAttribute($value)
{
$this->attributes['password'] = bcrypt($value);
}
āĻĒā§āϰāĻļā§āύ 5: Laravel-āĻ Authentication āĻāĻŦāĻ Authorization āĻĻā§āĻāĻŋ āĻāĻŋāύā§āύ āĻāĻŋāύā§āϤ⧠āϏāĻŽā§āĻĒāϰā§āĻāĻŋāϤ āϏāĻŋāĻāĻŋāĻāϰāĻŋāĻāĻŋ āĻāύāϏā§āĻĒā§āĻāĨ¤ āύāĻŋāĻā§ āĻŦāĻžāĻāϞāĻž āĻāĻžāώāĻžā§ āĻŦāĻŋāϏā§āϤāĻžāϰāĻŋāϤ āĻŦā§āϝāĻžāĻā§āϝāĻž āĻĻā§āĻā§āĻž āĻšāϞā§:
āĻāϤā§āϤāϰ:
â Authentication (āĻĒā§āϰāĻŽāĻžāĻŖā§āĻāϰāĻŖ)
Authentication āĻŽāĻžāύ⧠āĻšāĻā§āĻā§ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āĻĒāϰāĻŋāĻā§ āϝāĻžāĻāĻžāĻ āĻāϰāĻž â āϏ⧠āĻā§?
đš Laravel-āĻ Authentication āĻā§āĻāĻžāĻŦā§ āĻāĻžāĻ āĻāϰā§:
- āĻāĻāĻāĻžāϰ āϞāĻāĻāύ āĻāϰ⧠(āĻāĻŽā§āĻāϞ/āĻĒāĻžāϏāĻā§āĻžāϰā§āĻĄ āĻĻāĻŋā§ā§)
- Laravel
Auth
āĻĢā§āϝāĻžāϏā§āĻĄ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āĻĒāϰāĻŋāĻā§ āύāĻŋāĻļā§āĻāĻŋāϤ āĻāϰ⧠- āϏāĻĢāϞ āĻšāϞā§
session
āĻŦāĻžtoken
āĻāϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻāĻāĻāĻžāϰāĻā§ āϞāĻāĻāύ āĻ āĻŦāϏā§āĻĨāĻžā§ āϰāĻžāĻā§
đ§ āĻāĻĻāĻžāĻšāϰāĻŖ:
if (Auth::check()) {
// āĻāĻāĻāĻžāϰ āϞāĻāĻāύ āĻ
āĻŦāϏā§āĻĨāĻžā§ āĻāĻā§
}
đ Laravel Authentication Features:
Login, Register, Logout
- Password reset
- API Token authentication (Sanctum/Passport)
- Laravel Breeze, Jetstream, Fortify (Authentication scaffolding)
â Authorization (āĻ āύā§āĻŽā§āĻĻāύ)
Authorization
āĻŽāĻžāύ⧠āĻšāĻā§āĻā§ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰ⧠āĻāĻŋ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āĻāĻžāĻ āĻāϰāĻžāϰ āĻ
āύā§āĻŽāϤāĻŋ āĻĒāĻžāĻŦā§?
đ āĻĒāϰāĻŋāĻā§ āύāĻŋāĻļā§āĻāĻŋāϤ āĻšāĻā§āĻžāϰ āĻĒāϰā§, Laravel āĻĻā§āĻā§ āĻāĻāĻāĻžāϰ āĻā§āύ⧠āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āϰāĻŋāϏā§āϰā§āϏ āĻ ā§āϝāĻžāĻā§āϏā§āϏ āĻāϰāϤ⧠āĻĒāĻžāϰāĻŦā§ āĻāĻŋ āύāĻžāĨ¤
đš Laravel-āĻ Authorization āĻā§āĻāĻžāĻŦā§ āĻšā§:
- Gate āĻāĻŦāĻ Policy āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§
- āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āϰā§āϞ āĻŦāĻž āĻĒāĻžāϰāĻŽāĻŋāĻļāύ āϝāĻžāĻāĻžāĻ āĻāϰāĻž āĻšā§
đ§ āĻāĻĻāĻžāĻšāϰāĻŖ:
if (Auth::user()->can('update', $post)) {
// āĻāĻāĻāĻžāϰ āĻāĻ āĻĒā§āϏā§āĻ āĻāĻĒāĻĄā§āĻ āĻāϰāϤ⧠āĻĒāĻžāϰāĻŦā§
}
đ Authentication vs Authorization āϤā§āϞāύāĻž:
â
Laravel Example Scenario
// Authentication Middleware
Route::middleware('auth')->group(function () {
// Authorization check
Route::get('/post/{post}/edit', function (Post $post) {
if (Gate::allows('edit-post', $post)) {
// Edit form
} else {
abort(403);
}
});
});
đ āĻāĻĒāϏāĻāĻšāĻžāϰ
- Authentication āĻŦāϞ⧠āĻāĻāĻāĻžāϰ "āĻā§"
- Authorization āĻŦāϞ⧠āĻāĻāĻāĻžāϰ "āĻāĻŋ āĻāϰāϤ⧠āĻĒāĻžāϰā§"
đ Laravel-āĻ āĻāĻ āĻĻā§āĻāĻāĻŋ āĻĒāϰāĻŋāώā§āĻāĻžāϰāĻāĻžāĻŦā§ āĻāϞāĻžāĻĻāĻž āĻāϰāĻž āĻšā§ā§āĻā§, āĻāĻŦāĻ āϤāĻžāĻĻā§āϰ āĻāύā§āϝ āĻāϞāĻžāĻĻāĻž āĻŽā§āĻāĻžāύāĻŋāĻāĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻšā§āĨ¤
āĻĒā§āϰāĻļā§āύ ā§Ŧ: Laravel-āĻ āĻāĻĒāύāĻŋ āĻā§āĻāĻžāĻŦā§ āĻāĻāĻāĻŋ Custom Authentication Driver āĻāĻŽāĻĒā§āϞāĻŋāĻŽā§āύā§āĻ āĻāϰāĻŦā§āύ?
â āĻāϤā§āϤāϰ:
Laravel āϏāĻžāϧāĻžāϰāĻŖāϤ session āĻāĻŦāĻ token
(API) āĻāĻŋāϤā§āϤāĻŋāĻ authentication āϏāĻžāĻĒā§āϰā§āĻ āĻāϰā§, āϤāĻŦā§ āĻāĻĒāύāĻŋ āĻāĻžāĻāϞ⧠āύāĻŋāĻā§āϰ āĻŽāϤ⧠āĻāϰ⧠āĻāĻāĻāĻŋ Custom Authentication Driver
āϤā§āϰāĻŋ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύāĨ¤
Laravel-āĻ custom authentication driver āϤā§āϰāĻŋ āĻāϰāϤ⧠āĻšāϞ⧠āύāĻŋāĻā§āϰ āϧāĻžāĻĒāĻā§āϞ⧠āĻ āύā§āϏāϰāĻŖ āĻāϰāϤ⧠āĻšā§:
đ ī¸ āϧāĻžāĻĒ ā§§: Custom Guard Class āϤā§āϰāĻŋ āĻāϰā§āύ
āϧāϰā§āύ āĻāĻĒāύāĻŋ āĻāĻāĻāĻŋ CustomAuthGuard
āύāĻžāĻŽā§āϰ class āĻŦāĻžāύāĻžāĻŦā§āύāĨ¤
đ¸ app/Auth/CustomAuthGuard.php
namespace App\Auth;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Http\Request;
use Illuminate\Contracts\Auth\Authenticatable;
class CustomAuthGuard implements Guard
{
protected $request;
protected $provider;
protected $user;
public function __construct(UserProvider $provider, Request $request)
{
$this->provider = $provider;
$this->request = $request;
}
public function check()
{
return !is_null($this->user());
}
public function user()
{
if (!is_null($this->user)) {
return $this->user;
}
$id = $this->request->session()->get('custom_user_id');
if ($id) {
$this->user = $this->provider->retrieveById($id);
}
return $this->user;
}
public function id()
{
return $this->user()?->getAuthIdentifier();
}
public function validate(array $credentials = [])
{
$user = $this->provider->retrieveByCredentials($credentials);
if ($user && $this->provider->validateCredentials($user, $credentials)) {
$this->user = $user;
return true;
}
return false;
}
public function setUser(Authenticatable $user)
{
$this->user = $user;
return $this;
}
}
đ ī¸ āϧāĻžāĻĒ ā§¨: Service Provider āĻāϰ āĻŽāĻžāϧā§āϝāĻŽā§ Register āĻāϰā§āύ
đ¸ App\Providers\AuthServiceProvider.php
use App\Auth\CustomAuthGuard;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\ServiceProvider;
public function boot()
{
Auth::extend('custom_guard', function ($app, $name, array $config) {
$provider = Auth::createUserProvider($config['provider']);
return new CustomAuthGuard($provider, $app['request']);
});
}
đ ī¸ āϧāĻžāĻĒ ā§Š: config/auth.php āĻĢāĻžāĻāϞ⧠Guard āϝā§āĻā§āϤ āĻāϰā§āύ
'guards' => [
'custom' => [
'driver' => 'custom_guard',
'provider' => 'users',
],
],
đ ī¸ āϧāĻžāĻĒ ā§Ē: āĻāĻŋāĻāĻžāĻŦā§ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŦā§āύ
if (Auth::guard('custom')->attempt(['email' => 'test@example.com', 'password' => 'secret'])) {
// Login successful
}
đ§ āϏāĻāĻā§āώā§āĻĒā§:
āϧāĻžāĻĒ āĻāĻžāĻ
ā§§ Custom Guard class āϤā§āϰāĻŋ āĻāϰā§āύ
⧍ Auth::extend()
āĻāϰ āĻŽāĻžāϧā§āϝāĻŽā§ register āĻāϰā§āύ
ā§Š config/auth.php
-āĻ custom guard āϝā§āĻā§āϤ āĻāϰā§āύ
ā§Ē Auth::guard('custom')
āĻĻāĻŋā§ā§ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ
đ āĻāĻĒāϏāĻāĻšāĻžāϰ:
Custom authentication āϤāĻāύ āĻĻāϰāĻāĻžāϰ āĻšā§ āϝāĻāύ āĻāĻĒāύāĻŋ Session/Token āĻāĻžā§āĻžāĻ āĻāĻŋāύā§āύ āĻā§āύ⧠āĻĒā§āϰāĻā§āϰāĻŋā§āĻžā§ user āĻā§ authenticate āĻāϰāϤ⧠āĻāĻžāύ â āϝā§āĻŽāύ API Key, Third-Party Token, LDAP āĻāϤā§āϝāĻžāĻĻāĻŋāĨ¤
āĻĒā§āϰāĻļā§āύ ā§: Laravel-āĻ Queues āĻā§ āĻāĻŦāĻ āĻā§āύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āĻšāϝāĻŧ? āĻāĻŽāύ āĻāĻāĻāĻŋ āĻŦāĻžāϏā§āϤāĻŦ āĻāĻĻāĻžāĻšāϰāĻŖ āĻĻāĻŋāύ āϝā§āĻāĻžāύ⧠āĻāĻĒāύāĻŋ Queue āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŦā§āύāĨ¤
â āĻāϤā§āϤāϰ:
â Queues āĻā§?
Queue (āĻāĻŋāĻ) āĻšāϞ⧠Laravel-āĻāϰ āĻāĻāĻāĻŋ āĻĢāĻŋāĻāĻžāϰ āϝāĻž āĻāĻĒāύāĻžāĻā§ āĻĻā§āϰā§āĻ āϏāĻŽā§ āϞāĻžāĻāĻž āĻāĻžāĻāĻā§āϞā§āĻā§ āĻĒā§āĻāύ⧠(background) āĻĒā§āϰāĻā§āϰāĻŋāϝāĻŧāĻžāĻāϰāĻŖ āĻāϰāϤ⧠āϏāĻžāĻšāĻžāϝā§āϝ āĻāϰā§, āϝā§āύ āĻāĻāĻāĻžāϰ āĻĻā§āϰā§āϤ response āĻĒāĻžā§āĨ¤
āĻāĻā§āϞ⧠jobs
āĻāĻāĻžāϰ⧠āĻāĻ āĻŦāĻž āĻāĻāĻžāϧāĻŋāĻ worker āĻĻā§āĻŦāĻžāϰāĻž āĻĒā§āϰāϏā§āϏ āĻšā§āĨ¤
â āĻā§āύ Queues āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āĻšā§?
Queues āĻŦā§āϝāĻŦāĻšāĻžāϰā§āϰ āĻĒā§āϰāϧāĻžāύ āĻāĻžāϰāĻŖāĻā§āϞ⧠āĻšāϞā§:
- â āĻĒāĻžāϰāĻĢāϰāĻŽā§āϝāĻžāύā§āϏ āĻŦā§āĻĻā§āϧāĻŋ: āϝā§āϏāĻŦ āĻāĻžāĻ āĻ āύā§āĻ āϏāĻŽā§ āύā§ā§, āϏā§āĻā§āϞ⧠āĻŦā§āϝāĻžāĻāĻā§āϰāĻžāĻāύā§āĻĄā§ āĻĒāĻžāĻ āĻŋā§ā§ āĻĢā§āϞāĻž āϝāĻžā§āĨ¤
- â User Experience āĻāύā§āύā§āύ: āĻāĻāĻāĻžāϰ request-āĻāϰ āϏāĻžāĻĨā§ āϏāĻžāĻĨā§ response āĻĒāĻžā§, āĻāĻžāĻāĻāĻŋ āĻĒāϰ⧠āĻĒā§āϰāϏā§āϏ āĻšā§āĨ¤
- â Resources āĻŦāĻžāĻāĻāĻžāύā§: Worker āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ resource āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāĻžāĻ āϏāĻŽā§āĻĒāĻžāĻĻāύ āĻāϰā§āĨ¤
đ§ Queue āĻāĻžā§āĻž vs Queue āϏāĻš
đ´ Queue āĻāĻžā§āĻž:
public function sendEmail()
{
Mail::to($user)->send(new WelcomeMail());
return "Mail Sent!";
}
āĻāĻāĻžāύ⧠mail āĻĒāĻžāĻ āĻžāϤ⧠āĻ āύā§āĻ āϏāĻŽā§ āϞāĻžāĻāϤ⧠āĻĒāĻžāϰā§, āϝā§āĻāĻž user āĻāϰ āĻāύā§āϝ āϧā§āϰ āĻ āύā§āĻā§āϤāĻŋ āϤā§āϰāĻŋ āĻāϰā§āĨ¤
đĸ Queue āϏāĻš:
public function sendEmail()
{
dispatch(new SendWelcomeMailJob($user));
return "Mail Queued!";
}
āĻāĻāĻžāύ⧠āĻāĻžāĻāĻāĻŋ queue āϤ⧠āĻĒāĻžāĻ āĻŋā§ā§ āĻĻā§āĻā§āĻž āĻšā§, āĻāϰ āĻāĻāĻāĻžāϰ āϏāĻžāĻĨā§ āϏāĻžāĻĨā§ response āĻĒāĻžā§āĨ¤
â āĻŦāĻžāϏā§āϤāĻŦ āĻāĻĻāĻžāĻšāϰāĻŖ: Email Sending
āϧāϰāĻž āϝāĻžāĻ, āĻāĻĒāύāĻŋ āĻāĻāĻāύ āĻāĻāĻāĻžāϰāĻā§ āϰā§āĻāĻŋāϏā§āĻā§āϰā§āĻļāύā§āϰ āĻĒāϰ Welcome Email āĻĒāĻžāĻ āĻžāϤ⧠āĻāĻžāύāĨ¤ Email āĻĒāĻžāĻ āĻžāϤ⧠āϏāĻŽā§ āϞāĻžāĻā§ â āϤāĻžāĻ āĻāĻāĻŋ queue-āϤ⧠āĻĒāĻžāĻ āĻžāύ⧠āĻāϤā§āϤāĻŽāĨ¤
ā§§. Job āϤā§āϰāĻŋ āĻāϰā§āύ:
php artisan make:job SendWelcomeEmail
⧍. Job āĻā§āĻĄ:
public function handle()
{
Mail::to($this->user->email)->send(new WelcomeMail($this->user));
}
ā§Š. Dispatch āĻāϰā§āύ Controller āĻĨā§āĻā§:
dispatch(new SendWelcomeEmail($user));
â Queue āĻāĻžāϞ⧠āĻāϰāϤā§:
-
.env
āĻĢāĻžāĻāϞā§:
QUEUE_CONNECTION=database
- Queue table āϤā§āϰāĻŋ:
php artisan queue:table
php artisan migrate
- Queue worker āĻāĻžāϞā§:
php artisan queue:work
â Queue-āĻ āĻāϰāĻ āϝā§āϏāĻŦ āĻāĻžāĻ āĻĒāĻžāĻ āĻžāύ⧠āϝāĻžā§:
- āĻāĻŽā§āĻāϞ āĻĒāĻžāĻ āĻžāύ⧠(Email Sending)
- āϰāĻŋāĻĒā§āϰā§āĻ āĻā§āύāĻžāϰā§āĻ āĻāϰāĻž (PDF, Excel)
- āĻāĻŋāĻĄāĻŋāĻ āĻĒā§āϰāϏā§āϏāĻŋāĻ
- āύā§āĻāĻŋāĻĢāĻŋāĻā§āĻļāύ āĻĒāĻžāĻ āĻžāύā§
- āĻŦāĻŋāϞāĻŽā§āĻŦāĻŋāϤ āĻāĻžāĻ (Delayed Jobs)
đ āϏāĻāĻā§āώā§āĻĒā§:
â āĻĒā§āϰāĻļā§āύ ā§Ž: Laravel-āĻ āĻāĻĒāύāĻŋ āĻā§āĻāĻžāĻŦā§ Job āϤā§āϰāĻŋ āĻ Dispatch āĻāϰāĻŦā§āύ?
â āĻāϤā§āϤāϰ:
đˇ Job āĻā§?
Job āĻšāϞ⧠āĻāĻāĻāĻŋ āĻā§āϞāĻžāϏ āϝāĻž Laravel Queue-āĻāϰ āĻŽāĻžāϧā§āϝāĻŽā§ delay āĻŦāĻž background-āĻ āĻāĻžāĻ āϏāĻŽā§āĻĒāύā§āύ āĻāϰāϤ⧠āĻŦā§āϝāĻŦāĻšā§āϤ āĻšāϝāĻŧāĨ¤ āϝā§āĻŽāύ: āĻāĻŽā§āĻāϞ āĻĒāĻžāĻ āĻžāύā§, āϰāĻŋāĻĒā§āϰā§āĻ āϤā§āϰāĻŋ, āĻāĻŋāĻĄāĻŋāĻ āĻĒā§āϰāϏā§āϏ āĻāϤā§āϝāĻžāĻĻāĻŋāĨ¤
đ ī¸ Job āϤā§āϰāĻŋ āĻāϰāĻžāϰ āϧāĻžāĻĒ:
â
āϧāĻžāĻĒ ā§§: Job āĻā§āϞāĻžāϏ āϤā§āϰāĻŋ āĻāϰā§āύ
php artisan make:job SendWelcomeEmail
āĻāϤ⧠app/Jobs/SendWelcomeEmail.php
āĻĢāĻžāĻāϞ⧠āĻāĻāĻāĻŋ āĻā§āϞāĻžāϏ āϤā§āϰāĻŋ āĻšāĻŦā§āĨ¤
â
āϧāĻžāĻĒ ā§¨: Job-āĻ āĻāĻžāĻ āϞāĻŋāĻā§āύ
namespace App\Jobs;
use App\Mail\WelcomeMail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Mail;
class SendWelcomeEmail implements ShouldQueue
{
use Queueable;
protected $user;
public function __construct($user)
{
$this->user = $user;
}
public function handle()
{
// āĻŽā§āĻāϞ āĻĒāĻžāĻ āĻžāύā§āϰ āĻāĻžāĻ
Mail::to($this->user->email)->send(new WelcomeMail($this->user));
}
}
āĻŦāĻŋ.āĻĻā§āϰ.: ShouldQueue
āĻāύā§āĻāĻžāϰāĻĢā§āϏāĻāĻŋ Laravel āĻā§ āĻŦāϞ⧠āĻĻā§ā§ āϝ⧠āĻāĻāĻŋ queue-āϤ⧠āĻĒā§āϰāϏā§āϏ āĻāϰāϤ⧠āĻšāĻŦā§āĨ¤
â āϧāĻžāĻĒ ā§Š: Job Dispatch āĻāϰā§āύ
āϧāϰāĻž āϝāĻžāĻ, āĻāĻāĻāĻžāϰ āϰā§āĻāĻŋāϏā§āĻā§āϰā§āĻļāύā§āϰ āĻĒāϰ⧠āĻāĻ Job āĻāĻŋ Dispatch āĻāϰāĻŦā§āύāĨ¤
use App\Jobs\SendWelcomeEmail;
public function register(Request $request)
{
$user = User::create([...]);
// Dispatch Job
dispatch(new SendWelcomeEmail($user));
return response()->json(['message' => 'User registered and mail queued']);
}
đ ī¸ Queue āĻāĻžāϞ⧠āĻāϰāĻžāϰ āϧāĻžāĻĒ (āϝāĻĻāĻŋ queue āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ):
ā§§. .env
āĻĢāĻžāĻāϞ⧠āϏā§āĻ āĻāϰā§āύ:
QUEUE_CONNECTION=database
⧍. Queue table āϤā§āϰāĻŋ āĻāϰā§āύ:
php artisan queue:table
php artisan migrate
ā§Š. Worker āĻāĻžāϞ⧠āĻāϰā§āύ:
php artisan queue:work
đ§ āĻāϰāĻ āĻāĻŋāĻā§ āϤāĻĨā§āϝ:
â
āĻāĻĒāύāĻŋ Delay āϏāĻš Dispatch āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ:
dispatch(new SendWelcomeEmail($user))->delay(now()->addMinutes(5));
â
āĻā§āĻāύāĻŋāĻ āĻāϰ⧠āĻāĻāĻžāϧāĻŋāĻ Job āϏāĻŋāϰāĻŋā§āĻžāϞāĻŋ āĻāϞāĻžāϤ⧠āĻĒāĻžāϰā§āύ:
SendWelcomeEmail::withChain([
new LogEmailSent($user),
new NotifyAdmin($user),
])->dispatch();
đ āϏāĻāĻā§āώā§āĻĒā§:
â āĻĒā§āϰāĻļā§āύ ⧝: Laravel-āĻ āϝā§āϏāĻŦ āϧāϰāύā§āϰ Testing āĻāĻā§, āϏā§āĻā§āϞ⧠āĻŦā§āϝāĻžāĻā§āϝāĻž āĻāϰā§āύ āĻāĻŦāĻ āĻāĻāύ āĻā§āύāĻāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŦā§āύ āϤāĻž āĻāϞā§āϞā§āĻ āĻāϰā§āύāĨ¤
â āĻāϤā§āϤāϰ:
đ§Ē Laravel-āĻ Testing āĻāϰ āϧāϰāύāϏāĻŽā§āĻš:
Laravel āĻŽā§āϞāϤ ā§Š āϧāϰāĻŖā§āϰ
āĻā§āϏā§āĻāĻŋāĻ āϏāĻžāĻĒā§āϰā§āĻ āĻāϰā§:
- â Feature Testing
- â Unit Testing
- â Browser Testing (Dusk)
đš 1. Unit Testing
đ¸ āĻāĻ āĻā§āϏā§āĻ āĻā§āĻ āĻā§āĻ āĻĢāĻžāĻāĻļāύ āĻŦāĻž āĻā§āϞāĻžāϏāĻā§ isolate āĻāϰ⧠āĻĒāϰā§āĻā§āώāĻž āĻāϰā§āĨ¤
đ¸ āϏāĻžāϧāĻžāϰāĻŖāϤ Model, Service class āĻŦāĻž Helper function āĻāϤā§āϝāĻžāĻĻāĻŋāĻā§ test āĻāϰāϤ⧠āĻŦā§āϝāĻŦāĻšā§āϤ āĻšāϝāĻŧāĨ¤
⤠āĻāĻāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŦā§āύ:
- āϝāĻāύ āĻāĻĒāύāĻŋ āĻāĻžāύ āĻāĻāĻāĻŋ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āĻŽā§āĻĨāĻĄ āϏāĻ āĻŋāĻāĻāĻžāĻŦā§ āĻāĻžāĻ āĻāϰāĻā§ āĻāĻŋāύāĻž āϤāĻž āϝāĻžāĻāĻžāĻ āĻāϰāϤā§āĨ¤
⤠āĻāĻĻāĻžāĻšāϰāĻŖ:
php artisan make:test MathHelperTest --unit
public function test_add_numbers_correctly()
{
$this->assertEquals(4, MathHelper::add(2, 2));
}
đš 2. Feature Testing
đ¸ āĻāĻāĻŋ āĻĒā§āϰā§āĻĒā§āϰāĻŋ āĻāĻāĻāĻŋ feature (āϝā§āĻŽāύāĻ route, controller, middleware) āĻĒāϰā§āĻā§āώāĻž āĻāϰā§āĨ¤
đ¸ āĻāĻāĻžāύ⧠HTTP request simulate āĻāϰ⧠āϏāĻŽā§āĻĒā§āϰā§āĻŖ āĻĢā§āϞ⧠āĻā§āϏā§āĻ āĻāϰāĻž āĻšāϝāĻŧāĨ¤
⤠āĻāĻāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŦā§āύ:
- āϝāĻāύ āĻāĻĒāύāĻŋ āĻā§āĻ āĻāϰāϤ⧠āĻāĻžāύ, āĻāĻāĻāĻŋ āĻĢāĻŋāĻāĻžāϰ āĻ āĻŋāĻāĻāĻžāĻŦā§ āĻāĻžāĻ āĻāϰāĻā§ āĻāĻŋāύāĻž â āϝā§āĻŽāύ āĻĢāϰā§āĻŽ āϏāĻžāĻŦāĻŽāĻŋāĻļāύ, āϞāĻāĻāύ, āĻāĻāĻāĻžāϰ āϰā§āĻāĻŋāϏā§āĻā§āϰā§āĻļāύ āĻāϤā§āϝāĻžāĻĻāĻŋāĨ¤
⤠āĻāĻĻāĻžāĻšāϰāĻŖ:
php artisan make:test UserRegistrationTest
public function test_user_can_register()
{
$response = $this->post('/register', [
'name' => 'Ruhul',
'email' => 'ruhul@example.com',
'password' => 'secret',
'password_confirmation' => 'secret',
]);
$response->assertRedirect('/home');
$this->assertDatabaseHas('users', ['email' => 'ruhul@example.com']);
}
đš 3. Browser Testing (Laravel Dusk)
đ¸ āĻāĻāĻŋ āĻāĻāĻāĻŋ End-to-End (E2E) āĻā§āϏā§āĻāĻŋāĻ āϏāĻŋāϏā§āĻā§āĻŽ āϝāĻž āĻāϏāϞ browser āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠UI āĻā§āϏā§āĻ āĻāϰā§āĨ¤
đ¸ āĻāĻ āĻā§āϏā§āĻ āĻāĻāĻāĻžāϰ āĻāύā§āĻāĻžāϰāĻĢā§āϏ⧠āĻā§āϞāĻŋāĻ, āĻāĻžāĻāĻĒ, āϰāĻŋāĻĄāĻžāĻāϰā§āĻā§āĻ āĻāϤā§āϝāĻžāĻĻāĻŋ āĻ
āύā§āĻāϰāĻŖ āĻāϰā§āĨ¤
⤠āĻāĻāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŦā§āύ:
- āĻĢāϰā§āĻŽ, UI āĻāύā§āĻāĻžāϰāĻ ā§āϝāĻžāĻāĻļāύ āĻŦāĻž āĻāĻžāĻāĻžāϏā§āĻā§āϰāĻŋāĻĒā§āĻ āĻā§āϏā§āĻ āĻāϰāϤ⧠āĻāĻžāĻāϞā§āĨ¤
- āϞāĻāĻāύ/āϰā§āĻāĻŋāϏā§āĻā§āϰā§āĻļāύ āĻĒā§āϰāĻā§āϰāĻŋāϝāĻŧāĻžāϰ āĻāĻŋāĻā§āϝā§āϝāĻŧāĻžāϞ āĻĢā§āϞ⧠āĻĻā§āĻāϤ⧠āĻāĻžāĻāϞā§āĨ¤
⤠āĻāĻĻāĻžāĻšāϰāĻŖ:
php artisan dusk:make LoginTest
public function test_login()
{
$this->browse(function ($browser) {
$browser->visit('/login')
->type('email', 'test@example.com')
->type('password', 'password')
->press('Login')
->assertPathIs('/home');
});
}
đ§ āϏāĻāĻā§āώā§āĻĒā§ āĻĒāĻžāϰā§āĻĨāĻā§āϝ:
â
Laravel-āĻ Test āĻāĻžāϞāĻžāύā§āϰ āĻāĻŽāĻžāύā§āĻĄ:
php artisan test
āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ test file āĻāĻžāϞāĻžāϤā§:
php artisan test --filter=UserRegistrationTest
đ āĻāĻĒāϏāĻāĻšāĻžāϰ:
Laravel-āĻ testing āϏāĻŋāϏā§āĻā§āĻŽ āĻ āύā§āĻ āĻļāĻā§āϤāĻŋāĻļāĻžāϞ⧠āĻāĻŦāĻ development-āĻāϰ āϏāĻŽā§ āĻĒā§āϰāϤāĻŋāĻāĻŋ āϧāϰāĻŖā§āϰ test āϏāĻ āĻŋāĻāĻāĻžāĻŦā§ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϞ⧠bug-free āĻ āĻŦāĻŋāĻļā§āĻŦāĻžāϏāϝā§āĻā§āϝ āĻ ā§āϝāĻžāĻĒ āϤā§āϰāĻŋ āĻāϰāĻž āϝāĻžā§āĨ¤
â āĻĒā§āϰāĻļā§āύ ā§§ā§Ļ: Laravel āĻā§āϏā§āĻā§ āĻāĻĒāύāĻŋ āĻā§āĻāĻžāĻŦā§ dependency mock āĻāϰāĻŦā§āύ? āĻāĻāĻāĻŋ āĻāĻĻāĻžāĻšāϰāĻŖ āĻĻāĻŋāύāĨ¤
â āĻāϤā§āϤāϰ:
đ§ Mocking āĻŽāĻžāύ⧠āĻā§?
Mocking āĻŽāĻžāύ⧠āĻšāϞ⧠āĻāĻŽāύ āĻā§āύ⧠class āĻŦāĻž object-āĻāϰ āύāĻāϞ (fake) āĻāĻžāϰā§āϏāύ āϤā§āϰāĻŋ āĻāϰāĻž
, āϝāĻžāϤ⧠āĻāĻŽāϰāĻž āĻāϏāϞ dependency-āĻāϰ behavior āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰ⧠test āĻāϰāϤ⧠āĻĒāĻžāϰāĻŋāĨ¤
Laravel āĻ mocking āϏāĻžāϧāĻžāϰāĻŖāϤ service, external API, repository, notification, mail āĻāϤā§āϝāĻžāĻĻāĻŋ
āĻā§āώā§āϤā§āϰ⧠āĻāϰāĻž āĻšā§āĨ¤
đ§ Mocking Dependency āĻāĻŦā§ āĻĻāϰāĻāĻžāϰ āĻšā§?
- āϝāĻāύ āĻāĻĒāύāĻŋ āĻā§āύā§
external service
(āϝā§āĻŽāύ: payment gateway, SMS API) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻā§āύāĨ¤ - āϝāĻāύ āĻāĻĒāύāĻŋ āĻāĻŽāύ āĻā§āύ⧠āĻā§āϞāĻžāϏ āĻŦāĻž āϏāĻžāϰā§āĻāĻŋāϏ āĻā§āϏā§āĻ āĻāϰāĻā§āύ, āϝā§āĻāĻŋ āĻ āύā§āϝ āĻā§āϞāĻžāϏā§āϰ āĻāĻĒāϰ āύāĻŋāϰā§āĻāϰ āĻāϰā§āĨ¤
- āϝāĻžāϤ⧠āĻāĻĒāύāĻžāϰ āĻā§āϏā§āĻā§ "side effects" āύāĻž āĻšā§ (āϝā§āĻŽāύ āĻāϏāϞ API call, database change āĻāϤā§āϝāĻžāĻĻāĻŋ)āĨ¤
â āĻāĻĻāĻžāĻšāϰāĻŖ: āĻāĻāĻāĻŋ Service Class āĻā§ Mock āĻāϰāĻž
āϧāϰāĻž āϝāĻžāĻ, āĻāĻĒāύāĻŋ āĻāĻāĻāĻŋ PaymentService
āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻā§āύ āϝā§āĻāĻž āĻāϏāϞ API call āĻāϰā§āĨ¤
đš Step 1: āĻāϏāϞ āϏāĻžāϰā§āĻāĻŋāϏ āĻā§āϞāĻžāϏ (Mock āĻāϰāĻžāϰ āĻāύā§āϝ)
namespace App\Services;
class PaymentService
{
public function charge($amount)
{
// āĻāϏāϞ API call (āϝā§āĻāĻž āĻāĻŽāϰāĻž āĻā§āϏā§āĻā§ āĻāϰāϤ⧠āĻāĻžāĻ āύāĻž)
return "Charged {$amount} taka!";
}
}
đš Step 2: Controller āϝā§āĻāĻŋ āĻāĻ āϏāĻžāϰā§āĻāĻŋāϏ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§
namespace App\Http\Controllers;
use App\Services\PaymentService;
class PaymentController extends Controller
{
public function pay(PaymentService $payment)
{
return $payment->charge(100);
}
}
đš Step 3: āĻāĻāύ āĻā§āϏā§āĻā§ āĻāĻ āϏāĻžāϰā§āĻāĻŋāϏāĻā§ Mock āĻāϰāĻŦ
namespace Tests\Feature;
use Tests\TestCase;
use App\Services\PaymentService;
use Illuminate\Support\Facades\App;
class PaymentTest extends TestCase
{
public function test_payment_service_mock()
{
// 1. āĻŽāĻ āĻ
āĻŦāĻā§āĻā§āĻ āϤā§āϰāĻŋ āĻāϰā§āύ
$mock = \Mockery::mock(PaymentService::class);
// 2. āĻŽāĻ āĻŽā§āĻĨāĻĄā§āϰ āĻĒā§āϰāϤā§āϝāĻžāĻļāĻŋāϤ āϰāĻŋāĻāĻžāϰā§āύ āĻā§āϝāĻžāϞ⧠āϏā§āĻ āĻāϰā§āύ
$mock->shouldReceive('charge')
->with(100)
->once()
->andReturn('Mocked Payment Success!');
// 3. Laravel container-āĻ bind āĻāϰā§āύ
$this->app->instance(PaymentService::class, $mock);
// 4. āĻāĻāύ Controller call āĻāϰāϞ⧠Mock āĻāĻžāĻ āĻāϰāĻŦā§
$response = $this->get('/pay');
$response->assertStatus(200);
$response->assertSee('Mocked Payment Success!');
}
}
āĻāĻ āĻā§āϏā§āĻā§ āĻāϏāϞ charge()
āĻŽā§āĻĨāĻĄ āĻāϞ āĻšā§ āύāĻž, āĻŦāϰāĻ āĻāĻŽāϰāĻž āϝā§āĻāĻžāĻŦā§ āĻāĻžāĻ āϏā§āĻāĻžāĻŦā§ response āĻĒāĻžāĻāĨ¤
â āĻāϰāĻ āĻāĻŋāĻā§ āĻāĻŋāύāĻŋāϏ āĻāĻĒāύāĻŋ Mock āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ:
â
Example: HTTP Request Mock (Laravel HTTP client)
use Illuminate\Support\Facades\Http;
public function test_api_call_mock()
{
Http::fake([
'api.example.com/*' => Http::response(['success' => true], 200),
]);
$response = Http::get('https://api.example.com/data');
$this->assertTrue($response->json()['success']);
}
đ āϏāĻāĻā§āώā§āĻĒā§:
â āĻĒā§āϰāĻļā§āύ ā§§ā§§: Laravel āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύā§āϰ āĻĒāĻžāϰāĻĢāϰāĻŽā§āϝāĻžāύā§āϏ (Performance) āĻāύā§āύāϤ āĻāϰāĻžāϰ āĻāύā§āϝ āĻā§āύ āĻā§āύ āĻā§āĻļāϞ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āϝāĻžāϝāĻŧ? āĻŦā§āϝāĻžāĻā§āϝāĻž āĻāϰā§āύāĨ¤
â āĻāϤā§āϤāϰ:
Laravel āĻ āύā§āĻ āĻĢāĻŋāĻāĻžāϰ āϏāĻŽā§āĻĻā§āϧ āĻāĻāĻāĻŋ āĻĢā§āϰā§āĻŽāĻā§āĻžāϰā§āĻ, āĻāĻŋāύā§āϤ⧠āĻā§āϞāĻāĻžāĻŦā§ āĻā§āĻĄ āĻāϰāϞ⧠āĻāĻāĻŋ āϧā§āϰāĻāϤāĻŋāϰ (slow) āĻšāϤ⧠āĻĒāĻžāϰā§āĨ¤ āύāĻŋāĻā§ āĻāĻŋāĻā§ āĻā§āϰā§āϤā§āĻŦāĻĒā§āϰā§āĻŖ āĻā§āĻļāϞ āĻĻā§āĻā§āĻž āĻšāϞ⧠āϝāĻž āĻ ā§āϝāĻžāĻĒāĻā§ āĻĻā§āϰā§āϤāϤāϰ āĻāϰāϤ⧠āϏāĻžāĻšāĻžāϝā§āϝ āĻāϰāĻŦā§āĨ¤
đ 1. Eager Loading āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ (N+1 āϏāĻŽāϏā§āϝāĻž āĻāĻĄāĻŧāĻžāϤā§)
đ¸ āϏāĻŽāϏā§āϝāĻžāĻ
$users = User::all(); // āĻĒā§āϰāϤāĻŋāĻāĻŋ āĻāĻāĻāĻžāϰā§āϰ āϏāĻžāĻĨā§ profile āĻĻāϰāĻāĻžāϰ
foreach ($users as $user) {
echo $user->profile->bio;
}
āĻāĻ āĻā§āώā§āϤā§āϰ⧠āĻĒā§āϰāϤāĻŋāĻāĻŋ user-āĻāϰ āĻāύā§āϝ āĻāϞāĻžāĻĻāĻž query āĻāϞ⧠â āĻāĻāĻžāĻā§ āĻŦāϞ⧠N+1 problemāĨ¤
â
āϏāĻŽāĻžāϧāĻžāύāĻ
$users = User::with('profile')->get();
đ 2. Cache āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ
đ¸ Page Cache:
Cache::put('homepage', $data, 3600); // ā§§ āĻāĻŖā§āĻāĻž āĻĒāϰā§āϝāύā§āϤ cache āĻĨāĻžāĻāĻŦā§
đ¸ Route Cache:
php artisan route:cache
đ¸ Config Cache:
php artisan config:cache
đ 3. Query Optimization āĻāϰā§āύ
- āĻŦā§ query split āĻāϰ⧠āĻā§āĻ āĻā§āĻ āĻāϰā§āύāĨ¤
-
select *
āĻāĻĄāĻŧāĻŋā§ā§ āĻĒā§āϰā§ā§āĻāύā§ā§ column āĻā§āϞ⧠select āĻāϰā§āύ:
User::select('id', 'name')->get();
- Index āϤā§āϰāĻŋ āĻāϰā§āύ DB column-āĻ (search/filter āĻāϰ āĻā§āώā§āϤā§āϰā§)āĨ¤
đ 4. Queue āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ
Time-consuming āĻāĻžāĻ āϝā§āĻŽāύ āĻāĻŽā§āĻāϞ, āϰāĻŋāĻĒā§āϰā§āĻ āĻā§āύāĻžāϰā§āĻļāύ āĻāϤā§āϝāĻžāĻĻāĻŋ Queue-āϤ⧠āĻĒāĻžāĻ āĻŋā§ā§ āĻĻāĻŋāύāĨ¤
dispatch(new SendWelcomeEmail($user));
đ 5. Pagination āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ
āĻ
āύā§āĻ āĻĄā§āĻāĻž āĻāĻāϏāĻžāĻĨā§ āϞā§āĻĄ āύāĻž āĻāϰ⧠paginate āĻāϰā§āύ:
User::paginate(20);
đ 6. Lazy Collections āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ
Laravel-āĻāϰ Lazy Collection āĻŦā§ Dataset-āĻāϰ āĻāύā§āϝ memory-efficient:
User::cursor()->each(function ($user) {
// Memory āĻāĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻšāĻŦā§
});
đ 7. View / Blade Cache (Compiled View)
Blade āĻĢāĻžāĻāϞāĻā§āϞ⧠Compile āĻšā§ā§ Storage-āĻ āϏā§āĻ āĻšā§āĨ¤ Faster rendering-āĻāϰ āĻāύā§āϝ:
php artisan view:cache
đ 8. Database Connection & Pooling
-
.env
āĻĢāĻžāĻāϞ⧠āϝāĻĨāĻžāϝāĻĨ DB config āĻĻāĻŋāύāĨ¤ - āϝāĻĻāĻŋ high traffic āĻ ā§āϝāĻžāĻĒ āĻšā§, database connection pooling āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ (āϝā§āĻŽāύāĻ Swoole, Octane)āĨ¤
đ 9. Laravel Octane āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ (Advanced)
High performance āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύā§āϰ āĻāύā§āϝ Laravel Octane āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ:
- Swoole / RoadRunner āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āĨ¤
- Laravel request lifecycle āĻĒā§āύāϰāĻžā§ load āύāĻž āĻāϰ⧠āĻĻā§āϰā§āϤāϤāϰ āĻāϰ⧠āϤā§āϞā§āĨ¤
đ 10. Autoload Optimization
Production mode-āĻ class autoload āĻ
āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻ āĻāϰā§āύ:
composer install --optimize-autoloader --no-dev
đ 11. Redis āĻŦāĻž Memcached Cache Driver āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ
āĻĄāĻŋāĻĢāϞā§āĻ file cache-āĻāϰ āĻŦāĻĻāϞ⧠Redis āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϞ⧠āĻ āύā§āĻ āĻĻā§āϰā§āϤ performance āĻĒāĻžāĻā§āĻž āϝāĻžā§āĨ¤
.env
āĻĢāĻžāĻāϞā§:
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis
đ 12. Assets āĻ āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻ āĻāϰā§āύ (JS/CSS)
- Mix āĻŦāĻž Vite āĻĻāĻŋā§ā§ JS/CSS minify āĻāϰā§āύ:
npm run prod
đ§ āϏāĻāĻā§āώā§āĻĒā§ āĻĒāĻžāϰāĻĢāϰāĻŽā§āϝāĻžāύā§āϏ āĻāĻŋāĻĒāϏ āĻā§āĻŦāĻŋāϞā§:
⨠āĻ āϤāĻŋāϰāĻŋāĻā§āϤ āĻĒāϰāĻžāĻŽāϰā§āĻļ:
- Debugbar āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠Performance bottleneck āĻā§āĻāĻā§ āĻŦā§āϰ āĻāϰā§āύāĨ¤
-
.env
āĻĢāĻžāĻāϞā§APP_DEBUG=false
āĻāϰā§āύ production-āĻāĨ¤
â āĻĒā§āϰāĻļā§āύ ⧧⧍: Laravel-āĻ āĻāĻĒāύāĻŋ āĻā§āĻāĻžāĻŦā§ Caching āĻāĻŽāĻĒā§āϞāĻŋāĻŽā§āύā§āĻ āĻāϰāĻŦā§āύ? āĻāĻŦāĻ āĻā§āύ āĻā§āύ āϧāϰāĻŖā§āϰ Cache āĻŽā§āĻāĻžāύāĻŋāĻāĻŽ Laravel-āĻ āĻĒāĻžāĻā§āĻž āϝāĻžā§?
â āĻāϤā§āϤāϰ:
đ§ Caching āĻā§?
Caching
āĻšāϞ⧠āĻāĻāĻāĻŋ āĻ
āϏā§āĻĨāĻžāϝāĻŧā§ āĻĄā§āĻāĻž āϏāĻāϰāĻā§āώāĻŖā§āϰ āĻĒāĻĻā§āϧāϤāĻŋ āϝāĻžāϤ⧠āĻŦāĻžāϰāĻŦāĻžāϰ āĻāĻāĻŋ āĻĄā§āĻāĻž āĻĒā§āύāϰāĻžā§ āĻĄāĻžāĻāĻžāĻŦā§āĻ āĻŦāĻž API āĻĨā§āĻā§ āύāĻž āĻāύāϤ⧠āĻšāϝāĻŧāĨ¤ āĻāϰ āĻĢāϞ⧠āĻ
ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύā§āϰ āĻĒāĻžāϰāĻĢāϰāĻŽā§āϝāĻžāύā§āϏ āĻŦā§āĻĻā§āϧāĻŋ āĻĒāĻžā§ āĻāĻŦāĻ āϞā§āĻĄ āĻāĻŽā§āĨ¤
đ ī¸ Laravel-āĻ Cache āĻŦā§āϝāĻŦāĻšāĻžāϰā§āϰ āϏāĻžāϧāĻžāϰāĻŖ āύāĻŋā§āĻŽ
Laravel-āĻ Cache āĻŦā§āϝāĻŦāĻšāĻžāϰā§āϰ āĻāύā§āϝ Cache
Facade āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āĻšā§āĨ¤
â
1. Cache āϏāĻāϰāĻā§āώāĻŖ āĻāϰāĻž (Store Cache)
use Illuminate\Support\Facades\Cache;
Cache::put('key', 'value', $seconds = 3600); // ā§§ āĻāĻŖā§āĻāĻžāϰ āĻāύā§āϝ āϏāĻāϰāĻā§āώāĻŖ
â
2. Cache āĻĨā§āĻā§ āĻĄā§āĻāĻž āĻĒāĻžāĻā§āĻž (Retrieve Cache)
$value = Cache::get('key'); // value āĻĒāĻžāĻŦā§āύ
â
3. āĻĄāĻŋāĻĢāϞā§āĻ āĻā§āϝāĻžāϞ⧠āϏāĻš Cache āĻĒāĻĄāĻŧāĻž
$value = Cache::get('key', 'default_value');
â
4. Cache āĻĨāĻžāĻāϞ⧠return, āύāĻž āĻĨāĻžāĻāϞ⧠āϤā§āϰāĻŋ āĻāϰā§āύ
$value = Cache::remember('users', 3600, function () {
return DB::table('users')->get();
});
â
5. āĻāĻŋāϰāϏā§āĻĨāĻžā§ā§ Cache (forever)
Cache::forever('site_name', 'My Website');
â
6. Cache āĻŽā§āĻā§ āĻĢā§āϞāĻž (Delete Cache)
Cache::forget('key');
â
7. āϏāĻŦ Cache Clear āĻāϰāĻž
php artisan cache:clear
đ Route, Config āĻ View Cache:
đš Route Cache:
php artisan route:cache
đš Config Cache:
php artisan config:cache
đš View Cache:
php artisan view:cache
đ Laravel-āĻ āϝ⧠Caching Mechanism/Driver āĻā§āϞ⧠āĻĒāĻžāĻā§āĻž āϝāĻžā§:
Laravel āĻāϰ .env
āĻĢāĻžāĻāϞā§
CACHE_DRIVER
āĻĻāĻŋā§ā§ āύāĻŋāϰā§āϧāĻžāϰāĻŖ āĻāϰāĻž āĻšā§ āĻāĻĒāύāĻŋ āĻā§āύ āϏāĻŋāϏā§āĻā§āĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻā§āύāĨ¤
CACHE_DRIVER=file
â ā§§. file (āĻĄāĻŋāĻĢāϞā§āĻ):
- Storage āĻĢā§āϞā§āĻĄāĻžāϰ⧠āĻĢāĻžāĻāϞ āĻāĻāĻžāϰ⧠cache āϏāĻāϰāĻā§āώāĻŖ āĻāϰā§āĨ¤
â ⧍. database:
- Cache data āĻĄāĻžāĻāĻžāĻŦā§āĻā§ āϏāĻāϰāĻā§āώāĻŖ āĻāϰā§āĨ¤
php artisan cache:table
php artisan migrate
â ā§Š. array:
- āĻļā§āϧā§āĻŽāĻžāϤā§āϰ current request āĻāϰ āĻāύā§āϝ RAM-āĻ cache āϰāĻžāĻā§ (testing purpose)āĨ¤
â ā§Ē. redis:
- Very fast, scalable memory-based caching system (production recommendation)āĨ¤
â ā§Ģ. memcached:
- Lightweight distributed caching system (alternative to Redis)āĨ¤
đ¯ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāĻĒāϝā§āĻāĻŋāϤāĻž āĻ āύā§āϝāĻžā§ā§ Driver āύāĻŋāϰā§āĻŦāĻžāĻāύ:
đ§Ē āĻāĻĻāĻžāĻšāϰāĻŖ: Redis Cache āĻŦā§āϝāĻŦāĻšāĻžāϰ
.env
āĻĢāĻžāĻāϞā§:
CACHE_DRIVER=redis
config/database.php
-āĻ Redis āĻāĻžāύāĻĢāĻŋāĻāĻžāϰ āύāĻŋāĻļā§āĻāĻŋāϤ āĻāϰāϤ⧠āĻšāĻŦā§āĨ¤
đ§ āĻāĻžāĻāϰāĻŋāϰ āĻāύā§āĻāĻžāϰāĻāĻŋāĻ āĻāĻŋāĻĒāϏ:
"Production āĻ
ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ⧠āĻāĻĒāύāĻŋ āĻā§āύ cache āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŦā§āύ?"
āĻāϤā§āϤāϰ: Redis, āĻāĻžāϰāĻŖ āĻāĻāĻŋ in-memory, super fast āĻāĻŦāĻ scalableāĨ¤
â āϏāĻāĻā§āώā§āĻĒā§ Laravel Caching:
â āĻĒā§āϰāĻļā§āύ ā§§ā§Š: Laravel-āĻ RESTful API āϤā§āϰāĻŋ āĻāϰāĻžāϰ āϧāĻžāĻĒāĻā§āϞ⧠āĻā§ āĻā§? āĻĒā§āϰāϏā§āϏ āĻŦā§āϝāĻžāĻā§āϝāĻž āĻāϰā§āύāĨ¤
â āĻāϤā§āϤāϰ:
đ§ RESTful API āĻā§?
REST (Representational State Transfer) āĻšāϞ⧠āĻā§ā§āĻŦ āϏāĻžāϰā§āĻāĻŋāϏ āĻĄāĻŋāĻāĻžāĻāύā§āϰ āĻāĻāĻāĻŋ āϏā§āĻāĻžāĻāϞ, āϝāĻž HTTP āĻŽā§āĻĨāĻĄ (GET, POST, PUT, DELETE) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻĄā§āĻāĻž āϰāĻŋāϏā§āϰā§āϏ āĻŽā§āϝāĻžāύā§āĻ āĻāϰā§āĨ¤
Laravel-āĻ RESTful API āϤā§āϰāĻŋ āĻāϰāĻž āĻā§āĻŦ āϏāĻšāĻ āĻ āĻļāĻā§āϤāĻŋāĻļāĻžāϞā§āĨ¤
đ Laravel-āĻ RESTful API āϤā§āϰāĻŋ āĻāϰāĻžāϰ āϧāĻžāĻĒāĻā§āϞā§:
ā§§. āϰāĻžāĻāĻ āϤā§āϰāĻŋ āĻāϰāĻž (Routes)
Laravel-āĻ API āϰāĻžāĻāĻāĻā§āϞ⧠routes/api.php
āĻĢāĻžāĻāϞ⧠āϏāĻāĻā§āĻāĻžāϝāĻŧāĻŋāϤ āĻāϰāĻž āĻšā§āĨ¤
Route::apiResource('posts', PostController::class);
- apiResource āϏā§āĻŦā§āĻāĻā§āϰāĻŋā§āĻāĻžāĻŦā§ ā§āĻāĻŋ RESTful āϰāĻžāĻāĻ āϤā§āϰāĻŋ āĻāϰ⧠(index, show, store, update, destroy)āĨ¤
⧍. āĻāύā§āĻā§āϰā§āϞāĻžāϰ āϤā§āϰāĻŋ (Controller)
php artisan make:controller PostController --api
-
--api
āĻĢā§āϞā§āϝāĻžāĻ āĻĻāĻŋā§ā§ āĻāύā§āĻā§āϰā§āϞāĻžāϰ āϤā§āϰāĻŋ āĻāϰāϞ⧠create/edit view āĻŽā§āĻĨāĻĄ āĻĨāĻžāĻā§ āύāĻž, āĻāĻžāϰāĻŖ API āĻļā§āϧ⧠āĻĄā§āĻāĻž āĻšā§āϝāĻžāύā§āĻĄā§āϞ āĻāϰā§āĨ¤
ā§Š. āĻŽāĻĄā§āϞ āĻ āĻŽāĻžāĻāĻā§āϰā§āĻļāύ āϤā§āϰāĻŋ (Model & Migration)
php artisan make:model Post -m
- āĻŽāĻĄā§āϞ
Post
āĻ āϏāĻāĻļā§āϞāĻŋāώā§āĻ āĻŽāĻžāĻāĻā§āϰā§āĻļāύ āĻĢāĻžāĻāϞ āϤā§āϰāĻŋ āĻšāĻŦā§āĨ¤ - āĻŽāĻžāĻāĻā§āϰā§āĻļāύ āĻĢāĻžāĻāϞ⧠āĻā§āĻŦāĻŋāϞ āĻāĻžāĻ āĻžāĻŽā§ āĻĄāĻŋāĻĢāĻžāĻāύ āĻāϰā§āύ:
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->timestamps();
});
php artisan migrate
ā§Ē. āĻāύā§āĻā§āϰā§āϞāĻžāϰ⧠āĻĢāĻžāĻāĻļāύ āĻāĻŽāĻĒā§āϞāĻŋāĻŽā§āύā§āĻ āĻāϰāĻž
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index()
{
return Post::all(); // āϏāĻŦ āĻĒā§āϏā§āĻ āĻĻā§āĻāĻžāĻŦā§
}
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|string',
'content' => 'required|string',
]);
$post = Post::create($validated);
return response()->json($post, 201);
}
public function show($id)
{
return Post::findOrFail($id);
}
public function update(Request $request, $id)
{
$post = Post::findOrFail($id);
$validated = $request->validate([
'title' => 'sometimes|required|string',
'content' => 'sometimes|required|string',
]);
$post->update($validated);
return response()->json($post);
}
public function destroy($id)
{
Post::destroy($id);
return response()->json(null, 204);
}
}
ā§Ģ. API Resource āĻŦāĻž Resource Collections (Optional)
āĻāύā§āύāϤ JSON response āĻāϰ āĻāύā§āϝ Laravel Resource āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ:
php artisan make:resource PostResource
use App\Http\Resources\PostResource;
public function show($id)
{
$post = Post::findOrFail($id);
return new PostResource($post);
}
ā§Ŧ. API Authentication (Optional)
- API āĻā§āĻā§āύ āĻŦāĻž Passport/ Sanctum āĻĻāĻŋā§ā§ āύāĻŋāϰāĻžāĻĒāϤā§āϤāĻž āύāĻŋāĻļā§āĻāĻŋāϤ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύāĨ¤
ā§. Test API
Postman, Insomnia āĻŦāĻž āĻ āύā§āϝ āĻā§āύ⧠API client āĻĻāĻŋā§ā§ āĻāĻĒāύāĻžāϰ API endpoint āĻā§āϞ⧠āĻā§āϏā§āĻ āĻāϰā§āύāĨ¤
đĨ āϏāĻāĻā§āώā§āĻĒā§ RESTful API āϤā§āϰāĻŋ āĻāϰāĻžāϰ āϧāĻžāĻĒ:
đ āĻāĻĒāϏāĻāĻšāĻžāϰ:
Laravel-āĻ RESTful API āĻŦāĻžāύāĻžāύ⧠āĻā§āĻŦāĻ āϏāĻšāĻ āĻāĻŦāĻ āĻļāĻā§āϤāĻŋāĻļāĻžāϞā§āĨ¤ Route, Controller, Model, Validation āĻ Response handling-āĻ Laravel āĻāϰ āĻŦāĻŋāϞā§āĻ-āĻāύ āϏā§āĻŦāĻŋāϧāĻž API āĻĄā§āĻā§āϞāĻĒāĻŽā§āύā§āĻāĻā§ āĻ āύā§āĻ āĻĻā§āϰā§āϤāϤāϰ āĻāϰ⧠āĻĻā§ā§āĨ¤
â āĻĒā§āϰāĻļā§āύ ā§§ā§Ē: API Resources āĻā§, āĻāĻŦāĻ Laravel-āĻ āĻāĻĒāύāĻŋ āĻā§āĻāĻžāĻŦā§ āĻāĻā§āϞ⧠āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŦā§āύ?
â āĻāϤā§āϤāϰ:
đ§ API Resources āĻā§?
Laravel API Resources āĻšāϞ⧠JSON āϰā§āϏāĻĒāύā§āϏ āĻĢāϰāĻŽā§āϝāĻžāĻ āĻāϰāĻžāϰ āĻāĻāĻāĻŋ āϏā§āĻŦāĻŋāϧāĻžāĻāύāĻ āĻĒāĻĻā§āϧāϤāĻŋāĨ¤
āĻāĻā§āϞ⧠āĻĄā§āĻāĻžāĻā§ āĻāĻžāĻ āĻžāĻŽā§āĻāϤ, āĻĒāϰāĻŋāώā§āĻāĻžāϰ āĻāĻŦāĻ āĻāĻžāϏā§āĻāĻŽāĻžāĻāĻāĻĄ āĻāĻāĻžāϰ⧠API āϰā§āϏāĻĒāύā§āϏ āĻšāĻŋāϏā§āĻŦā§ āϰāĻŋāĻāĻžāϰā§āύ āĻāϰāϤ⧠āϏāĻžāĻšāĻžāϝā§āϝ āĻāϰā§āĨ¤
āĻā§āύ API Resource āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŦā§āύ?
- API āϰā§āϏāĻĒāύā§āϏ⧠āĻļā§āϧ⧠āĻĒā§āϰā§ā§āĻāύā§ā§ āĻĄā§āĻāĻž āĻĻā§āĻāĻžāϤ⧠āĻĒāĻžāϰāĻŦā§āύāĨ¤
- āĻĄā§āĻāĻžāϰ āĻĢāϰāĻŽā§āϝāĻžāĻ āĻāύā§āĻā§āϰā§āϞ āĻāϰāϤ⧠āĻĒāĻžāϰāĻŦā§āύāĨ¤
- Response consistency āĻŦāĻāĻžā§ āĻĨāĻžāĻā§āĨ¤
- Complex nested relationship āĻā§āϞ⧠āϏāĻšāĻā§ āĻŽā§āϝāĻžāύā§āĻ āĻāϰāĻž āϝāĻžā§āĨ¤
đ§ Laravel-āĻ API Resource āϤā§āϰāĻŋ āĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻžāϰ āϧāĻžāĻĒ:
ā§§. Resource āĻā§āϞāĻžāϏ āϤā§āϰāĻŋ āĻāϰāĻž
php artisan make:resource PostResource
⧍. Resource āĻā§āϞāĻžāϏ⧠āĻĄā§āĻāĻž āĻĢāϰāĻŽā§āϝāĻžāĻ āĻāϰāĻž
app/Http/Resources/PostResource.php
āĻĢāĻžāĻāϞā§:
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class PostResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'content' => $this->content,
'created_at' => $this->created_at->format('Y-m-d H:i:s'),
];
}
}
ā§Š. Controller-āĻ Resource āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž
use App\Http\Resources\PostResource;
use App\Models\Post;
class PostController extends Controller
{
public function show($id)
{
$post = Post::findOrFail($id);
return new PostResource($post);
}
public function index()
{
$posts = Post::all();
return PostResource::collection($posts);
}
}
ā§Ē. Nested Resource āĻŦā§āϝāĻŦāĻšāĻžāϰ (Optional)
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'author' => new UserResource($this->whenLoaded('author')),
];
}
â Collection Resource
Laravel Resource Collections āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϞ⧠āĻāĻāĻžāϧāĻŋāĻ āϰāĻŋāϏā§āϰā§āϏā§āϰ āĻāύā§āϝ āĻāĻžāϏā§āĻāĻŽ āϞāĻāĻŋāĻ āϝā§āĻ āĻāϰāϤ⧠āĻĒāĻžāϰāĻŦā§āύāĨ¤
php artisan make:resource PostCollection
đ§ āϏāĻāĻā§āώā§āĻĒā§:
â āĻĒā§āϰāĻļā§āύ ā§§ā§Ģ: Laravel āĻā§āĻāĻžāĻŦā§ Exception (āϤā§āϰā§āĻāĻŋ) āĻšā§āϝāĻžāύā§āĻĄā§āϞ āĻāϰā§? āĻāĻŦāĻ āĻā§āĻāĻžāĻŦā§ āĻāĻĒāύāĻŋ āĻŦāĻŋāĻāĻŋāύā§āύ Exception-āĻāϰ āĻāύā§āϝ āĻāĻžāϏā§āĻāĻŽ āĻāϰāϰ āĻĒā§āĻ āĻŦāĻžāύāĻžāϤ⧠āĻĒāĻžāϰā§āύ?
â āĻāϤā§āϤāϰ:
đ§ Laravel-āĻ Exception Handling āĻā§āĻāĻžāĻŦā§ āĻāĻžāĻ āĻāϰā§?
Laravel āĻāϰ Exception Handling āĻŽā§āĻāĻžāύāĻŋāĻāĻŽ āĻā§āĻŦāĻ āĻļāĻā§āϤāĻŋāĻļāĻžāϞ⧠āĻāĻŦāĻ āĻĢā§āϞā§āĻā§āϏāĻŋāĻŦāϞāĨ¤
āĻāĻāĻŋ app/Exceptions/Handler.php āĻĢāĻžāĻāϞ⧠āĻŽā§āϞāϤ āĻšā§āϝāĻžāύā§āĻĄā§āϞ āĻāϰāĻž āĻšā§āĨ¤
đ ī¸ Exception Handling āĻāϰ āĻŽā§āϞ āĻāĻĒāĻžāĻĻāĻžāύ:
ā§§. report() method
- Exception āϞāĻ āĻāϰāĻžāϰ āĻāύā§āϝ āĻŦā§āϝāĻŦāĻšā§āϤ āĻšā§ (Laravel āĻĄāĻŋāĻĢāϞā§āĻāĻāĻžāĻŦā§ Log āĻĢāĻžāĻāϞ⧠āϞā§āĻā§)āĨ¤
- āĻāĻĒāύāĻŋ āĻāĻāĻžāύ⧠āĻāĻžāϏā§āĻāĻŽ Exception āϞāĻ āĻŦāĻž ā§ŠāϝāĻŧ āĻĒāĻā§āώā§āϰ āϏāĻŋāϏā§āĻā§āĻŽā§ āϝā§āĻŽāύ Sentry, Bugsnag āĻāϤā§āϝāĻžāĻĻāĻŋāϤ⧠āĻĒāĻžāĻ āĻžāϤ⧠āĻĒāĻžāϰā§āύāĨ¤
public function report(Throwable $exception)
{
parent::report($exception);
}
⧍. render() method
- Exception āĻā§āϝāĻžāĻĒāĻāĻžāϰ āĻāϰ⧠HTTP Response āϤā§āϰāĻŋ āĻāϰā§āĨ¤
- āĻāĻāĻžāύ⧠āĻāĻĒāύāĻŋ Exception āĻ āύā§āϝāĻžā§ā§ āĻāϞāĻžāĻĻāĻž āĻāĻŋāĻ āĻŦāĻž JSON āϰā§āϏāĻĒāύā§āϏ āĻĻāĻŋāϤ⧠āĻĒāĻžāϰā§āύāĨ¤
public function render($request, Throwable $exception)
{
return parent::render($request, $exception);
}
â āĻāĻžāϏā§āĻāĻŽ Exception āĻšā§āϝāĻžāύā§āĻĄāϞāĻŋāĻ āĻāĻŦāĻ āĻāϰāϰ āĻĒā§āĻ āĻŦāĻžāύāĻžāύā§:
ā§§. āĻāĻžāϏā§āĻāĻŽ Exception āϤā§āϰāĻŋ āĻāϰāĻž
php artisan make:exception CustomException
app/Exceptions/CustomException.php:
namespace App\Exceptions;
use Exception;
class CustomException extends Exception
{
public function render($request)
{
return response()->view('errors.custom', [], 500);
}
}
⧍. Handler.php-āϤ⧠Exception āĻāϞāĻžāĻĻāĻžāĻāĻžāĻŦā§ āĻšā§āϝāĻžāύā§āĻĄāϞ āĻāϰāĻž
public function render($request, Throwable $exception)
{
if ($exception instanceof \App\Exceptions\CustomException) {
return response()->view('errors.custom', [], 500);
}
return parent::render($request, $exception);
}
ā§Š. āĻāĻŋāύā§āύ Exception-āϰ āĻāύā§āϝ āĻāϞāĻžāĻĻāĻž āĻĒā§āĻ āϤā§āϰāĻŋ āĻāϰāĻž
Laravel āĻ āĻĄāĻŋāĻĢāϞā§āĻāĻāĻžāĻŦā§ āĻāĻŋāĻā§ error view āĻĨāĻžāĻā§ resources/views/errors/
āĻĢā§āϞā§āĻĄāĻžāϰ⧠āϝā§āĻŽāύ:
- 404.blade.php (Not Found)
- 500.blade.php (Server Error)
- 403.blade.php (Forbidden)
- 419.blade.php (CSRF Token Mismatch)
āĻāĻĒāύāĻŋ āĻāĻā§āϞ⧠āĻāĻžāϏā§āĻāĻŽāĻžāĻāĻ āĻāϰ⧠āύāĻŋāĻā§āϰ āĻŽāϤ⧠āĻāϰāϤ⧠āĻĒāĻžāϰā§āύāĨ¤
ā§Ē. API Response āĻāϰ āĻāύā§āϝ Exception āĻšā§āϝāĻžāύā§āĻĄā§āϞ āĻāϰāĻž
public function render($request, Throwable $exception)
{
if ($request->wantsJson()) {
if ($exception instanceof ModelNotFoundException) {
return response()->json(['error' => 'Resource not found'], 404);
}
return response()->json(['error' => 'Server Error'], 500);
}
return parent::render($request, $exception);
}
đĨ Laravel Exception Handling Summary:
â āϏāĻāĻā§āώā§āĻĒā§:
- Laravel exception āĻā§āϞ⧠central
Handler.php
-āϤ⧠āϧāϰāĻž āĻšā§āĨ¤ - āĻāĻĒāύāĻŋ āύāĻŋāĻāϏā§āĻŦ Exception class āĻŦāĻžāύāĻŋā§ā§ āĻāϞāĻžāĻĻāĻž āĻšā§āϝāĻžāύā§āĻĄāϞ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύāĨ¤
- āĻāĻŋāύā§āύ HTTP status code āĻŦāĻž JSON response āϤā§āϰāĻŋ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύāĨ¤
- āĻāĻŋāĻ āĻĢāĻžāĻāϞ āĻāĻžāϏā§āĻāĻŽāĻžāĻāĻ āĻāϰ⧠error page āϏā§āύā§āĻĻāϰ āĻāϰāϤ⧠āĻĒāĻžāϰāĻŦā§āύāĨ¤
â āĻĒā§āϰāĻļā§āύ ā§§ā§Ŧ: Laravel-āĻ Logging System āĻā§āĻāĻžāĻŦā§ āĻāĻžāĻ āĻāϰā§? āĻāĻŦāĻ āĻā§āĻāĻžāĻŦā§ āĻāĻĒāύāĻŋ āĻŦāĻŋāĻāĻŋāύā§āύ Log Channel āĻāύāĻĢāĻŋāĻāĻžāϰ āĻāϰāĻŦā§āύ?
â āĻāϤā§āϤāϰ:
đ§ Laravel Logging System āĻā§?
Laravel āĻāϰ Logging āϏāĻŋāϏā§āĻā§āĻŽ āĻŽā§āϞāϤ Monolog āϞāĻžāĻāĻŦā§āϰā§āϰāĻŋ
āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§, āϝāĻž āĻāĻāĻāĻŋ āĻāύāĻĒā§āϰāĻŋā§ PHP logging āϞāĻžāĻāĻŦā§āϰā§āϰāĻŋāĨ¤
Laravel Logging āϏāĻŋāϏā§āĻā§āĻŽ āĻĄā§āĻā§āϞāĻĒāĻžāϰāĻĻā§āϰ āĻĄāĻŋāĻŦāĻžāĻ, āĻāϰāϰ āĻā§āϰā§āϝāĻžāĻāĻŋāĻ āĻāĻŦāĻ āĻāύāĻĢāϰāĻŽā§āĻļāύ āϞāĻ āĻāϰāĻžāϰ āĻāύā§āϝ āϏā§āĻŦāĻŋāϧāĻžāĻāύāĻ āĻŦā§āϝāĻŦāϏā§āĻĨāĻž āĻĻā§ā§āĨ¤
đ ī¸ Laravel-āĻ Logging āĻāϰ āĻŽā§āϞ āĻŦā§āĻļāĻŋāώā§āĻā§āϝ:
- āϏāĻšāĻā§ āϞāĻ āϞā§āĻāĻž (info, warning, error, debug, critical āĻāϤā§āϝāĻžāĻĻāĻŋ)
- āĻāĻāĻžāϧāĻŋāĻ Channel āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻžāϰ āϏā§āϝā§āĻ (āĻāĻāĻ āϏāĻžāĻĨā§ āĻĢāĻžāĻāϞ, āϏāĻŋāϏā§āĻā§āĻŽ āϞāĻ, Slack āĻāϤā§āϝāĻžāĻĻāĻŋāϤ⧠āĻĒāĻžāĻ āĻžāύā§)
- āĻŦāĻŋāĻāĻŋāύā§āύ āĻāύāĻĢāĻŋāĻāĻžāϰā§āĻļāύ āĻ āĻĒāĻļāύ āϏāĻšāĻā§ āĻĒāϰāĻŋāĻŦāϰā§āϤāύāϝā§āĻā§āϝ
- Custom Channel āϤā§āϰāĻŋ āĻāϰāĻžāϰ āϏā§āĻŦāĻŋāϧāĻž
đ Laravel āĻ Log āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻžāϰ āĻŽā§āϞāĻŋāĻ āĻĒāĻĻā§āϧāϤāĻŋ
use Illuminate\Support\Facades\Log;
Log::info('This is an info log');
Log::warning('This is a warning log');
Log::error('This is an error log');
âī¸ Log Channel āĻāύāĻĢāĻŋāĻāĻžāϰā§āĻļāύ
Laravel āĻāϰ āϞāĻ āĻāύāĻĢāĻŋāĻāĻžāϰā§āĻļāύ config/logging.php
āĻĢāĻžāĻāϞ⧠āĻĨāĻžāĻā§āĨ¤
ā§§. Default Log Channel
.env
āĻĢāĻžāĻāϞ⧠āĻĄāĻŋāĻĢāϞā§āĻ āĻā§āϝāĻžāύā§āϞ āϏā§āĻ āĻāϰāĻž āĻšā§:
LOG_CHANNEL=stack
⧍. āĻĒā§āϰāϧāĻžāύ āĻāĻŋāĻā§ Log Channel:
ā§Š. āĻāĻĻāĻžāĻšāϰāĻŖ: Stack Channel āĻāύāĻĢāĻŋāĻāĻžāϰā§āĻļāύ
config/logging.php
āĻĨā§āĻā§:
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily', 'slack'],
'ignore_exceptions' => false,
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'days' => 14,
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => 'critical',
],
],
ā§Ē. Log Level āĻā§āϞā§:
emergency
alert
critical
error
warning
notice
info
debug
ā§Ģ. Custom Channel āϤā§āϰāĻŋ āĻāϰāĻž
'channels' => [
'custom' => [
'driver' => 'monolog',
'handler' => Monolog\Handler\StreamHandler::class,
'with' => [
'stream' => storage_path('logs/custom.log'),
],
'level' => 'debug',
],
],
đ§ Laravel Logging āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāĻĻāĻžāĻšāϰāĻŖ:
Log::debug('Debug message');
Log::info('User logged in', ['user_id' => $user->id]);
Log::error('Something went wrong!');
â āϏāĻāĻā§āώā§āĻĒā§:
Logging System
-> Monolog āϞāĻžāĻāĻŦā§āϰā§āϰāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠Laravel logging āĻāϰā§
Log Channel
-> āϞāĻ āϞā§āĻāĻž āĻā§āĻĨāĻžā§ āĻšāĻŦā§ āϤāĻžāϰ āύāĻŋāϰā§āĻĻā§āĻļāύāĻž (file, slack, syslog āĻāϤā§āϝāĻžāĻĻāĻŋ)
Default Channel
-> .env
āĻĨā§āĻā§ āύāĻŋāϰā§āϧāĻžāϰāĻŖ āĻāϰāĻž āĻšā§
Stack Channel
-> āĻāĻāĻžāϧāĻŋāĻ channel āĻāĻāĻ āϏāĻžāĻĨā§ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āϝāĻžā§
Log Levels
-> error, warning, info, debug āĻāϤā§āϝāĻžāĻĻāĻŋ
Custom Channel
-> āύāĻŋāĻā§āϰ āĻŽāϤ⧠āĻāϰ⧠āĻāĻžāϏā§āĻāĻŽ āϞāĻ āĻā§āϝāĻžāύā§āϞ āϤā§āϰāĻŋ āĻāϰāĻž āϝāĻžā§
â āĻĒā§āϰāĻļā§āύ ā§§ā§: Laravel āĻ ā§āϝāĻžāĻĒāϞāĻŋāĻā§āĻļāύ āĻĄā§āĻĒā§āϞāϝāĻŧ āĻāϰāĻžāϰ āĻĒā§āϰāĻā§āϰāĻŋāϝāĻŧāĻž āĻŦā§āϝāĻžāĻā§āϝāĻž āĻāϰā§āύāĨ¤ āĻāĻĒāύāĻŋ āĻā§āύ āĻā§āϞ āĻŦāĻž āĻĒāĻĻā§āϧāϤāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŦā§āύ?
â āĻāϤā§āϤāϰ:
đ§ Laravel āĻ ā§āϝāĻžāĻĒ āĻĄā§āĻĒā§āϞā§āĻŽā§āύā§āĻ āĻā§?
āĻĄā§āĻĒā§āϞāϝāĻŧāĻŽā§āύā§āĻ āĻŽāĻžāύ⧠āĻšāϞ⧠āĻāĻĒāύāĻžāϰ Laravel āĻ
ā§āϝāĻžāĻĒāĻā§ āϞā§āĻāĻžāϞ āĻŽā§āĻļāĻŋāύ āĻĨā§āĻā§ āϞāĻžāĻāĻ āϏāĻžāϰā§āĻāĻžāϰ/āĻĒā§āϰā§āĻĄāĻžāĻāĻļāύ āϏāĻžāϰā§āĻāĻžāϰ⧠āϏā§āĻĨāĻžāύāĻžāύā§āϤāϰ āĻāϰāĻž
, āϝāĻžāϤ⧠āĻāĻāĻāĻžāϰāϰāĻž āĻ
ā§āϝāĻžāĻā§āϏā§āϏ āĻāϰāϤ⧠āĻĒāĻžāϰā§āĨ¤
đ§ Laravel āĻĄā§āĻĒā§āϞāϝāĻŧāĻŽā§āύā§āĻā§āϰ āϧāĻžāĻĒāϏāĻŽā§āĻš (āϏāĻžāϧāĻžāϰāĻŖ āύāĻŋā§āĻŽ):
đš ā§§. āĻĒā§āϰā§āĻĄāĻžāĻāĻļāύ āϏāĻžāϰā§āĻāĻžāϰ āĻĒā§āϰāϏā§āϤā§āϤ āĻāϰāĻž
- āĻāĻĒāύāĻŋ āϏāĻžāϰā§āĻāĻžāϰ āĻšāĻŋāϏā§āĻŦā§ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ:
- Shared Hosting
- VPS/Cloud Server (e.g., DigitalOcean, AWS, Linode)
- Platform as a Service (PaaS) â āϝā§āĻŽāύ Heroku, Laravel Forge
āĻĒā§āϰā§ā§āĻāύā§ā§ āϏāĻĢāĻāĻā§ā§āϝāĻžāϰ:
- PHP (>=8.1)
- MySQL / MariaDB
- Nginx āĻŦāĻž Apache
- Composer
- Laravel CLI
đš ⧍. āĻā§āĻĄ āĻāĻĒāϞā§āĻĄ āĻāϰāĻž
⧍āĻāĻŋ āĻāύāĻĒā§āϰāĻŋā§ āĻāĻĒāĻžā§:
(āĻ) Git āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠(āϰā§āĻāĻŽā§āύā§āĻĄā§āĻĄ)
git clone https://github.com/your-repo.git
(āĻ) FTP/SFTP āĻŦāĻž cPanel File Manager āĻĻāĻŋā§ā§ āĻā§āĻĄ āĻāĻĒāϞā§āĻĄ āĻāϰāĻž
đš ā§Š. Environment āϏā§āĻāĻāĻĒ (.env āĻĢāĻžāĻāϞ āĻāύāĻĢāĻŋāĻāĻžāϰ)
āĻĒā§āϰā§āĻĄāĻžāĻāĻļāύ āϏāĻžāϰā§āĻāĻžāϰā§āϰ āĻāύā§āϝ .env
āĻĢāĻžāĻāϞ āϤā§āϰāĻŋ āĻāϰā§āύ:
APP_ENV=production
APP_DEBUG=false
APP_URL=https://yourdomain.com
DB_HOST=127.0.0.1
DB_DATABASE=your_db
DB_USERNAME=root
DB_PASSWORD=secret
đš ā§Ē. āĻĄāĻŋāĻĒā§āύāĻĄā§āύā§āϏāĻŋ āĻāύā§āϏāĻāϞ āĻāϰāĻž
composer install --optimize-autoloader --no-dev
- --no-dev â āĻĄā§āĻā§āϞāĻĒāĻŽā§āύā§āĻ āĻĒā§āϝāĻžāĻā§āĻ āĻāύāϏā§āĻāϞ āĻšāĻŦā§ āύāĻž
- --optimize-autoloader â āĻā§āϞāĻžāϏāϞā§āĻĄāĻžāϰ āĻ āĻĒāĻāĻŋāĻŽāĻžāĻāĻ āĻāϰā§
đš ā§Ģ. APP Key āĻā§āύāĻžāϰā§āĻ āĻāϰāĻž
php artisan key:generate
đš ā§Ŧ. Storage Permission āĻĻā§āĻā§āĻž
chmod -R 775 storage
chmod -R 775 bootstrap/cache
đš ā§. āĻŽāĻžāĻāĻā§āϰā§āĻļāύ āĻāĻžāϞāĻžāύā§
php artisan migrate --force
-
--force
āĻĻāĻŋā§ā§ āύāĻŋāĻļā§āĻāĻŋāϤ āĻāϰ⧠āĻĒā§āϰā§āĻĄāĻžāĻāĻļāύ āϏāĻžāϰā§āĻāĻžāϰ⧠āĻŽāĻžāĻāĻā§āϰā§āĻļāύ āĻšāĻŦā§
đš ā§Ž. āĻā§āϝāĻžāĻļ āĻ
āĻĒāĻāĻŋāĻŽāĻžāĻāĻ āĻāϰāĻž
php artisan config:cache
php artisan route:cache
php artisan view:cache
đš ⧝. Queue Worker āĻāĻžāϞāĻžāύ⧠(āϝāĻĻāĻŋ queue āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ)
php artisan queue:work
āĻŦāĻž Supervisor āĻĻāĻŋā§ā§ manage āĻāϰā§āύāĨ¤
đ ī¸ Laravel Deployment Tools (āĻĒāĻāύā§āĻĻ āĻ āύā§āϝāĻžā§ā§):
đ§Ē Deployment Checklist (āϏāĻāĻā§āώā§āĻĒā§):
āϧāĻžāĻĒ āĻāĻžāĻ
â
Server Setup -> PHP, DB, Composer āĻāύāϏā§āĻāϞ
â
Code Upload -> Git clone / FTP
â
.env Config -> Production āĻ
āύā§āϝāĻžā§ā§
â
Composer Install -> Dependencies āĻāύāϏā§āĻāϞ
â
Storage Permission -> āϞā§āĻāĻžāϰ āĻĒāĻžāϰāĻŽāĻŋāĻļāύ āĻĻāĻŋāύ
â
DB Migrate -> Artisan āĻĻāĻŋā§ā§
â
Optimize -> config, route, view cache
â
Supervisor (Queue) -> worker āĻāĻžāϞ⧠āĻāϰā§āύ (āϝāĻĻāĻŋ āĻĒā§āϰāϝā§āĻā§āϝ āĻšā§)
đ āĻāĻĒāϏāĻāĻšāĻžāϰ:
Laravel āĻ
ā§āϝāĻžāĻĒ āĻĄā§āĻĒā§āϞ⧠āĻāϰāϤ⧠āĻšāϞ⧠āĻāĻĒāύāĻžāĻā§ āĻļā§āϧ⧠āĻā§āĻĄ āĻšā§āϏā§āĻ āĻāϰāϞā§āĻ āĻšāĻŦā§ āύāĻž, āĻŦāϰāĻ āϏāĻ āĻŋāĻāĻāĻžāĻŦā§ āϏāĻžāϰā§āĻāĻžāϰ āϏā§āĻāĻāĻĒ, .env
āĻāύāĻĢāĻŋāĻāĻžāϰ, āĻĒāĻžāϰāĻŽāĻŋāĻļāύ, āĻŽāĻžāĻāĻā§āϰā§āĻļāύ, āĻā§āϝāĻžāĻļ āĻāĻŦāĻ āĻĒāĻžāϰāĻĢāϰāĻŽā§āϝāĻžāύā§āϏ āĻ
āĻĒāĻāĻŋāĻŽāĻžāĻāĻ āĻāϰāĻžāĻ āĻā§āĻŦ āĻā§āϰā§āϤā§āĻŦāĻĒā§āϰā§āĻŖāĨ¤
â āĻĒā§āϰāĻļā§āύ ā§§ā§Ž: Laravel-āĻ environment-specific configuration āĻā§āĻāĻžāĻŦā§ āĻšā§āϝāĻžāύā§āĻĄā§āϞ āĻāϰāĻž āĻšā§?
â āĻāϤā§āϤāϰ:
đ§ Environment-specific configuration āĻŽāĻžāύ⧠āĻā§?
Laravel āĻ ā§āϝāĻžāĻĒāĻāĻŋ āĻŦāĻŋāĻāĻŋāύā§āύ āĻĒāϰāĻŋāĻŦā§āĻļā§ (environment) āĻāĻžāĻ āĻāϰāϤ⧠āĻĒāĻžāϰ⧠â āϝā§āĻŽāύ:
-
local
(āĻĄā§āĻā§āϞāĻĒāĻŽā§āύā§āĻ) -
staging
(āĻĒāϰā§āĻā§āώāĻž) -
production
(āϞāĻžāĻāĻ)
Environment-specific configuration āĻŽāĻžāύ⧠āĻĒā§āϰāϤāĻŋāĻāĻŋ environment āĻ āύā§āϝāĻžāϝāĻŧā§ āĻāϞāĻžāĻĻāĻž āĻāϞāĻžāĻĻāĻž āϏā§āĻāĻŋāĻāϏ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻžāĨ¤
đ§ Laravel āĻā§āĻāĻžāĻŦā§ Environment āĻĄāĻŋāĻĢāĻžāĻāύ āĻāϰā§?
Laravel APP_ENV
variable āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠environment āĻāĻŋāύā§āĨ¤
đ .env
āĻĢāĻžāĻāϞ⧠āĻāĻĒāύāĻŋ āϏā§āĻ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ:
APP_ENV=local
đ .env āĻĢāĻžāĻāϞ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāύāĻĢāĻŋāĻāĻžāϰā§āĻļāύ āĻŽā§āϝāĻžāύā§āĻāĻŽā§āύā§āĻ
.env
āĻĢāĻžāĻāϞ Laravel āĻ
ā§āϝāĻžāĻĒā§āϰ āĻā§āĻĒāύ āĻ āĻĒāϰāĻŋāĻŦā§āĻļ-āύāĻŋāϰā§āĻāϰ āϤāĻĨā§āϝ āϏāĻāϰāĻā§āώāĻŖ āĻāϰā§āĨ¤ āϝā§āĻŽāύ:
APP_NAME=MyApp
APP_ENV=production
APP_KEY=base64:...
APP_DEBUG=false
APP_URL=https://example.com
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=myapp
DB_USERNAME=root
DB_PASSWORD=secret
đ āĻāĻ .env
āĻĢāĻžāĻāϞ āĻĨā§āĻā§ āĻāύāĻĢāĻŋāĻāĻžāϰā§āĻļāύ āĻāĻŋāĻāĻžāĻŦā§ āĻĒāĻžāĻā§āĻž āϝāĻžā§?
Laravel āĻāϰ āĻāύāĻĢāĻŋāĻ āĻĢāĻžāĻāϞāĻā§āϞ⧠(āϝā§āĻŽāύ config/app.php
, config/database.php
) .env
āĻĨā§āĻā§ env()
āĻĢāĻžāĻāĻļāύā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻŽāĻžāύ āύāĻŋāϝāĻŧā§ āĻāϏā§āĨ¤
āĻāĻĻāĻžāĻšāϰāĻŖ:
'debug' => env('APP_DEBUG', false),
đī¸ Environment Specific Config āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻžāϰ āĻāĻĒāĻžāϝāĻŧ:
â
ā§§. āĻŦāĻŋāĻāĻŋāύā§āύ .env āĻĢāĻžāĻāϞ āϤā§āϰāĻŋ āĻāϰāĻž (āϏā§āĻā§āĻ āĻ
āύā§āϝāĻžā§ā§)
.env â local environment
.env.staging â staging server
.env.production â live server
â ⧍. Git-āĻ .env āĻĢāĻžāĻāϞ āϰāĻžāĻāĻž āĻāĻāĻŋāϤ āύāĻž
.gitignore
āĻĢāĻžāĻāϞ⧠.env
āϰāĻžāĻāĻž āĻĨāĻžāĻā§, āϝā§āύ āĻāĻāĻž version control-āĻ āύāĻž āϝāĻžā§āĨ¤
đ ī¸ Environment Configuration āĻŦā§āϝāĻŦāĻšāĻžāϰā§āϰ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻŋāĻ āĻā§āώā§āϤā§āϰ:
â
āĻāĻžāĻāϞ⧠āĻā§āĻĄā§āϰ āĻāĻŋāϤāϰ⧠environment āĻā§āĻ āĻāϰāϤā§āĻ āĻĒāĻžāϰā§āύ
if (app()->environment('local')) {
// Local environment-specific logic
}
āĻŦāĻž
if (App::environment(['staging', 'production'])) {
// For both staging and production
}
đ āĻāύāĻĢāĻŋāĻāĻžāϰā§āĻļāύ āĻā§āϝāĻžāĻļ āĻā§āϞāĻŋā§āĻžāϰ āĻāĻŦāĻ āϰāĻŋāĻĢā§āϰā§āĻļ āĻāϰāĻžāϰ āĻāĻŽāĻžāύā§āĻĄ:
php artisan config:clear
php artisan config:cache
đ§Ē āĻāĻĒāϏāĻāĻšāĻžāϰ (Summary):
â āĻĒā§āϰāĻļā§āύ ⧧⧝: āĻāϝāĻŧā§āĻŦ āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ⧠āϏāĻžāϧāĻžāϰāĻŖ āϏāĻŋāĻāĻŋāĻāϰāĻŋāĻāĻŋ āĻĻā§āϰā§āĻŦāϞāϤāĻžāĻā§āϞā§āϰ āĻāϞā§āĻāύāĻž āĻāϰā§āύ āĻāĻŦāĻ Laravel āĻā§āĻāĻžāĻŦā§ āĻāĻ āĻā§āĻāĻāĻŋāĻā§āϞ⧠āĻĒā§āϰāϤāĻŋāϰā§āϧ āĻāϰ⧠āϤāĻž āĻŦā§āϝāĻžāĻā§āϝāĻž āĻāϰā§āύāĨ¤
â āĻāϤā§āϤāϰ:
đ āϏāĻžāϧāĻžāϰāĻŖ āĻā§ā§āĻŦ āϏāĻŋāĻāĻŋāĻāϰāĻŋāĻāĻŋ āĻāϞāύāĻžāϰā§āĻŦāĻŋāϞāĻŋāĻāĻŋ (Vulnerabilities):
āĻāϝāĻŧā§āĻŦ āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ āϏāĻžāϧāĻžāϰāĻŖāϤ āύāĻŋāĻā§āϰ āύāĻŋāϰāĻžāĻĒāϤā§āϤāĻž āϏāĻŽāϏā§āϝāĻžāϰ āĻŽā§āĻā§āĻŽā§āĻāĻŋ āĻšāϝāĻŧ:
â Laravel āĻā§āĻāĻžāĻŦā§ āĻāϏāĻŦ āϏāĻŽāϏā§āϝāĻžāϰ āϏāĻŽāĻžāϧāĻžāύ āĻāϰā§:
đ ā§§. SQL Injection â āϏāĻŽāĻžāϧāĻžāύ: Eloquent āĻ Query Builder
Laravel āĻāϰ Eloquent ORM āĻāĻŦāĻ Query Builder āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϞ⧠āĻĄāĻŋāĻĢāϞā§āĻāĻāĻžāĻŦā§ prepared statements āϤā§āϰāĻŋ āĻšā§āĨ¤
// āύāĻŋāϰāĻžāĻĒāĻĻ
$user = DB::table('users')->where('email', $email)->first();
đ° āĻāύāĻĒā§āĻ āϏāϰāĻžāϏāϰāĻŋ SQL āϤ⧠āĻŦāϏāĻžāϞ⧠āĻāύāĻā§āĻāĻļāύ āĻšā§ āύāĻžāĨ¤
đ ⧍. XSS (Cross-site scripting) â āϏāĻŽāĻžāϧāĻžāύ: Blade Escaping
Laravel āĻāϰ Blade āĻā§āĻŽāĻĒā§āϞā§āĻ āĻāĻā§āĻāĻŋāύ āϏā§āĻŦāϝāĻŧāĻāĻā§āϰāĻŋāϝāĻŧāĻāĻžāĻŦā§ HTML encode āĻāϰā§:
{{ $userInput }} {{-- āύāĻŋāϰāĻžāĻĒāĻĻ --}}
{!! $userInput !!} {{-- āϏāĻžāĻŦāϧāĻžāύ⧠āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻšāĻŦā§ --}}
đ° Blade āĻ {{ }}
āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϞ⧠JavaScript āĻāύāĻā§āĻāĻļāύ āĻĒā§āϰāϤāĻŋāϰā§āϧ āĻšā§āĨ¤
đ ā§Š. CSRF (Cross-site request forgery) â āϏāĻŽāĻžāϧāĻžāύ: CSRF Token
Laravel āϏā§āĻŦāϝāĻŧāĻāĻā§āϰāĻŋāϝāĻŧāĻāĻžāĻŦā§ āĻĢāϰā§āĻŽā§ CSRF āĻā§āĻā§āύ āϝā§āĻā§āϤ āĻāϰā§:
<form method="POST" action="/submit">
@csrf
</form>
đ° Laravel āĻāϰ middleware VerifyCsrfToken
āĻāĻ āĻā§āĻā§āύ āϝāĻžāĻāĻžāĻ āĻāϰā§āĨ¤
đ ā§Ē. Mass Assignment â āϏāĻŽāĻžāϧāĻžāύ: Fillable āĻŦāĻž Guarded
Laravel āĻ mass assignment āĻĨā§āĻā§ āϰāĻā§āώāĻž āĻāϰāϤ⧠fillable
āĻŦāĻž guarded
āĻĒā§āϰāĻĒāĻžāϰā§āĻāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āĻšāϝāĻŧāĨ¤
// āϏāĻ āĻŋāĻ
protected $fillable = ['name', 'email'];
// āύāĻž āĻāĻžāĻāϞ⧠āϏāĻŦ āĻŦā§āϞāĻ
protected $guarded = ['is_admin'];
đ° āĻāĻāĻž prevents āĻāϰ⧠āĻāĻāĻāĻžāϰ āĻāύāĻĒā§āĻ āĻĨā§āĻā§ āĻ āĻŦāĻžāĻā§āĻāĻŋāϤ āĻĢāĻŋāϞā§āĻĄ āĻāĻĒāĻĄā§āĻ āĻšāĻāϝāĻŧāĻžāĨ¤
đ ā§Ģ. Password Hashing â āϏāĻŽāĻžāϧāĻžāύ: bcrypt / Hash āĻĢā§āϝāĻžāϏāĻžāĻĄ
Laravel āĻ āĻĒāĻžāϏāĻāϝāĻŧāĻžāϰā§āĻĄ āĻāύāĻā§āϰāĻŋāĻĒā§āĻ āĻāϰāĻžāϰ āĻāύā§āϝ bcrypt()
āĻŦāĻž Hash
āĻĢā§āϝāĻžāϏāĻžāĻĄ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āĻšāϝāĻŧāĨ¤
use Illuminate\Support\Facades\Hash;
$user->password = Hash::make($request->password);
đ° āĻĒāĻžāϏāĻā§āĻžāϰā§āĻĄ āĻāĻāύ⧠āĻĒā§āϞā§āĻāύ āĻā§āĻā§āϏāĻā§ āϏāĻāϰāĻā§āώāĻŖ āĻāϰāĻž āĻāĻāĻŋāϤ āύāĻžāĨ¤
đ ā§Ŧ. File Upload Protection
Laravel āĻĢāĻžāĻāϞ āĻāĻĒāϞā§āĻĄ āĻāϰāĻžāϰ āϏāĻŽā§ āĻŽāĻžāĻāĻŽ āĻāĻžāĻāĻĒ, āĻāĻā§āϏāĻā§āύāĻļāύ, āĻ āĻĢāĻžāĻāϞ āϏāĻžāĻāĻ āϝāĻžāĻāĻžāĻ āĻāϰāĻžāϰ āϏā§āĻŦāĻŋāϧāĻž āĻĻā§ā§āĨ¤
$request->validate([
'photo' => 'required|image|mimes:jpg,png,jpeg|max:2048',
]);
đ° āĻāĻ āĻā§āϝāĻžāϞāĻŋāĻĄā§āĻļāύ āĻŽā§āϝāĻžāϞāĻŋāϏāĻŋā§āĻžāϏ āϏā§āĻā§āϰāĻŋāĻĒā§āĻ āĻŦāĻž exe āĻĢāĻžāĻāϞ āĻŦā§āϞāĻ āĻāϰā§āĨ¤
đ ā§. Secure Redirects
Laravel āĻāϰ redirect()
āĻĢāĻžāĻāĻļāύ āĻļā§āϧ⧠āĻ
āύā§āĻŽā§āĻĻāĻŋāϤ URL-āĻ āĻĒāĻžāĻ āĻžāϤ⧠āϏāĻžāĻšāĻžāϝā§āϝ āĻāϰā§āĨ¤
return redirect()->intended('/dashboard');
đ° āĻāĻĒāύāĻžāϰ āĻāĻā§āĻā§āĻŽāϤ⧠āϰāĻŋāĻĄāĻŋāϰā§āĻā§āĻ āύāĻž āĻāϰā§, āĻāĻāĻŋ āĻāĻā§ āύāĻŋāϰā§āϧāĻžāϰāĻŋāϤ route āĻ āĻĒāĻžāĻ āĻžā§āĨ¤
⨠Laravel āĻāϰāĻ āϝā§āϏāĻŦ āύāĻŋāϰāĻžāĻĒāϤā§āϤāĻž āϏā§āĻŦāĻŋāϧāĻž āĻĻā§ā§:
đ§Ē āĻāĻĒāϏāĻāĻšāĻžāϰ:
Laravel āĻĄā§āĻā§āϞāĻĒāĻžāϰāĻĻā§āϰ āϏāĻŋāĻāĻŋāĻāϰāĻŋāĻāĻŋ āύāĻŋāϝāĻŧā§ āϏāĻā§āϤāύ āĻĨāĻžāĻāϤ⧠āĻšā§ āĻāĻŦāĻ Laravel-āĻāϰ āĻŦāĻŋāϞā§āĻ-āĻāύ āϏā§āĻŦāĻŋāϧāĻžāĻā§āϞ⧠āĻ āĻŋāĻāĻāĻžāĻŦā§ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϞā§āĻ āĻ āύā§āĻ āύāĻŋāϰāĻžāĻĒāϤā§āϤāĻž āĻā§āĻāĻāĻŋ āĻĻā§āϰ āĻšā§āĨ¤
â āĻĒā§āϰāĻļā§āύ ⧍ā§Ļ: Laravel āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ⧠SQL Injection āĻāĻā§āϰāĻŽāĻŖ āĻĒā§āϰāϤāĻŋāϰā§āϧ⧠āĻāĻĒāύāĻŋ āĻā§ āĻā§ āĻŦā§āϝāĻŦāϏā§āĻĨāĻž āύā§āĻŦā§āύ?
â āĻāϤā§āϤāϰ:
đ SQL Injection āĻā§?
SQL Injection āĻšāϞ⧠āĻāĻāĻāĻŋ āĻāĻžāϞāύāĻžāϰā§āĻŦāĻŋāϞāĻŋāĻāĻŋ, āϝā§āĻāĻžāύ⧠āĻāĻāĻāĻžāϰ āĻāύāĻĒā§āĻā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻĄāĻžāĻāĻžāĻŦā§āĻā§ āĻā§āώāϤāĻŋāĻāϰ SQL āĻāĻŽāĻžāύā§āĻĄ āĻāύāĻā§āĻā§āĻ āĻāϰāĻž āϝāĻžā§āĨ¤ āĻāϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻšā§āϝāĻžāĻāĻžāϰ:
- āĻĄāĻžāĻāĻž āĻā§āϰāĻŋ āĻāϰāϤ⧠āĻĒāĻžāϰā§
- āĻĄāĻžāĻāĻž āĻŽā§āĻā§ āĻĢā§āϞāϤ⧠āĻĒāĻžāϰā§
- āĻ āĻĨāϰāĻžāĻāĻāĻĄ āύāĻž āĻšā§ā§āĻ āĻĄāĻžāĻāĻžāĻŦā§āĻ āĻ ā§āϝāĻžāĻā§āϏā§āϏ āĻāϰāϤ⧠āĻĒāĻžāϰā§
đ Laravel āĻā§āĻāĻžāĻŦā§ SQL Injection āĻĨā§āĻā§ āϰāĻā§āώāĻž āĻāϰā§?
Laravel āĻĄāĻŋāĻĢāϞā§āĻāĻāĻžāĻŦā§ SQL Injection āĻĒā§āϰāϤāĻŋāϰā§āϧ āĻāϰ⧠āύāĻŋāĻā§āϰ āĻā§āĻāύāĻŋāĻāĻā§āϞ⧠āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§:
â ā§§. Eloquent ORM āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž
Eloquent āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϞ⧠āĻāύāĻĒā§āĻ āϏā§āĻŦāϝāĻŧāĻāĻā§āϰāĻŋāϝāĻŧāĻāĻžāĻŦā§ bind āĻšā§, āϝā§āĻāĻžāύ⧠injection āϏāĻŽā§āĻāĻŦ āĻšā§ āύāĻžāĨ¤
// āύāĻŋāϰāĻžāĻĒāĻĻ
$user = User::where('email', $request->email)->first();
đ āĻāĻāĻžāύ⧠$request->email
āĻĄāĻŋāϰā§āĻā§āĻ SQL-āĻ āύāĻž āĻāĻŋā§ā§ bind āĻšā§ā§ āϝāĻžā§āĨ¤
â ⧍. Query Builder āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž
Laravel āĻāϰ Query Builder where()
āĻāϤā§āϝāĻžāĻĻāĻŋ āĻŽā§āĻĨāĻĄ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϞ⧠prepared statements āϤā§āϰāĻŋ āĻšā§āĨ¤
$user = DB::table('users')->where('name', $request->name)->get();
đ āĻāĻāĻžāύā§āĻ $request->name
SQL string āĻšāĻŋāϏā§āĻŦā§ āĻāύāĻā§āĻā§āĻ āĻšāϤ⧠āĻĒāĻžāϰ⧠āύāĻžāĨ¤
đĢ ā§Š. Raw SQL āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϞ⧠bind āĻāϰāϤ⧠āĻšāĻŦā§
āϝāĻĻāĻŋ āĻāĻĒāύāĻŋ raw SQL āĻāĻžāϞāĻžāϤ⧠āĻāĻžāύ, āϤāĻžāĻšāϞ⧠parameter binding āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻšāĻŦā§āĨ¤
// â āĻā§āĻāĻāĻŋāĻĒā§āϰā§āĻŖ: āĻāĻāĻāĻžāϰ āĻāύāĻĒā§āĻ āĻĄāĻŋāϰā§āĻā§āĻ āĻŦāϏāĻžāύ⧠āĻšā§ā§āĻā§
DB::select("SELECT * FROM users WHERE name = '$name'");
// â
āύāĻŋāϰāĻžāĻĒāĻĻ (bindings āϏāĻš)
DB::select("SELECT * FROM users WHERE name = ?", [$name]);
â ā§Ē. Mass Assignment āĻĒā§āϰāϤāĻŋāϰā§āϧ
Mass assignment āĻĨā§āĻā§ SQL injection āĻšāϤ⧠āĻĒāĻžāϰ⧠āϝāĻĻāĻŋ āĻāĻĒāύāĻŋ $fillable/$guarded
āύāĻž āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύāĨ¤
// â
āύāĻŋāϰāĻžāĻĒāĻĻ
protected $fillable = ['name', 'email'];
đ āύāĻž āĻĻāĻŋāϞ⧠malicious āĻĢāϰā§āĻŽ āĻāύāĻĒā§āĻ sensitive āĻĢāĻŋāϞā§āĻĄā§ āĻāύāĻā§āĻā§āĻ āĻšāϤ⧠āĻĒāĻžāϰā§āĨ¤
â ā§Ģ. Request Validation āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž
āĻĢāϰā§āĻŽ āĻāύāĻĒā§āĻ āĻā§āϝāĻžāϞāĻŋāĻĄ āύāĻž āĻšāϞ⧠āϤāĻž SQL-āĻ āĻĒā§āĻāĻāĻžāύā§āϰ āĻāĻā§āĻ āĻŦā§āϞāĻ āĻšā§ā§ āϝāĻžā§āĨ¤
$request->validate([
'email' => 'required|email',
'name' => 'required|string|max:255',
]);
â ā§Ŧ. Stored Procedure āĻ ORM āĻŽāĻŋāϞāĻŋā§ā§ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž (Optional Advanced)
Laravel āĻĨā§āĻā§ āĻĄāĻžāĻāĻžāĻŦā§āĻā§āϰ stored procedures āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āϝāĻžā§, āϝāĻžāϤ⧠āϏāϰāĻžāϏāϰāĻŋ āĻāύāĻā§āĻāĻļāύ āĻĒā§āϰāϤāĻŋāϰā§āϧ āĻšā§āĨ¤
DB::statement('CALL safeProcedure(?, ?)', [$val1, $val2]);
đ§Ē āϏāĻāĻā§āώā§āĻĒā§ āĻĒā§āϰāϤāĻŋāϰā§āϧāĻŽā§āϞāĻ āĻŦā§āϝāĻŦāϏā§āĻĨāĻž:
đ āĻāĻĒāϏāĻāĻšāĻžāϰ:
Laravel āĻāϰ āĻĄāĻŋāĻĢāϞā§āĻ ORM āĻ Query Builder āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϞ⧠āĻāĻĒāύāĻŋ SQL Injection āĻĨā§āĻā§ āĻ
āύā§āĻāĻāĻžāĻ āύāĻŋāϰāĻžāĻĒāĻĻāĨ¤ āϤāĻŦā§ āĻāĻāύ⧠raw SQL āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϞ⧠āĻ
āĻŦāĻļā§āϝāĻ bindings
āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻšāĻŦā§āĨ¤ āĻāĻŦāĻ āϏāϰā§āĻŦāĻĻāĻž āĻā§āϝāĻžāϞāĻŋāĻĄā§āĻļāύ, āĻĢāĻŋāϞā§āĻāĻžāϰāĻŋāĻ, āĻ āϏāĻ āĻŋāĻ āĻŽāĻĄā§āϞ āĻĢāĻŋāϞā§āĻĄ āύāĻŋā§āύā§āϤā§āϰāĻŖ āĻāϰāĻž āĻāĻāĻŋāϤāĨ¤
â āĻĒā§āϰāĻļā§āύ ⧍⧧: āĻāĻāĻāĻŋ PHP āĻĢāĻžāĻāĻļāύ āϞāĻŋāĻā§āύ āϝāĻž āĻāĻāĻāĻŋ āϏāĻāĻā§āϝāĻžāϰ āϏā§āĻ āĻĨā§āĻā§ āϏāĻŦ āϏāĻŽā§āĻāĻžāĻŦā§āϝ āĻāĻŽā§āĻŦāĻŋāύā§āĻļāύ āĻā§āĻāĻā§ āĻŦā§āϰ āĻāϰ⧠āϝā§āĻā§āϞā§āϰ āϝā§āĻāĻĢāϞ āĻāĻāĻāĻŋ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āĻāĻžāϰā§āĻā§āĻā§āϰ āϏāĻŽāĻžāύ āĻšā§āĨ¤ āύāĻŋāĻļā§āĻāĻŋāϤ āĻāϰā§āύ āϝ⧠āĻāĻāĻŋ āĻŦā§ āĻāύāĻĒā§āĻ āĻ ā§āϝāĻžāϰ⧠āĻšā§āϝāĻžāύā§āĻĄā§āϞ āĻāϰāϤ⧠āĻĻāĻā§āώāϤāĻžāϰ āϏāĻžāĻĨā§ āĻāĻžāĻ āĻāϰā§āĨ¤
āĻāĻĻāĻžāĻšāϰāĻŖ:
āĻāύāĻĒā§āĻ: [2, 3, 5, 7], target = 8
āĻāĻāĻāĻĒā§āĻ: [[3, 5], [2, 3, 3]]
â āĻāϤā§āϤāϰ:
â āϏāĻŽāĻžāϧāĻžāύ (PHP āĻā§āĻĄ āϏāĻš):
āĻāĻŽāϰāĻž āĻāĻāĻžāύ⧠āĻŦā§āϝāĻžāĻāĻā§āϰā§āϝāĻžāĻāĻŋāĻ āĻ āĻŽā§āĻŽā§āĻāĻā§āĻļāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŦ āϝāĻžāϤ⧠āĻāĻŽā§āĻŦāĻŋāύā§āĻļāύ āĻā§āĻāĻā§ āĻŦā§āϰ āĻāϰāϤ⧠āĻĒāĻžāϰāĻŋ āĻāĻŦāĻ āĻŦāĻžāϰāĻŦāĻžāϰ āĻāĻāĻ āĻāĻĒāϏāĻŽāϏā§āϝāĻž āύāĻž āĻāϰāĻŋāĨ¤
function combinationSum(array $candidates, int $target): array {
sort($candidates); // Optional but helps avoid duplicate combinations
$result = [];
$memo = [];
function dfs($candidates, $target, $start, $path, &$result, &$memo) {
$key = $target . '-' . implode(',', $path);
if (isset($memo[$key])) return;
if ($target == 0) {
$result[] = $path;
return;
}
for ($i = $start; $i < count($candidates); $i++) {
if ($candidates[$i] > $target) break;
dfs($candidates, $target - $candidates[$i], $i, array_merge($path, [$candidates[$i]]), $result, $memo);
}
$memo[$key] = true;
}
dfs($candidates, $target, 0, [], $result, $memo);
return $result;
}
// â
āĻāĻĻāĻžāĻšāϰāĻŖ āĻāĻžāϞāĻžāύā§:
$candidates = [2, 3, 5, 7];
$target = 8;
print_r(combinationSum($candidates, $target));
đ§ āĻā§āĻāĻžāĻŦā§ āĻāĻžāĻ āĻāϰā§:
-
dfs()
āĻĢāĻžāĻāĻļāύāĻāĻŋ āϰāĻŋāĻāĻžāϰā§āϏāĻŋāĻāϞāĻŋ āĻĒā§āϰāϤāĻŋāĻāĻŋ āϏāĻŽā§āĻāĻžāĻŦā§āϝ āϏāĻāĻā§āϝāĻžāϰ āϏāĻŽāύā§āĻŦā§ āĻĒāϰā§āĻā§āώāĻž āĻāϰā§āĨ¤ - āĻāĻāĻ āϏāĻžāĻŦ-āĻĒā§āϰā§āĻŦā§āϞā§āĻŽ āĻāĻŦāĻžāϰ āύāĻž āĻāϰāϤā§
memo
āĻ ā§āϝāĻžāϰ⧠āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻāĻŋāĨ¤ -
start
āĻāύāĻĄā§āĻā§āϏ āĻĻāĻŋā§ā§ āĻĒāϰāĻŦāϰā§āϤ⧠āϰāĻŋāĻāϰā§āĻļāύ⧠āĻĒā§āύāϰāĻžāĻŦā§āϤā§āϤāĻŋ āύāĻŋā§āύā§āϤā§āϰāĻŖ āĻāϰāĻž āĻšā§ āϝāĻžāϤ⧠āĻĄā§āĻĒā§āϞāĻŋāĻā§āĻ āĻāĻŽā§āĻŦāĻŋāύā§āĻļāύ āύāĻž āĻāϏā§āĨ¤ - āϝāĻĻāĻŋ
target == 0
āĻšā§, āϤāĻžāĻšāϞ⧠āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻā§āϝāĻžāϞāĻŋāĻĄ āĻāĻŽā§āĻŦāĻŋāύā§āĻļāύ āĻāĻŦāĻ āϤāĻžresult
āĻ āϝā§āĻ āĻāϰāĻž āĻšā§āĨ¤
âĄī¸ āĻŦā§ āĻāύāĻĒā§āĻā§ āĻĒāĻžāϰāĻĢāϰāĻŽā§āϝāĻžāύā§āϏ āĻāĻŋāĻĒāϏ:
-
sort()
āĻāϰāϞ⧠āϞā§āĻĒā§ āĻāĻā§āĻ āĻŦā§ āϏāĻāĻā§āϝāĻžāĻā§āϞ⧠āĻŦāĻžāĻĻ āĻĻā§ā§āĻž āϝāĻžā§ (if ($candidates[$i] > $target) break;
) -
memoization
āĻāϰ āĻĢāϞ⧠āĻāĻāĻ āĻāĻŽā§āĻŦāĻŋāύā§āĻļāύ āĻŦāĻžāϰāĻŦāĻžāϰ āĻā§āĻ āĻāϰāϤ⧠āĻšā§ āύāĻžāĨ¤
đ¤ āĻāĻĻāĻžāĻšāϰāĻŖ āĻāĻāĻāĻĒā§āĻ:
Array
(
[0] => Array
(
[0] => 2
[1] => 3
[2] => 3
)
[1] => Array
(
[0] => 3
[1] => 5
)
)
â āĻĒā§āϰāĻļā§āύ ⧍⧍: Laravel-āĻāϰ Eloquent ORM āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāĻāĻāĻŋ āĻā§ā§ā§āϰāĻŋ āϞāĻŋāĻā§āύ āϝāĻž āύāĻŋāĻā§āϰ āϤāĻĨā§āϝ āĻĢāĻŋāϰāĻŋā§ā§ āĻĻā§ā§:
- āĻāϤ ā§Šā§Ļ āĻĻāĻŋāύā§āϰ āĻŽāϧā§āϝ⧠āϝā§āϏāĻŦ āĻāĻāĻāĻžāϰ $1,000+ āĻ āϰā§āĻĄāĻžāϰ āĻāϰā§āĻā§āύ āϤāĻžāĻĻā§āϰ āϤāĻžāϞāĻŋāĻāĻž
- āĻĒā§āϰāϤā§āϝā§āĻ āĻāĻāĻāĻžāϰā§āϰ āĻŽā§āĻ āĻ āϰā§āĻĄāĻžāϰ āĻ ā§āϝāĻžāĻŽāĻžāĻāύā§āĻ āĻ āĻ āϰā§āĻĄāĻžāϰ āϏāĻāĻā§āϝāĻž
- āϤāĻžāĻĻā§āϰ āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻ āϏāϰā§āĻŦāĻļā§āώ āĻ āϰā§āĻĄāĻžāϰ eager load āĻāϰāϤ⧠āĻšāĻŦā§
â āĻāϤā§āϤāϰ:
đ§Š āϧāϰāĻž āϝāĻžāĻ āĻāĻĒāύāĻžāϰ āĻŽāĻĄā§āϞ āĻā§āϞ⧠āĻāĻŽāύ:
-
User
āĻŽāĻĄā§āϞā§āϰ āϏāĻžāĻĨā§orders(), profile()
āϰāĻŋāϞā§āĻļāύ āĻāĻā§ -
Order
āĻŽāĻĄā§āϞā§āϰamount, created_at
āĻĢāĻŋāϞā§āĻĄ āĻāĻā§
â
Laravel Eloquent ORM āĻā§āĻĄ:
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use App\Models\User;
$users = User::whereHas('orders', function ($query) {
$query->where('created_at', '>=', now()->subDays(30));
})
->withSum(['orders' => function ($query) {
$query->where('created_at', '>=', now()->subDays(30));
}], 'amount')
->withCount(['orders' => function ($query) {
$query->where('created_at', '>=', now()->subDays(30));
}])
->with(['profile', 'orders' => function ($query) {
$query->latest()->limit(1);
}])
->get()
->filter(function ($user) {
return $user->orders_sum_amount > 1000;
});
đ§ āĻā§ āĻšā§ā§āĻā§ āĻāĻāĻžāύā§:
đ āύā§āĻ:
-
orders_sum_amount
āĻāĻŦāĻorders_count
āĻ āĻā§ āĻā§āύāĻžāϰā§āĻā§āĻĄ āĻĢāĻŋāϞā§āĻĄ Laravel-āĻāϰwithSum() āĻ withCount()
āĻĨā§āĻā§ āĻāϏ⧠- āĻāĻāĻžāύ⧠āĻāĻŽāϰāĻž only those users āϰāĻžāĻāĻāĻŋ āϝāĻžāĻĻā§āϰ āĻāϤ ā§Šā§Ļ āĻĻāĻŋāύā§āϰ āĻ āϰā§āĻĄāĻžāϰ āĻā§āĻāĻžāϞ > 1000
â
āĻāĻĻāĻžāĻšāϰāĻŖ āϰāĻŋāĻāĻžāϰā§āύ āĻā§āϝāĻžāϞā§:
[
{
"id" => 1,
"name" => "Ruhul Amin",
"orders_sum_amount" => 1200,
"orders_count" => 3,
"profile" => [ ... ],
"orders" => [
[ "id" => 5, "amount" => 700, "created_at" => "..." ]
]
},
...
]
â āĻĒā§āϰāĻļā§āύ ā§¨ā§Š: Laravel-āĻ āĻāĻāĻāĻŋ āĻāĻžāϏā§āĻāĻŽ āϏāĻžāϰā§āĻāĻŋāϏ āϤā§āϰāĻŋ āĻāϰā§āύ āϝāĻž āĻŦāĻŋāĻāĻŋāύā§āύ salary heads (āϝā§āĻŽāύ: basic pay, allowances, deductions) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāϰā§āĻŽāĻāĻžāϰā§āĻĻā§āϰ āĻŽāĻžāϏāĻŋāĻ āĻŦā§āϤāύ āĻāĻŖāύāĻž āĻāϰāĻŦā§āĨ¤
- āϏāĻžāϰā§āĻāĻŋāϏāĻāĻŋ āϏāĻžāϰā§āĻāĻŋāϏ āĻāύā§āĻā§āĻāύāĻžāϰ⧠bind āĻāϰā§āύ
- āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻāύā§āĻā§āϰā§āϞāĻžāϰ⧠inject āĻāϰā§āύ āĻāĻŦāĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻĻā§āĻāĻžāύ
â āĻāϤā§āϤāϰ:
â āϧāĻžāĻĒā§ āϧāĻžāĻĒā§ āϏāĻŽāĻžāϧāĻžāύ
đ§ Step 1: āĻāĻžāϏā§āĻāĻŽ āϏāĻžāϰā§āĻāĻŋāϏ āĻā§āϞāĻžāϏ āϤā§āϰāĻŋ āĻāϰā§āύ
php artisan make:service SalaryCalculatorService
đŊ āĻŦāĻž āύāĻŋāĻā§ āϤā§āϰāĻŋ āĻāϰā§āύ:
đ app/Services/SalaryCalculatorService.php
namespace App\Services;
class SalaryCalculatorService
{
public function calculate(array $salaryData): float
{
$basic = $salaryData['basic'] ?? 0;
$allowances = $salaryData['allowances'] ?? 0;
$deductions = $salaryData['deductions'] ?? 0;
$totalSalary = $basic + $allowances - $deductions;
return max($totalSalary, 0); // āύā§āĻā§āĻāĻŋāĻ āĻšāϞ⧠ā§Ļ āϰāĻŋāĻāĻžāϰā§āύ
}
}
đ§Š Step 2: āϏāĻžāϰā§āĻāĻŋāϏ āĻāύā§āĻā§āĻāύāĻžāϰ⧠bind āĻāϰāĻž
đ app/Providers/AppServiceProvider.php
use App\Services\SalaryCalculatorService;
public function register(): void
{
$this->app->bind(SalaryCalculatorService::class, function ($app) {
return new SalaryCalculatorService();
});
}
đ§Ē Step 3: āĻāύā§āĻā§āϰā§āϞāĻžāϰ⧠āĻāύāĻā§āĻā§āĻ āĻāϰ⧠āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž
php artisan make:controller EmployeeController
đ app/Http/Controllers/EmployeeController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Services\SalaryCalculatorService;
class EmployeeController extends Controller
{
protected $salaryCalculator;
public function __construct(SalaryCalculatorService $salaryCalculator)
{
$this->salaryCalculator = $salaryCalculator;
}
public function calculateSalary(Request $request)
{
$salaryData = $request->only(['basic', 'allowances', 'deductions']);
$monthlySalary = $this->salaryCalculator->calculate($salaryData);
return response()->json([
'monthly_salary' => $monthlySalary,
]);
}
}
đ Step 4: āϰāĻžāĻāĻ āϝā§āĻā§āϤ āĻāϰāĻž
đ routes/web.php (āĻŦāĻž api.php)
use App\Http\Controllers\EmployeeController;
Route::post('/calculate-salary', [EmployeeController::class, 'calculateSalary']);
â
āĻāĻĻāĻžāĻšāϰāĻŖ āĻāύāĻĒā§āĻ (POST Request):
{
"basic": 20000,
"allowances": 5000,
"deductions": 3000
}
â
Response:
{
"monthly_salary": 22000
}
đ§ āĻāĻŋāĻĒāϏ:
- āĻāĻžāĻāϞ⧠āĻāĻĒāύāĻŋ SalaryCalculatorService-āĻ
calculateAnnual()
āĻŦāĻžgeneratePayslip()
āĻŽā§āĻĨāĻĄāĻ āϝā§āĻ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύāĨ¤ - āϏāĻžāϰā§āĻāĻŋāϏāĻā§ āĻāύā§āĻāĻžāϰāĻĢā§āϏ āĻĻāĻŋā§ā§ bind āĻāϰāϞā§āĻ āĻāĻžāϞ⧠practice āĻšā§āĨ¤
â āĻĒā§āϰāĻļā§āύ ⧍ā§Ē: Laravel-āĻāϰ Broadcasting āĻĢāĻŋāĻāĻžāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāĻāĻāĻŋ āϰāĻŋā§ā§āϞ-āĻāĻžāĻāĻŽ Notification System āϤā§āϰāĻŋ āĻāϰā§āύāĨ¤
- āĻāĻāĻāĻŋ āύāϤā§āύ āĻŦā§āϞāĻ āĻĒā§āϏā§āĻ āĻĒāĻžāĻŦāϞāĻŋāĻļ āĻšāϞ⧠āĻāĻāĻāĻŋ Event āĻā§āϰāĻŋāĻāĻžāϰ āĻāϰā§āύ
- Pusher āĻŦāĻž Laravel Echo āĻĻāĻŋā§ā§ āϏāĻāϞ āĻāĻžāύā§āĻā§āĻā§āĻĄ āĻāĻāĻāĻžāϰāĻā§ āϤāĻžā§āĻā§āώāĻŖāĻŋāĻ āύā§āĻāĻŋāĻĢāĻŋāĻā§āĻļāύ āĻĒāĻžāĻ āĻžāύ
â āĻāϤā§āϤāϰ:
â āϧāĻžāĻĒā§ āϧāĻžāĻĒā§ āϏāĻŽāĻžāϧāĻžāύ:
đ§ Step 1: Laravel Broadcast āϏāĻžāĻĒā§āϰā§āĻ āĻāĻžāϞā§
đ .env
āĻĢāĻžāĻāϞ⧠āϝā§āĻā§āϤ āĻāϰā§āύ:
BROADCAST_DRIVER=pusher
PUSHER_APP_ID=your_app_id
PUSHER_APP_KEY=your_app_key
PUSHER_APP_SECRET=your_app_secret
PUSHER_APP_CLUSTER=mt1
đ config/broadcasting.php:
'default' => env('BROADCAST_DRIVER', 'null'),
đĻ Step 2: āĻĒā§āϰā§ā§āĻāύā§ā§ āĻĒā§āϝāĻžāĻā§āĻ āĻāύāϏā§āĻāϞ āĻāϰā§āύ
composer require pusher/pusher-php-server
npm install --save laravel-echo pusher-js
âĄī¸ Step 3: āĻāĻā§āύā§āĻ āϤā§āϰāĻŋ āĻāϰā§āύ
php artisan make:event NewBlogPostPublished
đ app/Events/NewBlogPostPublished.php
namespace App\Events;
use App\Models\Post;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class NewBlogPostPublished implements ShouldBroadcast
{
use InteractsWithSockets, SerializesModels;
public $post;
public function __construct(Post $post)
{
$this->post = $post;
}
public function broadcastOn()
{
return new Channel('blog-posts');
}
public function broadcastAs()
{
return 'new-post';
}
}
âī¸ Step 4: āĻĒā§āϏā§āĻ āĻĒāĻžāĻŦāϞāĻŋāĻļā§ āĻāĻā§āύā§āĻ āĻā§āϰāĻŋāĻāĻžāϰ āĻāϰā§āύ
đ app/Http/Controllers/PostController.php
use App\Models\Post;
use App\Events\NewBlogPostPublished;
public function store(Request $request)
{
$post = Post::create($request->all());
broadcast(new NewBlogPostPublished($post))->toOthers();
return response()->json(['message' => 'Post published!']);
}
đ§Ē Step 5: āĻĢā§āϰāύā§āĻāĻāύā§āĻĄ (Laravel Echo + Pusher)
đ resources/js/bootstrap.js āĻŦāĻž resources/js/app.js
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'pusher',
key: import.meta.env.VITE_PUSHER_APP_KEY,
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
forceTLS: true
});
đ Component āĻŦāĻž Script-āĻ:
Echo.channel('blog-posts')
.listen('.new-post', (e) => {
console.log('đ āύāϤā§āύ āĻĒā§āϏā§āĻ:', e.post.title);
alert('New Blog Post: ' + e.post.title);
});
đĄ Step 6: Laravel WebSocket āĻāĻžāϞ⧠(Local Test āĻāϰ āĻāύā§āϝ)
composer require beyondcode/laravel-websockets
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider"
php artisan migrate
php artisan websockets:serve
â āĻāĻĒāϏāĻāĻšāĻžāϰ:
đ§ āĻ āϤāĻŋāϰāĻŋāĻā§āϤ āĻāĻŋāĻĒāϏ:
- āϝāĻĻāĻŋ āĻāĻĒāύāĻŋ āϞāĻāĻāύ āĻāĻāĻāĻžāϰā§āϰ āĻāύā§āϝ āĻŦā§āϝāĻā§āϤāĻŋāĻāϤ āĻā§āϝāĻžāύā§āϞ āĻāĻžāύ, āϤāĻžāĻšāϞā§
PrivateChannel
āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύāĨ¤ - āĻāύā§āύāϤ āĻŦā§āϝāĻŦāϏā§āĻĨāĻžāϰ āĻāύā§āϝ
Notification
āĻā§āϞāĻžāϏ āĻŦāĻžlaravel-notification-channels
āĻāĻāĻ āĻāϰāĻž āϝāĻžā§āĨ¤
â
āĻĒā§āϰāĻļā§āύ ⧍ā§Ģ: Laravel-āĻ āĻāĻāĻāĻŋ custom validation rule
āϤā§āϰāĻŋ āĻāϰā§āύ āϝāĻž Social Security Number (SSN) āĻāϰ āĻĢāϰāĻŽā§āϝāĻžāĻ (āϝā§āĻŽāύ 123-45-6789
) āϝāĻžāĻāĻžāĻ āĻāϰāĻŦā§āĨ¤
āĻĒāĻžāĻļāĻžāĻĒāĻžāĻļāĻŋ, āĻāĻāĻ āĻĢāϰāĻŽā§āϝāĻžāĻ āϝāĻžāĻāĻžāĻā§ā§āϰ āĻāύā§āϝ āĻāĻāĻāĻŋ Raw PHP āĻĢāĻžāĻāĻļāύ āϞāĻŋāĻā§āύāĨ¤
â āĻāϤā§āϤāϰ:
đĻ ā§§) Laravel Custom Validation Rule
đ§ āϧāĻžāĻĒ ā§§: āϰā§āϞ āϤā§āϰāĻŋ āĻāϰā§āύ
php artisan make:rule ValidSSN
đ app/Rules/ValidSSN.php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class ValidSSN implements Rule
{
public function passes($attribute, $value)
{
// Valid SSN format: 123-45-6789
return preg_match('/^\d{3}-\d{2}-\d{4}$/', $value);
}
public function message()
{
return 'The :attribute must be a valid SSN format (e.g. 123-45-6789).';
}
}
đĨ āϧāĻžāĻĒ ā§¨: āϰā§āϞ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ āĻĢāϰā§āĻŽ āϰāĻŋāĻā§ā§ā§āϏā§āĻ āĻŦāĻž āĻāύā§āĻā§āϰā§āϞāĻžāϰā§
â
āĻāĻĻāĻžāĻšāϰāĻŖ â Controller:
use App\Rules\ValidSSN;
public function store(Request $request)
{
$request->validate([
'ssn' => ['required', new ValidSSN()],
]);
// valid āĻšāϞ⧠āĻĄā§āĻāĻž āϏā§āĻ āĻāϰā§āύ
}
đР⧍) Raw PHP Function (SSN āĻĢāϰāĻŽā§āϝāĻžāĻ āϝāĻžāĻāĻžāĻ)
function isValidSSN($ssn)
{
return preg_match('/^\d{3}-\d{2}-\d{4}$/', $ssn);
}
// â
āĻāĻĻāĻžāĻšāϰāĻŖ
$ssn1 = "123-45-6789";
$ssn2 = "12-345-6789";
echo isValidSSN($ssn1) ? "Valid" : "Invalid"; // Valid
echo isValidSSN($ssn2) ? "Valid" : "Invalid"; // Invalid
â āϏāĻāĻā§āώā§āĻĒā§:
â āĻĒā§āϰāĻļā§āύ ⧍ā§Ŧ: Using Laravel's Cache facade, optimize a scenario where API responses are cached for frequent requests but invalidated whenever the corresponding database table is updated.
Use PHP's Redis extension for caching.Implement a fallback for file-based caching if Redis isn't available.
āϝā§āĻāĻžāύ⧠Laravel Cache Facade āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠API āϰā§āϏāĻĒāύā§āϏ āĻā§āϝāĻžāĻļ āĻāϰāĻž āĻšā§ā§āĻā§ āĻāĻŦāĻ āĻĄāĻžāĻāĻžāĻŦā§āĻ āĻāĻĒāĻĄā§āĻ āĻšāϞā§āĻ āĻā§āϝāĻžāĻļ āĻāύāĻā§āϝāĻžāϞāĻŋāĻĄ āĻšāĻā§āĻā§āĨ¤ Redis āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āĻšā§ā§āĻā§ āĻāĻŦāĻ Redis āύāĻž āĻĨāĻžāĻāϞ⧠file-based fallback āĻ āϝā§āĻā§āϤ āĻāĻā§āĨ¤
â āĻāϤā§āϤāϰ:
â āϞāĻā§āώā§āϝ:
- API āϰā§āϏāĻĒāύā§āϏ āĻā§āϝāĻžāĻļ āĻāϰāϤ⧠āĻšāĻŦā§
- āĻā§āϝāĻžāĻļ āϤāĻāύāĻ āĻāύāĻā§āϝāĻžāϞāĻŋāĻĄ āĻšāĻŦā§ āϝāĻāύ āĻĄāĻžāĻāĻžāĻŦā§āĻ āĻāĻĒāĻĄā§āĻ āĻšā§
- Redis āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŦ, āĻāĻŋāύā§āϤ⧠Redis āύāĻž āĻĨāĻžāĻāϞ⧠file fallback āĻšāĻŦā§
đ§ āϧāĻžāĻĒ ā§§: .env
āĻ cache.php
āĻĢāĻžāĻāϞ āĻāύāĻĢāĻŋāĻāĻžāϰ āĻāϰā§āύ
â
.env
āĻĢāĻžāĻāϞ⧠āϝā§āĻā§āϤ āĻāϰā§āύ:
CACHE_DRIVER=redis
REDIS_CLIENT=phpredis
â
config/cache.php
'default' => env('CACHE_DRIVER', 'file'), // Redis āύāĻž āĻĨāĻžāĻāϞ⧠fallback 'file'
Laravel āϏā§āĻŦā§āĻāĻā§āϰāĻŋā§āĻāĻžāĻŦā§ fallback cache āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āĨ¤
đĻ āϧāĻžāĻĒ ā§¨: Redis āϏā§āĻāĻāĻĒ
Redis āĻāύā§āϏāĻāϞ āĻāϰā§āύ (āĻāĻŦā§āύā§āĻā§):
sudo apt install redis
sudo systemctl enable redis
sudo systemctl start redis
Laravel Redis āĻĒā§āϝāĻžāĻā§āĻ āĻāĻā§ āĻĨā§āĻā§āĻ āĻ
āύā§āϤāϰā§āĻā§āĻā§āϤ āĻĨāĻžāĻā§āĨ¤ āϤāĻŦā§ āύāĻŋāĻļā§āĻāĻŋāϤ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ:
composer require predis/predis
đ āϧāĻžāĻĒ ā§Š: API āϰā§āϏāĻĒāύā§āϏ āĻā§āϝāĻžāĻļ āĻāϰā§āύ
āϧāϰāĻŋ /api/products
āϰāĻžāĻāĻ āϰā§ā§āĻā§āĨ¤
đ ProductController.php
use Illuminate\Support\Facades\Cache;
use App\Models\Product;
public function index()
{
$cacheKey = 'products.all';
// Redis/File Cache āĻĨā§āĻā§ āϰā§āϏāĻĒāύā§āϏ āύā§āĻā§āĻž, āύāĻž āĻĨāĻžāĻāϞ⧠DB āĻĨā§āĻā§
$products = Cache::remember($cacheKey, 60, function () {
return Product::all();
});
return response()->json($products);
}
đ§š āϧāĻžāĻĒ ā§Ē: āĻā§āϝāĻžāĻļ āĻāύāĻā§āϝāĻžāϞāĻŋāĻĄ āĻāϰāĻž āϝāĻāύ āĻĄā§āĻāĻž āĻāĻĒāĻĄā§āĻ āĻšā§
đ ProductController.php
public function update(Request $request, $id)
{
$product = Product::findOrFail($id);
$product->update($request->all());
// āĻā§āϝāĻžāĻļ āĻĄāĻŋāϞāĻŋāĻ
Cache::forget('products.all');
return response()->json(['message' => 'Product updated']);
}
āĻāĻāĻžāĻŦā§ āĻāĻĒāύāĻŋ store()
āĻŦāĻž delete()
āĻŽā§āĻĨāĻĄā§āĻ Cache::forget()
āϝā§āĻ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύāĨ¤
đ¯ Optional: Observer āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻ āĻā§ āĻā§āϝāĻžāĻļ āĻāύāĻā§āϝāĻžāϞāĻŋāĻĄā§āĻļāύ
đ app/Observers/ProductObserver.php
namespace App\Observers;
use App\Models\Product;
use Illuminate\Support\Facades\Cache;
class ProductObserver
{
public function saved(Product $product)
{
Cache::forget('products.all');
}
public function deleted(Product $product)
{
Cache::forget('products.all');
}
}
đ AppServiceProvider.php
use App\Models\Product;
use App\Observers\ProductObserver;
public function boot()
{
Product::observe(ProductObserver::class);
}
đ§Ē Bonus: Cache fallback āϝāĻžāĻāĻžāĻ
āĻāĻĒāύāĻŋ Redis āϏāĻžāϰā§āĻāĻžāϰ āĻŦāύā§āϧ āĻāϰ⧠file
fallback āĻāĻžāĻ āĻāϰāĻā§ āĻāĻŋāύāĻž āĻĻā§āĻā§āύ:
sudo systemctl stop redis
php artisan route:clear
php artisan config:clear
āϰāĻžāύ āĻāϰāϞ⧠Laravel āύāĻŋāĻā§āĻ fallback āĻĄā§āϰāĻžāĻāĻāĻžāϰ⧠(file) āĻāϞ⧠āϝāĻžāĻŦā§āĨ¤
â āϏāĻžāϰāϏāĻāĻā§āώā§āĻĒ:
â āĻĒā§āϰāĻļā§āύ ⧍ā§: āϤā§āĻŽāĻŋ āĻāĻāĻāĻŋ Laravel āĻā§āĻĄ āĻĒā§ā§ā§āĻā§ āϝāĻž āĻ
āύā§āĻ āϧā§āϰāĻāϤāĻŋāϤ⧠āĻāϞāĻā§āĨ¤ āύāĻŋāĻā§āϰ āĻā§āĻĄāĻāĻŋ āĻā§āĻāĻžāĻŦā§ āĻ
āĻĒāĻāĻŋāĻŽāĻžāĻāĻ āĻāϰāĻŦā§ āϝāĻžāϤ⧠āĻĄāĻžāĻāĻžāĻŦā§āĻ āĻā§ā§ā§āϰāĻŋāϰ āϏāĻāĻā§āϝāĻž āĻāĻŽāĻžāύ⧠āϝāĻžā§?
$orders = Order::where('status', 'completed')->get();
foreach ($orders as $order) {
$items = $order->items;
foreach ($items as $item) {
$details = $item->details;
}
}
â āĻāϤā§āϤāϰ:
āĻāĻĒāϰā§āϰ āĻā§āĻĄāĻāĻŋ N+1 Query Problem āĻāϰ āĻļāĻŋāĻāĻžāϰāĨ¤ āĻĒā§āϰāϤāĻŋāĻāĻŋ Order
āĻāϰ āĻāύā§āϝ āĻāϞāĻžāĻĻāĻž āĻāϰ⧠items
āĻāĻŦāĻ āĻĒā§āϰāϤāĻŋāĻāĻŋ item
āĻāϰ āĻāύā§āϝ āĻāϞāĻžāĻĻāĻž āĻāϰ⧠details
āĻā§ā§ā§āϝāĻžāϰāĻŋ āĻāĻžāϞāĻžāύ⧠āĻšāĻā§āĻā§āĨ¤ āĻāϰ āĻĢāϞ⧠āĻ
āύā§āĻāĻā§āϞ⧠āĻ
āĻĒā§āϰā§ā§āĻāύā§ā§ āĻĄāĻžāĻāĻžāĻŦā§āĻ āĻšāĻŋāĻ āĻšā§āĨ¤
đ§ āϏāĻŽāĻžāϧāĻžāύ: Eager Loading āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ
Laravel-āĻāϰ with()
āĻŽā§āĻĨāĻĄ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāĻŽāϰāĻž āĻĒā§āϰā§ā§āĻāύā§ā§ āϰāĻŋāϞā§āĻļāύāĻā§āϞ⧠āĻāĻāϏāĻžāĻĨā§ āϞā§āĻĄ āĻāϰāϤ⧠āĻĒāĻžāϰāĻŋāĨ¤
â
āĻ
āĻĒāĻāĻŋāĻŽāĻžāĻāĻāĻĄ āĻā§āĻĄ:
$orders = Order::with('items.details')
->where('status', 'completed')
->get();
foreach ($orders as $order) {
foreach ($order->items as $item) {
$details = $item->details;
}
}
đ§ āĻŦā§āϝāĻžāĻā§āϝāĻž:
đ āĻĢāϞāĻžāĻĢāϞ:
- Performance āĻŦā§āĻĻā§āϧāĻŋ āĻĒāĻžāĻŦā§
- Query āϏāĻāĻā§āϝāĻž āĻāĻŽāĻŦā§
- Memory Efficient āĻšāĻŦā§
- āĻĄā§āĻāĻž āĻāĻāϏāĻžāĻĨā§ āĻā§āϝāĻžāĻļā§ āĻĨāĻžāĻāϤ⧠āĻĒāĻžāϰāĻŦā§
â āϏāĻāĻā§āώā§āĻĒā§:
â āĻĒā§āϰāĻļā§āύ 28: . You are given the following PHP script, which processes a large array, Rewrite it to reduce memory usage without changing the output.
code:
$data = [];
for ($i = 0; $i < 100000; $i++) {
$data[] = str_repeat('X', 1000);
}
echo array_sum(array_map('strlen', $data));
â āĻāϤā§āϤāϰ:
āύāĻŋāĻļā§āĻā§āĻ! āύāĻŋāĻā§ āĻĻā§āĻā§āĻž āĻā§āĻĄāĻāĻŋ āĻāĻāĻāĻŋ āĻŦā§ āĻ
ā§āϝāĻžāϰ⧠$data āϤā§āϰāĻŋ āĻāϰ⧠āϝā§āĻāĻžāύ⧠⧧ āϞāĻžāĻ āĻāϞāĻŋāĻŽā§āύā§āĻ āĻāĻā§, āĻĒā§āϰāϤāĻŋāĻāĻŋāϤ⧠⧧ā§Ļā§Ļā§Ļ āĻŦāĻžāϰā§āϰ 'X'
āĻĨāĻžāĻā§āĨ¤ āĻāϰāĻĒāϰ strlen()
āĻĻāĻŋā§ā§ āĻĒā§āϰāϤāĻŋāĻāĻŋ āϏā§āĻā§āϰāĻŋāĻā§ā§āϰ āĻĻā§āϰā§āĻā§āϝ āĻŦā§āϰ āĻāϰ⧠āϤāĻžāĻĻā§āϰ āϝā§āĻāĻĢāϞ āĻĒā§āϰāĻŋāύā§āĻ āĻāϰā§āĨ¤
đ´ āĻŽā§āϞ āϏāĻŽāϏā§āϝāĻž:
$data[] = str_repeat('X', 1000);
āĻāĻāĻžāĻŦā§ ā§§ āϞāĻžāĻ āĻŦā§ āϏā§āĻā§āϰāĻŋāĻ āĻŽā§āĻŽā§āϰāĻŋāϤ⧠āϰā§āĻā§ āĻĻā§ā§, āϝāĻž āĻĒā§āϰāĻā§āϰ āĻŽā§āĻŽā§āϰāĻŋ āĻāϰāĻ āĻāϰā§āĨ¤
â āϞāĻā§āώā§āϝ:
- āĻāĻāĻ āĻāĻāĻāĻĒā§āĻ
- āĻāĻŋāύā§āϤ⧠āĻāĻŽ memory consumption
â
āĻ
āĻĒāĻāĻŋāĻŽāĻžāĻāĻāĻĄ āĻāĻžāϰā§āϏāύ:
$totalLength = 0;
for ($i = 0; $i < 100000; $i++) {
$totalLength += strlen(str_repeat('X', 1000));
}
echo $totalLength;
â āĻŦā§āϝāĻžāĻā§āϝāĻž:
- āĻāĻŽāϰāĻž āĻĒā§āϰ⧠āĻ
ā§āϝāĻžāϰā§
$data
āĻŽā§āĻŽā§āϰāĻŋāϤ⧠āĻāĻŽāĻžāĻ āύāĻžāĨ¤ - āϏāϰāĻžāϏāϰāĻŋ āĻĒā§āϰāϤāĻŋāĻāĻŋ āϏā§āĻā§āϰāĻŋāĻā§ā§āϰ
strlen
āĻŦā§āϰ āĻāϰā§totalLength
āĻ āϝā§āĻ āĻāϰāĻŋāĨ¤ - āĻŽā§āĻŽā§āϰāĻŋāϤ⧠1 āϞāĻžāĻ āϏā§āĻā§āϰāĻŋāĻ āύāĻž āϰā§āĻā§ āϏāϰāĻžāϏāϰāĻŋ āϝā§āĻāĻĢāϞ āĻāϰāĻž āĻšā§, āĻĢāϞ⧠Memory Usage āĻ āύā§āĻ āĻāĻŽā§ āϝāĻžā§āĨ¤
đ āĻāĻāĻāĻĒā§āĻ:
100000000
āĻāĻžāϰāĻŖ
100000 * 1000 = 100,000,000
āĻāϰāĻŋāϤā§āϰ
â āĻ āϤāĻŋāϰāĻŋāĻā§āϤ āĻāĻŋāĻĒāϏ:
- Laravel āĻŦāĻž PHP performance optimization-āĻāϰ āϏāĻŽā§ "avoid keeping large arrays in memory" āĻā§āĻŦ āĻā§āϰā§āϤā§āĻŦāĻĒā§āϰā§āĻŖ āĻŦāĻŋāώā§āĨ¤
- āĻāĻāĻ āĻā§āĻļāϞ āĻāĻĒāύāĻŋ CSV read, log process, āĻŦāĻž large dataset āĻā§āϞā§āϰ āĻā§āώā§āϤā§āϰā§āĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ â
streaming āĻŦāĻž on-the-fly processing
āĨ¤
â āĻĒā§āϰāĻļā§āύ 29:. Write a raw PHP script to handle form submission with:
- XSS protection for input fields.
- CSRF token generation and validation.
â āĻāϤā§āϤāϰ:
āĻ āĻŦāĻļā§āϝāĻ! āύāĻŋāĻā§ āĻāĻāĻāĻŋ āϏāĻŽā§āĻĒā§āϰā§āĻŖ Raw PHP āϏā§āĻā§āϰāĻŋāĻĒā§āĻ āĻĻā§āĻā§āĻž āĻšāϞ⧠āϝāĻž āĻāĻāĻāĻŋ āĻĢāϰā§āĻŽ āĻĒā§āϰāϏā§āϏ āĻāϰ⧠āĻāĻŦāĻ āϤāĻžāϤā§:
â
XSS Protection
â
CSRF Token Generation & Validation
āĻāĻā§ āϏāĻŋāĻāĻŋāĻāϰāĻŋāĻāĻŋ āĻŦā§āϝāĻŦāϏā§āĻĨāĻž āĻ āύā§āϤāϰā§āĻā§āĻā§āϤ āĻāϰāĻž āĻšā§ā§āĻā§āĨ¤
â
Step-by-Step Raw PHP Script
đ form.php
<?php
session_start();
// â
CSRF Token Generate
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
// â
āϝāĻĻāĻŋ POST āϏāĻžāĻŦāĻŽāĻŋāĻ āĻšā§
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// â
1. CSRF Token Validate
if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die('CSRF token validation failed!');
}
// â
2. XSS Protection â input sanitize
$name = htmlspecialchars(trim($_POST['name'] ?? ''));
$email = htmlspecialchars(trim($_POST['email'] ?? ''));
echo "<h3>Form submitted safely!</h3>";
echo "Name: " . $name . "<br>";
echo "Email: " . $email . "<br>";
// â
Optional: regenerate token for next form
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
?>
<!-- â
HTML Form -->
<!DOCTYPE html>
<html>
<head><title>Secure Form</title></head>
<body>
<h2>Secure Form</h2>
<form method="POST" action="form.php">
<label>Name:</label><br>
<input type="text" name="name" required><br><br>
<label>Email:</label><br>
<input type="email" name="email" required><br><br>
<!-- â
CSRF Token -->
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
<button type="submit">Submit</button>
</form>
</body>
</html>
đ Breakdown
â
Example Output:
Form submitted safely!
Name: Ruhul Amin
Email: ruhul@example.com
đĄī¸ Extra Security Tips:
- XSS āϰā§āϧ⧠āĻĒā§āϰāϤāĻŋāĻāĻŋ āĻāĻāĻāĻĒā§āĻā§āĻ
htmlspecialchars()
āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ - CSRF Token āĻĒā§āϰāϤāĻŋāĻāĻŋ āĻĢāϰā§āĻŽā§ āύāϤā§āύ āĻāϰ⧠āĻā§āύāĻžāϰā§āĻ āĻāϰāĻž āĻāĻžāϞ⧠(per request)
- āĻāϰāĻ āĻļāĻā§āϤāĻŋāĻļāĻžāϞ⧠validation-āĻāϰ āĻāύā§āϝ
filter_var()
āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ
â āĻĒā§āϰāĻļā§āύ 30: Implement a custom artisan command to archive orders older than 1 year by:
Moving them to an archive table.Logging the operation details to a custom log file.Handling errors gracefully with retries and notifications.
â āĻāϤā§āϤāϰ:
āĻ āĻŦāĻļā§āϝāĻ! āύāĻŋāĻā§ Laravel Custom Artisan Command āĻāϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻāĻāĻāĻŋ āϏāĻŽā§āĻĒā§āϰā§āĻŖ āϏāĻŽāĻžāϧāĻžāύ āĻĻā§āĻā§āĻž āĻšāϞ⧠āϝā§āĻāĻžāύā§:
â
ā§§ āĻŦāĻāϰā§āϰ āĻĒā§āϰā§āύ⧠āĻ
āϰā§āĻĄāĻžāϰāĻā§āϞ⧠orders
āĻā§āĻŦāĻŋāϞ āĻĨā§āĻā§ archived_orders
āĻā§āĻŦāĻŋāϞ⧠āϏāϰāĻŋā§ā§ āύā§āĻā§āĻž āĻšāĻā§āĻā§
â
āĻ
āĻĒāĻžāϰā§āĻļāύ āĻĄāĻŋāĻā§āĻāϞāϏ custom log file āĻ āϏāĻāϰāĻā§āώāĻŖ āĻāϰāĻž āĻšāĻā§āĻā§
â
āϰāĻŋāĻā§āϰāĻžāĻ āĻ āύā§āĻāĻŋāĻĢāĻŋāĻā§āĻļāύ āϏāĻš error handling āĻŦā§āϝāĻŦāϏā§āĻĨāĻžāĻ āϰāĻžāĻāĻž āĻšā§ā§āĻā§
đ ī¸ āϧāĻžāĻĒ ā§§: archived_orders
āĻŽāĻžāĻāĻā§āϰā§āĻļāύ āϤā§āϰāĻŋ āĻāϰā§āύ
php artisan make:migration create_archived_orders_table
đ database/migrations/xxxx_xx_xx_create_archived_orders_table.php
public function up()
{
Schema::create('archived_orders', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->decimal('amount', 10, 2);
$table->timestamps();
});
}
php artisan migrate
đ§âđģ āϧāĻžāĻĒ ā§¨: āĻāĻžāϏā§āĻāĻŽ āĻāĻŽāĻžāύā§āĻĄ āϤā§āϰāĻŋ āĻāϰā§āύ
php artisan make:command ArchiveOldOrders
đ app/Console/Commands/ArchiveOldOrders.php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Throwable;
class ArchiveOldOrders extends Command
{
protected $signature = 'orders:archive-old';
protected $description = 'Archive orders older than 1 year to archived_orders table';
public function handle()
{
$this->info('Starting archive process...');
$attempts = 0;
$maxAttempts = 3;
do {
try {
DB::beginTransaction();
$oldOrders = DB::table('orders')
->where('created_at', '<', now()->subYear())
->get();
foreach ($oldOrders as $order) {
DB::table('archived_orders')->insert([
'id' => $order->id,
'user_id' => $order->user_id,
'amount' => $order->amount,
'created_at'=> $order->created_at,
'updated_at'=> $order->updated_at,
]);
DB::table('orders')->where('id', $order->id)->delete();
// â
āĻāĻžāϏā§āĻāĻŽ āϞāĻ āĻĢāĻžāĻāϞ⧠āϞāĻ āĻāϰāĻž
Log::channel('archive')->info("Archived order ID: {$order->id}");
}
DB::commit();
$this->info('Archiving complete. Total orders: ' . count($oldOrders));
return Command::SUCCESS;
} catch (Throwable $e) {
DB::rollBack();
$attempts++;
Log::channel('archive')->error("Attempt {$attempts} failed: " . $e->getMessage());
if ($attempts >= $maxAttempts) {
$this->error('Archiving failed after 3 attempts.');
// â
Email or Slack notification if needed
// Notification::route('mail', 'admin@example.com')->notify(new ArchiveFailedNotification($e));
return Command::FAILURE;
}
$this->warn("Retrying... (Attempt: {$attempts})");
sleep(2); // delay between retries
}
} while ($attempts < $maxAttempts);
}
}
đ āϧāĻžāĻĒ ā§Š: āĻāĻžāϏā§āĻāĻŽ āϞāĻ āĻā§āϝāĻžāύā§āϞ āϤā§āϰāĻŋ āĻāϰā§āύ
đ config/logging.php
āĻ channels
āϏā§āĻāĻļāύ⧠āϝā§āĻā§āϤ āĻāϰā§āύ:
'archive' => [
'driver' => 'single',
'path' => storage_path('logs/order-archive.log'),
'level' => 'info',
],
đ āϧāĻžāĻĒ ā§Ē: Artisan Command āϰāĻžāύ āĻāϰā§āύ
php artisan orders:archive-old
đ āϞāĻ āĻĢāĻžāĻāϞ
āϞāĻ āĻĒāĻžāĻŦā§āύ āĻāĻāĻžāύā§:
storage/logs/order-archive.log
āĻāĻĻāĻžāĻšāϰāĻŖ:
[2025-05-26 12:30:00] local.INFO: Archived order ID: 10123
[2025-05-26 12:30:00] local.INFO: Archived order ID: 10124
đ Bonus: āύā§āĻāĻŋāĻĢāĻŋāĻā§āĻļāύ āĻĢā§āĻāϞ āĻšāϞā§
// Notification::route('mail', 'admin@example.com')
// ->notify(new ArchiveFailedNotification($e));
āĻāĻžāĻāϞ⧠āĻāĻŽāĻŋ ArchiveFailedNotification
āĻā§āϞāĻžāϏāĻ āϤā§āϰāĻŋ āĻāϰ⧠āĻĻāĻŋāϤ⧠āĻĒāĻžāϰāĻŋāĨ¤
â āϏāĻāĻā§āώā§āĻĒā§
Top comments (0)