Laravel Framework Basics পর্ব-৩: Laravel Routes

Last Updated on August 6, 2022 by Masud Alam

Laravel Route কি?

Route

সাধারণত ইংরেজি শব্দ route যাকে অনেক সময় আমরা বাংলায় বলি রুট যার অর্থ দাঁড়ায় গন্তব্যস্থলে পৌঁছানোর রাস্তা। আর Laravel Application এ route হচ্ছে URL থেকে request গ্রহণ করে এবং application কে resource এর জন্য নির্দেশনা প্রদান করে। আরো সহজ ভাবে বলা যায় route হল আপনার অ্যাপ্লিকেশনের একটি request এর বিপরীতে কোন URL টি hit হবে? বা কোথায় থেকে কি response করবে তা নির্ধারণের একটি উপায়। Laravel এ সব route গুলো routes ফোল্ডারে তৈরী করা থাকে। এর মধ্যে web application এর route সমূহ routes/web.php তে লিখা হয়। এবং API এর জন্য route সমূহ routes/api.php তে লিখা হয়। Laravel Framework এ route এর সবচেয়ে বড় সুবিধা হচ্ছে আপনি এক যায়গা থেকেই সমস্ত route কে নিয়ন্ত্রণ করতে পারবেন অর্থাৎ পরবর্তিতে route সম্পর্কিত যেকোনো ধরনের পরিবর্তন এখান থেকেই করতে পারবেন।

Laravel Route এর প্রাথমিক ধারণা

Laravel Route লিখার আগে আপনাকে PHP Anonymous Function, Closure এবং PHP Class এর Static Method সম্পর্কে ধারণা থাকা দরকার, আমরা ধরে নিলাম আপনি এই গুলো জানেন। তো আসা যাক কিভাবে route দিয়ে URL Request গুলো Manage করতে পারি। ধরুন আমাদের Web Application এ তিনটি পেজ আছে , সেগুলো যথাক্রমে Home, About এবং Contact. এখন Web Application ব্যবহারকারী এই তিনটি পেজ এর মধ্যে যাকে request করবে শুধু সংশ্লিষ্ট পেজটি response করবে। অনেকটা নিচের URL এর মত:

for Home page:

http://localhost:8000/

for About page:

http://localhost:8000/about

for Contact page:

http://localhost:8000/contact

এখন এই তিনটি URL Request এর জন্য আপনি Laravel এর routes/web.php ফাইল এ ঠিক নিচের মত করে লিখতে পারেন।

Route::get('/', function (){
    echo "<h2>This is Home Page</h2>;
});
Route::get('/about', function (){
    echo "<h2> This is About Page</h2>";
});
Route::get('/contact', function (){
    echo "<h2> This is Contact Page</h2>";
}); 

এখন আপনি আপনার ব্রাউজার এর Address bar এ http://localhost:8000 , http://localhost:8000/about এবং http://localhost:8000/contact লিখে hit করুন, তাহলে আপনার route ঠিক নিম্নের screenshot গুলোর মতো রেজাল্ট দেখাবে:

Contact Us Page

About Us Page

নোট: অবশ্যই ” php artisan serve ” command দিয়ে server run রাখতে ভুলবেননা।

ব্যাখ্যা: উপরোক্ত উদাহরণে আমরা Route class এর get() মেথডকে call করেছি। Route Class এর get() মেথডটি দুইটি Argument গ্রহণ করে। প্রথম Argument হিসেবে URL Path অর্থাৎ যেই URL এ hit করবে সেটি, এবং দ্বিতীয় Argument হিসেবে একটি Anonymous Function সাথে closure থাকতে পারে। যেমনঃ উপরোক্ত উদাহরণে আমাদের Home URL এর জন্য প্রথম আর্গুমেন্ট হিসেবে শুধু forward slash ( / ) ব্যবহার করি , যার দ্বারা Laravel route রুট ডোমেইনকে নির্দেশ করে। একই ভাবে About URL এর জন্য forward slash সাথে about (/about) এবং Contact URL এর জন্য forward slash সাথে contact(/contact) লিখি। আর তিনটি URL এর জন্যই দ্বিতীয় Argument হিসেবে একটি Anonymous Function ব্যবহার করি যার দ্বারা action কি হবে তা নির্ধারণ করি।

Laravel Mastering Course

Available Router Methods

Laravel 9.0 এ মূলত ছয় ধরণের মেথড রয়েছে। যা দিয়ে আপনি বিভিন্ন ধরণের HTTP Request এবং Response এর কাজ গুলো করতে পারেন।

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
Route::match(['http_method_1','http_method_n'], $uri, $callback);
Route::any($uri, $callback);

কখনো কখনো আপনাকে এমন একটি route তৈরি করতে হতে পারে যা একাধিক বা ভিন্ন ধরণের HTTP রিকোয়েস্ট কে গ্রহণ করে। এই কাজটি আপনি match method ব্যবহার করে করতে পারেন। অথবা, আপনি এমন একটি route তৈরি করতে পারেন যা যেকোনো পদ্ধতি ব্যবহার করে সমস্ত HTTP রিকোয়েস্ট কে গ্রহণ করে। নিচের উদাহরণটি দেখুন:

Route::match(['get', 'post'], '/', function () {
    //
});
 
Route::any('/', function () {
    //
});

Dependency Injection

আপনি চাইলে আপনার route এর callback ফাঙ্কশনের প্যারামিটারে আপনার route এর জন্য প্রয়োজনীয় লারাভেলের যেকোনো dependencies ক্লাস লাইব্রেরি এর type-hint সুবিধা ব্যবহার করতে পারেন। ঘোষিত dependencies ক্লাসটি স্বয়ংক্রিয়ভাবে লোড হবে এবং route এ ব্যবহারের সুযোগ হবে এবং Laravel service container দ্বারা কলব্যাক ফাঙ্কশনে ব্যবহার করা যাবে। উদাহরণস্বরূপ, আপনি আপনার route কলব্যাকে বর্তমান HTTP Request স্বয়ংক্রিয়ভাবে ব্যবহার করার জন্য Illuminate\Http\Request ক্লাসের type-hint করতে পারেন:

use Illuminate\Http\Request;
 
Route::get('/users', function (Request $request) {
    // ...
});

CSRF Protection

মনে রাখবেন, route ফাইলে সংজ্ঞায়িত POST, PUT, PATCH বা DELETE route এর দিকে পয়েন্ট করা যেকোন HTML ফর্মে অবশ্যই একটি CSRF টোকেন অন্তর্ভুক্ত করা উচিত। অন্যথায়, রিকোয়েস্ট রিজেক্ট করা হবে. আপনি CSRF ডকুমেন্টেশনে CSRF প্রটেকশন সম্পর্কে আরও পড়তে পারেন:

<form method="POST" action="/profile">
    @csrf
    ...
</form>

Redirect Routes

আপনি যদি একটি URL কে অন্য একটা URL এ redirect করতে চান , তাহলে আপনি লারাভেলের Route::redirect method টি ব্যবহার করতে পারেন। আর এর সিনটেক্স তা ঠিক নিচের মতো করে হবে:

Route::get('/here', function () {
    return "You're here!";
}); 

Route::get('/there', function () {
    return "You're there!";
}); 
Route::redirect('/here', '/there');

বাই ডিফল্ট Route::redirect মেথড টি ৩০২ স্টেটাস কোড রিটার্ন করে। তবে আপনি চাইলে এটিকে কাস্টমাইজ করতে পারেন।

Route::redirect('/here', '/there', 301);

View Routes

যদি আপনার route শুধু মাত্র একটা view রিটার্ন প্রয়োজন হয়, তাহলে আপনি Route::view এই method টি ব্যবহার করতে পারেন। অনেকটা redirect method এর মতো, অর্থাৎ আপনাকে একটা সম্পূর্ণ route বা controller ডিফাইন করতে হবেনা । view method এর মধ্যে প্রথম আর্গুমেন্ট টি হবে একটি URI এবং দ্বিতীয় আর্গুমেন্ট টি হবে একটি view file । এছাড়াও, আপনি অপশনাল হিসেবে তৃতীয় argument হিসেবে view তে একটা array পাস করতে পারেন:

Route::view('/welcome', 'welcome');
 
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);

Laravel Route Parameter নিয়ে কাজ

অবশ্যই, কখনও কখনও আপনাকে আপনার route মধ্যে URI এর segment গুলিকে receive বা capture করতে হবে। এটি করার জন্য Laravel Route এ চারটি উপায় আছে যার মাধ্যমে আপনি URL- এর মাধ্যমে পাঠানো Parameter গুলিকে Capture করতে পারেন।

  1. Required Parameters
  2. Optional Parameters
  3. Regular Expression Constraints
  4. Global Constraints

Required Parameters

অর্থাৎ আপনার URL এ অবশ্যই Parameter থাকতে হবে। ধরুন আপনাকে URL থেকে ইউজারদের নাম capture করতে হতে পারে । আপনাকে route এ Parameter define করে তা করতে হবে । একটি উদাহরণ দিয়ে যাক ।

// get the parameter of name
Route::get('students/{name}', function($name) {
        echo 'Students Name is ' . $name;
}); 

এখন আপনার ব্রাউজারে, আপনি নিচের মতো করে student name এ access করতে পারেন।


http://localhost:8000/students/Masud

Parameter

আর যদি URL এ কোনো Parameter না দেন বা খালি রাখেন, Laravel আপনাকে নিচের Message টি দিবে :

"Sorry, the page you are looking for could not be found."

একইভাবে আপনি একাধিক Required Parameter পাঠাতে পারেন, নিচের উদাহরণ লক্ষ্য করুন :

// get the parameter of name
Route::get('students/{name}/{age}', function($name,$age) {
        echo "Students Name is  $name and he is $age years old";
}); 

এখন আপনার ব্রাউজারে, আপনি নিচের মতো করে student name এবং তার age এ access করতে পারেন।


http://localhost:8000/students/Masud/30

Multiple Required Paramter

এক্ষেত্রে আপনি চাইলে সরাসরি Request class এর Object দিয়েও data রিসিভ গ্রহণ পারেন। নিচের উদাহরণ লক্ষ্য করুন :

use Illuminate\Http\Request;

Route::get('/user/{name}', function (Request $request) {
    return "User name: ".$request->name;
});
Receive URL Data using Request Object

Laravel Receive URL Data using Request Object in Route

Parameters & Dependency Injection

যদি আপনার route এ dependencies থাকে তখন আপনি যদি চান যে Laravel service container টি স্বয়ংক্রিয়ভাবে আপনার route এর callback এ চলে আসুক , তাহলে আপনার dependencies গুলোর পরে আপনার route এর parameter গুলি রাখা উচিত। নিচের উদাহরণ দেখুন :

use Illuminate\Http\Request;
 
Route::get('/user/{id}/{name}', function (Request $request, $id, $name) {
    return "User Id : $id and Name: $name";
});
Route Parameters & Dependency Injection

Parameters & Dependency Injection

Optional Parameters

আপনি যদি আপনার URL এ এমন কিছু Parameter পাঠাতে চান , যা থাকতেও পারে আবার নাও থাকতে পারে। এই সব ক্ষেত্রে আপনাকে Laravel এর Optional Parameter System ব্যবহার করতে হবে। তখন URL এ এই প্যারামিটার গুলির থাকার আবশ্যকীয় নয়। আর এই Parameter গুলির নামের পরে “?” চিহ্ন দিতে হয়। নিম্নের কোডটি লক্ষ্য করুন :

Route::get('/user/{name?}', function ($name = null) {
    return $name;
});
 
Route::get('/user/{name?}', function ($name = 'Masud Alam') {
    return $name;
});

এখন আপনার URL এ যেই Parameter পাঠাবেন সেটা দেখাবে, অন্যথা default Parameter Masud Alam দেখাবে। নিম্নের ছবিতে লক্ষ্য করুন :

Route with Optional Parameter

একইভাবে আপনি একাধিক Optional Parameter পাঠাতে পারেন, নিচের উদাহরণ লক্ষ্য করুন :

Route::get('users/{name?}/{age?}', function($name="Masud Alam",$age=30) {
        echo "User Name is $name and He is $age years Old";
});

এখন আপনার ব্রাউজারে, আপনি নিচের মতো করে user name এবং তার age এ access করতে পারেন।


http://localhost:8000/users

Multiple Optional Route Paramter

Regular Expression Constraints

এই পদ্ধতিতে route parameter গুলোকে where method ব্যবহার করে একটা নির্দিষ্ট ফরম্যাট এ ফিক্সড বা সীমাবদ্ধ করে দিতে পারেন। আর where method টি route এর জন্য শুধু মাত্র regular expression দিয়ে সঙ্গায়িত প্যারামিটার গুলো গ্রহণ করতে বাধ্য করবে।

Route::get('/user/{name}', function ($name) {
    return "Name: ".$name;
})->where('name', '[A-Za-z]+');  //accept only alphabetical value


Route::get('/user/{id}', function ($id) {
    return "Id: ".$id;  
})->where('id', '[0-9]+');  //accept only numerical value


Route::get('/user/{id}/{name}', function ($id, $name) {
    return "Id: $id and Name: $name";
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']); //Accept both Alphabetical and Numerical Value
Route accept only Alphabetical value

Route accept only Alphabetical value

Route accept only Numerical value

Route accept only Numerical value

Route accept both Numerical and alphabetical value

Route accept both Numerical and alphabetical value

তবে আপনি চাইলে Regex Pattern ব্যবহারের পরিবর্তে লারাভেলের বিদ্যমান ফাঙ্কশন গুলোও ব্যবহার করতে পারেন।

Route::get('/user/{id}/{name}', function ($id, $name) {
    return "Welcome $name, Your Id is: $id";
})->whereNumber('id')->whereAlpha('name');

Route::get('/user/{name}', function ($name) {
    return "Welcome $name";
})->whereAlphaNumeric('name');

Route::get('/user/{id}', function ($id) {
    return "Welcome , Your Id is: $id";
})->whereUuid('id');

Global Constraints

এই পদ্ধতিতে আপনি একটা নির্দিষ্ট route parameter কে সবসময় একটা নির্দিষ্ট ফরমেট এ রিটার্ন করতে পারেন। এর জন্যে আপনাকে App\Providers\RouteServiceProvider class: এর boot Method এ pattern মেথড ব্যবহার করতে পারেন।

/**
 * Define your route model bindings, pattern filters, etc.
 *
 * @return void
 */
public function boot()
{
    Route::pattern('id', '[0-9]+');
}

প্যাটার্নটি যখন নির্দিষ্ট করে দিবেন, এটি স্বয়ংক্রিয়ভাবে সেই প্যারামিটার নাম ব্যবহার করে সব route এ প্রয়োগ হবে :

Route::get('/user/{id}', function ($id) {
    // Only executed if {id} is numeric...
});

Encoded Forward Slashes

একটা বিষয় লক্ষ্য করে দেখবেন , Laravel routing component গুলো প্যারামিটার এ সব ধরণের ক্যারেক্টার একসেপ্ট করে , শুধু মাত্র forwarding slash (/) ছাড়া। কারণ এই ক্যারেক্টার (/) টি প্যারামিটার গুলো আলাদা করার জন্য ব্যবহৃত হয়। তবে আপনি চাইলে এটিকেও where condition এর মাধ্যমে এলাও করতে পারেন। তবে মনে রাখতে হবে এই কাজটি শুধু সর্বশেষ প্যারামিটার এর জন্য ব্যবহার করা যায়। নিচের উদাহরণ দেখুন।

Route::get('/search/{search}', function ($search) {
    return $search;
})->where('search', '.*');
Encoded Forward Slashes example

Encoded Forward Slashes example

Named Routes

Laravel এর Named route ফীচার দিয়ে আপনি যেকোনো ছোট অথবা বড় URL কে একটা নির্দিষ নাম দিতে পারেন। এবং পরবর্তীতে route redirects সহ বহু কাজে ব্যবহার করতে পারেন। আপনি name method chaining করে একটি route এর জন্য একটি name নির্ধারণ করতে পারেন:

Route::get('/user/profile', function () {
    //
})->name('profile');

আপনি চাইলে controller actions এর জন্য নিচের মতো করে route name গুলি নির্দিষ্ট করতে পারেন:

Route::get(
    '/user/profile',
    [UserProfileController::class, 'show']
)->name('profile');

Generating URLs To Named Routes

ধরুন আপনি একটি route লিখলেন , এবং সেটি পরবর্তীতে page redirect সহ অন্য অনেক কাজে ব্যবহার করতে চান , তাহলে আপনার জন্য সবচেয়ে সুবিধা হয় , যদি route টি কে আলাদা ভ্যারিয়েবল এ সংরক্ষণ না রেখে , এটিকে ডিক্লেয়ার এর সময় একটা Name দিয়ে দেওয়া। ব্যাপারটা অনেকটা এই রকম:

// Generating URLs...
$url = route('profile');

// Generating Redirects...
return redirect()->route('profile');

আর উপরোক্ত কাজটি করতে হলে , আপনাকে নিচের মতো করে route ডিক্লেয়ার করতে হবে:

Route::get('/profile/test', function () {
    return route("profile");
})->name('profile');
name route example

laravel name route example

তবে আপনি চাইলে নিচের মতো করে অতিরিক্ত প্যারামিটার ও পাঠাতে পারেন।

Route::get('/profile/test', function () {
    return route("profile",['id' => 1, 'photos' => 'yes']);
})->name('profile');
laravel name route with parameter example

laravel name route with parameter example

এমনকি আপনি চাইলে view file সহ সমগ্র লারাভেলের যেকোনো জায়গায় এই Named Route ব্যবহার করতে পারেন :

<!-- named.blade.php -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Laravel Named Route</title>
</head>
<body>
   Hello {{route('profile')}} 
</body>
</html>
//Route Defination
Route::get('/profile/test', function () {
    return view('named');
})->name('profile');
laravel named route example

laravel named route example

Laravel Mastering Course

Route Groups

ধরুন আপনি একটা customer CRUD এর কাজ করবেন , সেক্ষেত্রে আপনি চাইলে create, read, update এবং delete এর কাজ গুলোকে পৃথক পৃথক route এ declare না করে একটা গ্রুপের মধ্যে কল করতে পারবেন। নিচের উদাহরণ টি দেখুন:

Route::group([], function(){  
   Route::get('/create',function(){  
   echo "First route for Create/Insert";
   });  
   Route::get('/read',function(){  
   echo "Second route for Read";  
   });  
   Route::get('/update/{id}',function($id){  
   echo "Third route for Update";  
   });
   Route::get('/delete/{id}',function($id){  
    echo "Fourth route for Delete";  
    });  
});     

আর এই কাজটি Controller দিয়ে করতে হলে আপনার কোড টি হবে নিম্নরুপঃ

use App\Http\Controllers\UserController;

 Route::group([], function(){  
    Route::get('/create',[UserController::class, 'create']);  
    Route::get('/read',[UserController::class, 'read']);  
    Route::get('/update/{id}',[UserController::class, 'update']);
    Route::get('/delete/{id}',[UserController::class, 'delete']);  
 });
create example in route group

create example in route group

read example in route group

read example in route group

update example in route group

update example in route group

delete example in route group

delete example in route group

তবে আপনি চাইলে group এ prefex ও যুক্ত করতে পারেন। নিচের উদাহরণ টি দেখুন:

Route::group(["prefix"=>"/user"], function(){  
   Route::get('/create',function(){  
   echo "First route for Create/Insert";
   });  
   Route::get('/read',function(){  
   echo "Second route for Read";  
   });  
   Route::get('/update/{id}',function($id){  
   echo "Third route for Update";  
   });
   Route::get('/delete/{id}',function($id){  
    echo "Fourth route for Delete";  
    });  
}); 

আর এই কাজটি Controller দিয়ে করতে হলে আপনার কোড টি হবে নিম্নরুপঃ

use App\Http\Controllers\UserController;

 Route::group(["prefix"=>"/user"], function(){  
    Route::get('/create',[UserController::class, 'create']);  
    Route::get('/read',[UserController::class, 'read']);  
    Route::get('/update/{id}',[UserController::class, 'update']);
    Route::get('/delete/{id}',[UserController::class, 'delete']);  
 });

এখন আপনার url গুলো নিচের মতো হবে:

http://localhost:8000/user/create
http://localhost:8000/user/read
http://localhost:8000/user/update/2
http://localhost:8000/user/delete/2

Route Prefixes

উপরে আপনি নিশ্চয়ই লক্ষ্য করেছেন , আমরা প্রয়োজন হলে Route Group এর মধ্যে prefix যুক্ত করতে পারি , তবে আপনি চাইলে Route::prefix এই মেথডের মাধমেও prefix যুক্ত করতে পারেন। নিচের উদাহরণ লক্ষ্য করুন :

Route::prefix('user')->group(function () {
    Route::get('/create',function(){  
    echo "First route for Create/Insert!";
    });  
    Route::get('/read',function(){  
    echo "Second route for Read";  
    });  
    Route::get('/update/{id}',function($id){  
    echo "Third route for Update";  
    });
    Route::get('/delete/{id}',function($id){  
    echo "Fourth route for Delete";  
    });  
});

আর এই কাজটি Controller দিয়ে করতে হলে আপনার কোড টি হবে নিম্নরুপঃ

 Route::prefix('user')->group(function () {
    Route::get('/create',[UserController::class, 'create']);  
    Route::get('/read',[UserController::class, 'read']);  
    Route::get('/update/{id}',[UserController::class, 'update']);
    Route::get('/delete/{id}',[UserController::class, 'delete']);  
});

এখন আপনার url গুলো নিচের মতো হবে:

http://localhost:8000/user/create
http://localhost:8000/user/read
http://localhost:8000/user/update/2
http://localhost:8000/user/delete/2

Laravel Mastering Course

Route Group Controller

আপনার যদি একই controller এর অধীনে একাধিক route url থাকে তাহলে আপনি প্রত্যেকটি route এর জন্য একই controller বার বার call করার পরিবর্তে Route Group Controller পদ্ধতি ব্যবহার করতে পারেন। তখন Route Group Controller টি হবে নিম্নরূপ :

use App\Http\Controllers\UserController;
Route::prefix('user')
    ->name('user.')
    ->controller(UserController::class)
    ->group(function () {
        Route::get('/create','create')->name('create');  
        Route::get('/read','read')->name('read'); 
        Route::get('/update/{id}','update')->name('update');
        Route::get('/delete/{id}','delete')->name('delete'); 
});

এখন আপনার url গুলো নিচের মতো হবে:

http://localhost:8000/user/create
http://localhost:8000/user/read
http://localhost:8000/user/update/2
http://localhost:8000/user/delete/2

Note: তবে এই সুবিধাটি শুধু মাত্র লারাভেল ৮.৮০.০ ভার্সন থেকে কাজ করবে।

Route Name Prefixes

আপনি যদি group route এর মধ্যে প্রত্যেকটি route কে একটি করে নাম দিতে চান , তাহলে আপনি এই সুবিধা গ্রহণ করতে পারেন , তবে এই ক্ষেত্রে আপনাকে group route নামের পর একটা “.” দিতে হবে। নিচের উদাহরণ দেখুন :

Route::name('admin.')->group(function () {
    Route::get('/create',function(){ 
        echo Route::currentRouteName();
    })->name('create');  
    Route::get('/read',function(){  
        echo Route::currentRouteName();
    })->name('read'); 
    Route::get('/update/{id}',function($id){  
        echo Route::currentRouteName()."/".$id; 
    })->name('update');
    Route::get('/delete/{id}',function($id){  
        echo Route::currentRouteName()."/".$id;  
    })->name('delete'); 
});

আর এই কাজটি Controller দিয়ে করতে হলে আপনার কোড টি হবে নিম্নরুপঃ

Route::name('user.')->group(function () {
    Route::get('/create',[UserController::class, 'create'])->name('create');  
    Route::get('/read',[UserController::class, 'read'])->name('read'); 
    Route::get('/update/{id}',[UserController::class, 'update'])->name('update');
    Route::get('/delete/{id}',[UserController::class, 'delete'])->name('delete'); 
});

এখন আপনার url গুলো নিচের মতো হবে:

http://localhost:8000/create
http://localhost:8000/read
http://localhost:8000/update/2
http://localhost:8000/delete/2

Multiple Middleware in Route Group

আপনি যদি একটি group route এর মধ্যে প্রত্যেকটি route কে ভিন্ন ভিন্ন middleware চেক করার পর রান করতে চান, তাহলে আপনাকে এই পদ্ধতি ব্যবহার করতে হবে। চলুন প্রথমে দেখা যাক এই পদ্ধতিতে , আপনার route দেখতে কেমন হবে :

Route::middleware(['first', 'second'])->group(function () {
    Route::get('/profile', function () {
        return "Checked By First Middleware";
    });

    Route::get('/user/profile', function () {
        return "Checked By Second Middleware";
    });
});

এইবার নিম্নোক্ত দুটি কমান্ড ব্যবহার করে দুটি middleware তৈরী করে ফেলুন :

php artisan make:middleware first
php artisan make:middleware second

এবার উক্ত middleware দুটিকে Kernel.php তে রেজিস্টার করে আসুন।

protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'first' => \App\Http\Middleware\first::class,
        'second' => \App\Http\Middleware\second::class,
    ];

এবার আপনার route ফাইলে সবার উপরে নিম্নোক্ত দুটি middleware যুক্ত করে দিন।

use App\Http\Middleware\first;
use App\Http\Middleware\second;

এখন আপনি যথাক্রমে http://localhost:8000/profile এবং http://localhost:8000/user/profile

Middleware in Route Group

Middleware in Route Group

Multiple Middleware in Route Group

Multiple Middleware in Route Group

এতক্ষন আমরা দেখলাম কিভাবে একটা route group এর মধ্যে একাধিক middleware রান করে হয়। এবার চলুন উক্ত first এবং second middleware থেকে আমাদের profile এবং user/profile route এর জন্য কিছু data যুক্ত করা যাক।

প্রথমে আমাদের তৈরি first Middleware কে নিচের মতো করে পরিবর্তন করে নিন।

public function handle(Request $request, Closure $next)
    {
        $request->request->add(["name"=>"Masud Alam"]);
        return $next($request);
    }

এবার আমাদের তৈরি second Middleware কে নিচের মতো করে পরিবর্তন করে নিন।

  public function handle(Request $request, Closure $next)
    {
        $request->request->add(["user"=>"Sohel Alam"]);
        return $next($request);
    }

এবার আমাদের তৈরি route কে নিচের মতো করে পরিবর্তন করে নিন।

Route::middleware(['first', 'second'])->group(function () {
    Route::get('/profile', function (Request $request) {
        return "Welcome ".$request->name."!";
    });

    Route::get('/user/profile', function (Request $request) {
        return "Welcome ".$request->user."!";
    });
});

এখন আপনি যথাক্রমে http://localhost:8000/profile এবং http://localhost:8000/user/profile

add data from laravel Middleware

add data from laravel Middleware

add extra data from laravel middleware

add extra data from laravel middleware

Larave Route এর মাধ্যমে MySQL Database Table থেকে Data Fetch করা :

Laravel Database table থেকে Data fetch করতে হলে আপনাকে প্রথমে Database এর host এর সাথে connect এবং Database Select করতে হবে। আর এর জন্য আপনাকে আপনার project এর root ফোল্ডারের .env ফাইল এ Database এর host, username, password এবং Database name বলে দিতে হবে। নিচের ছবিটি লক্ষ্য করুন :

Laravel Database Connection in .env file-

Note: .env file edit করার পর অবশ্যই php artisan সার্ভার টি রিস্টার্ট দিতে হবে। অথবা “php artisan config:clear” এই command টি run করতে হবে।

এবার নিম্নের কোডটি routes/web.php তে লিখুন :

Route::get('/getall', function()
{
$fetchData = DB::select('select * from students');
echo "<pre>";
print_r($fetchData);
echo "</pre>";
});

এখন আপনি আপনার ব্রাউজার এর Address bar এ http://localhost:8000/getall লিখে hit করুন , তাহলে আপনার route ঠিক নিম্নের screenshot এর মতো রেজাল্ট দেখাবে:

get all data from database using route and env file

Laravel Mastering Course

Route Model Binding

যখন একটি model ID যেকোনো route বা controller এ ব্যবহার করা হয়, তখন প্রত্যেকবার আপনাকে সেই model ID সংশ্লিষ্ট model টি call করতে হয়। আর এই কাজটি একজন ডেভেলপারের জন্য অবশ্যই বিরক্তিকর বিষয়। আপনি যেই মডেলের আইডি ব্যবহার করবেন, যেন সেই মডেল টি অটোমেটিক্যালি route বা controller এ লোড হয়ে যায়, তা আপনি Laravel route model binding ফীচার এর মাধ্যমে খুব সহজেই করতে পারেন। আর এই কাজটি আপনি দুইভাবে করতে পারেন :

  1. Implicit Binding
  2. Explicit Binding

Implicit Binding

এই পদ্ধতিতে ,যখন কোনো route বা controller এ যেকোনো function এর মধ্যে অবস্থিত type-hinted variable এর নামের সাথে route বা controller এ ব্যবহার করা মডেলের নাম একই হয় , তখন লারাভেল স্বয়ংক্রিয় ভাবে উক্ত মডেলটি লোড করে নেয়। নিচের উদাহরণটি দেখুন :

use App\Models\User;

Route::get('/users/{user}', function (User $user) {
    return $user->name."<br>".$user->email;
});

উল্লেখ্য Implicit Binding এ route বা controller এ অবস্থিত function এ Typed Hint Parameter variable এর নাম এবং route এর URL variable এর নাম একই হতে হয়। তা না হলে আপনি কোনো রেজাল্ট পাবেন না।

আর এই কাজটি Controller দিয়ে করতে হলে আপনার কোড টি হবে নিম্নরুপঃ

// Route definition...
use App\Http\Controllers\UserController;


Route::get('/users/{user}', [UserController::class, 'show']);
// Controller method definition...
public function show(User $user)
{
    return $user->name."<br>".$user->email;
}
Laravel Implicit Binding

Laravel Implicit Binding in Route

Note:

controller এর প্রাকটিস টি করার পূর্বে , UserController Class শুরুর পূর্বে এই use App\Models\User; লাইনটি যুক্ত আছে কিনা তা নিশ্চিত হয়ে নিবেন।

এক্ষেত্রে আপনি যদি উক্ত মডেলের ডাটা কোনো view ফাইলে পাঠাতে চান , তাহলে আপনার কোডটি হবে নিম্নরুপঃ

শুধু route এর মাধ্যমে view তে পাঠাতে কোডঃ


// Route definition...
use App\Models\User;

Route::get('/users/{user}', function (User $user) {
   return view('user.profile', ['user' => $user]);
});

আর এই কাজটি Controller দিয়ে করতে হলে আপনার কোড টি হবে নিম্নরুপঃ

// Route definition...
use App\Http\Controllers\UserController;


Route::get('/users/{user}', [UserController::class, 'show']);
// Controller method definition...
public function show(User $user)
{
    return view('user.profile', ['user' => $user]);
}

এই ক্ষেত্রে আপনার resources/view/user/profile.blade.php ফাইলের কোড হবে নিম্নরূপ:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Route Model Implicit Binding</title>
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    </head>
    <body>
       <div>
        <h4>Welcome {{$user['name']}}!</h4>
        <p>Your Email is: {{$user['email']}}!</p>
       </div>
    </body>
</html>

Soft Deleted Models in Laravel Route

সাধারণতঃ implicit model binding পদ্ধতিতে আপনি লারাভেলের সফ্ট ডিলিট ডাটা কে সরাসরি retrieve করতে পারবেন না। তবে আপনি এই কাজটি withTrashed ফাঙ্কশন ব্যবহার করে করতে পারেন। তখন আপনার কোডটি হবে নিম্নরুপঃ

use App\Models\User;

Route::get('/users/{user}', function (User $user) {
    return $user->email;
})->withTrashed();

Customizing The Key in Laravel Route

আপনার অনেক সময় Eloquent model কে Id এর পরিবর্তে অন্য যেকোনো কলাম দিয়েও কল করতে ইচ্ছে বা দরকার হতে পারে। আর এই কাজটি করতে হলে আপনাকে route parameter definition এ Database table এর column কে নির্দিষ্ট করে দিতে হবে। কোডটি হবে নিম্নরুপঃ

use App\Models\User;

Route::get('/users/{user:email}', function (User $user) {
    return $user->name."<br>".$user->email;
});

এখন আপনার url টি হবে নিম্নরুপঃ

Customizing The Key in laravel implicit binding

Customizing The Key in laravel implicit binding

তবে আপনি চাইলে আপনার User Model ক্লাসে getRouteKeyName ফাঙ্কশন দিয়ে নতুন ডিফল্ট কলামের নাম বলে দিতে পারেন । কোডটি হবে নিম্নরুপঃ

/**
 * Get the route key for the model.
 *
 * @return string
 */
public function getRouteKeyName()
{
    return 'email';
}

আর তখন আপনাকে আপনার route parameter definition এ Database table এর column কে আলাদাভাবে নির্দিষ্ট করে দিতে হবেনা।

use App\Models\User;

Route::get('/users/{user}', function (User $user) {
    return $user->name."<br>".$user->email;
});
Customizing The Key using getRouteKeyName

Customizing The Key using getRouteKeyName

Laravel Mastering Course

Custom Keys & Scoping in Laravel Route

একটি route এ যখন একাধিক Eloquent model কে implicitly binding বা পরোক্ষভাবে আবদ্ধ করার সময়, আপনি দ্বিতীয় Eloquent model কে এমনভাবে স্কোপ করতে চাইতে পারেন যে এটি অবশ্যই তার পূর্ববর্তী Eloquent model এর একটি child হতে হবে। উদাহরণস্বরূপ, এই route definition টি লক্ষ্য করুন যা একটি নির্দিষ্ট ইউজারের জন্য id দ্বারা একটি ব্লগ পোস্ট খুঁজে বের করবে।

তবে এই কাজটি করার জন্য আপনাকে প্রথমে User Model এবং Post Model এর মধ্যে নিম্নোক্ত উপায়ে রিলেশন করে দিতে হবে।

User.php

 public function posts()
    {
        return $this->hasMany(Post::class);
    }

Post.php

   public function user(){
        return $this->belongsTo(User::class);
    }

web.php

use App\Models\Post;
use App\Models\User;

Route::get('/users/{user}/posts/{post:id}', function (User $user, Post $post) {
    dd($post);
});
Laravel Custom Keys & Scoping example

Laravel Custom Keys & Scoping example

একটি nested route এ প্যারামিটার হিসাবে যখন একটি custom keyed implicit binding ব্যবহার করার সময়, লারাভেল স্বয়ংক্রিয়ভাবে প্যারেন্টের সাথে relationship বের করার conventions গুলি ব্যবহার করে এবং তার প্যারেন্টস দ্বারা নেস্টেড মডেলটি খুঁজে বের করার জন্য ক্যোয়ারী স্কোপ করবে৷ এই ক্ষেত্রে, এটি ধরে নেওয়া হবে যে User মডেলের Post নামে একটি relationship রয়েছে ,যা Post মডেল খুঁজে বের করতে ব্যবহার করা যেতে পারে।

তবে আপনি যদি চান, আপনি লারাভেলকে নির্দেশ দিতে পারেন “child” বাইন্ডিং করার জন্য এমনকি যদি একটি custom key প্রদান করা না হয়। এটি করার জন্য, আপনি আপনার route সংজ্ঞায়িত করার সময় scopeBindings পদ্ধতি ব্যবহার করতে পারেন:

use App\Models\Post;
use App\Models\User;
 
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
    dd($post);
})->scopeBindings();
laravel custom keys and scoping

laravel custom keys and scoping

অথবা, আপনি চাইলে scoped bindings ব্যবহার করার জন্য route definition গুলো একটি সম্পূর্ণ Group এর মধ্যে লিখতে পারেন:

Route::scopeBindings()->group(function () {
    Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
        return $post;
    });
});

এক্ষেত্রে আপনার Model ক্লাসে getRouteKeyName ফাঙ্কশন দিয়ে নতুন ডিফল্ট কলামের নাম বলে দিতে ভুলবেন না ।


/**
 * Get the route key for the model.
 *
 * @return string
 */
public function getRouteKeyName()
{
    return 'email';
}

Customizing Missing Model Behavior in Laravel Route

সাধারণত, যদি কোনো কারণে লারাভেলে কোনো implicitly bound model পাওয়া না যায়, লারাভেল তখন বাইডিফল্ট একটি 404 HTTP response তৈরি করে। তবে আপনি চাইলে, আপনার route কে ডিফাইন করার সময় লারাভেলের missing method কল করে এটি কাস্টমাইজ করতে পারেন। মূলতঃ যখনি কোনো কারণে implicitly bound model পাওয়া না যায়, তখন missing method টি প্রথমে একটি closure কে কল করবে। নিচের উদাহরণটি দেখুন :

use App\Models\User;
use Illuminate\Support\Facades\Redirect;

Route::get('/users/{user}', function (User $user) {
    return $user->name."<br>".$user->email;
})->missing(fn()=>response()->view('404'));

আর যদি এই কাজটি আপনি কন্ট্রোলারের মাধ্যমে করতে চান , তখন আপনার route টি হবে নিম্নরুপঃ

use App\Models\User;
use Illuminate\Support\Facades\Redirect;
use App\Http\Controllers\UserController;

     Route::get('/users/{user}', [UserController::class, 'show'])
     ->name('user.view')
      ->missing(function (Request $request) {
         return response()->view('404');
    });

আপনার কাস্টম resources/views/404.blade.php ফাইলের কোড হবে নিম্নরুপঃ

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>404</title>
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    </head>
    <body>
       <div class="vh-100 d-flex justify-content-center align-items-center">
        <h4>It seems we can’t find what you’re looking for.</h4>
       </div>
    </body>
</html>

Customizing Missing Model Behavior

Customizing Missing Model Behavior

Implicit Route Bindings With Enums in Laravel Route

আপনি এখন আপনার লারাভেল route এ PHP 8.1 এর enum TypeHint সুবিধা যুক্ত করতে পারেন। Laravel তারপর শুধুমাত্র route টি ব্যবহার করবে যদি route এর URI তে একটি ভ্যালিড enum থাকে। আর যদি enum না পাওয়া যায় তাহলে একটি 404 ফেরত রিটার্ন করবে।

চলুন প্রথমে app/Enums ফোল্ডারে Category.php নামে একটা Enum তৈরি করা যাক।

<?php
namespace App\Enums;

enum Category: string{
    case Fruits = 'fruits';
    case People = 'people';
}

এবার আমরা route এ নিম্নোক্ত কোডটি লিখব:

use App\Enums\Category;
 
Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});

এখন আমরা যদি দুটি enum যথাক্রমে fruites এবং people এর মধ্যে যেকোনো একটি দেই , তুমি তাহলে লারাভেল রুট আপনাকে আউটপুট রিটার্ন করবে।
অন্যথায় 404 output রিটার্ন করবে।

Laravel Enum Route

Laravel Enum Route

Explicit Binding in Laravel Route

এটা অনেকটা Implicit Model Binding এর মতোই ,শুধু পার্থক্য হচ্ছে এই পদ্ধতিতে আপনি route বা controller function এ Model Class কে Typed Hint করা লাগবেনা। তবে Parameter Variable টির নাম অবশ্যই মডেলের নামের সাথে মিল থাকতে হবে। এবং app/Providers/ ফোল্ডারের মধ্যে অবস্থিত RouteServiceProvider ফাইলে boot মেথডে আপনার মডেল টিকে রেজিস্ট্রেশন করে রাখতে হবে।

তো চলুন প্রথমে RouteServiceProvider ফাইলে boot মেথডে আমাদের User Model টি রেজিস্টার করে রাখি।

use App\Models\User;
use Illuminate\Support\Facades\Route;
 
/**
 * Define your route model bindings, pattern filters, etc.
 *
 * @return void
 */
public function boot()
{
    Route::model('user', User::class);
 
    // ...
}

এখন আপনি আপনার route ফাইলে Model class Typed Hint ছাড়াই Route Model Binding করতে পারবেন।

Route::get('/users/{user}', function ($user) {
    return $user->name."<br>".$user->email;
});
Laravel-Explicit Binding

Laravel-Explicit Binding

Laravel Mastering Course

Customizing The Resolution Logic in Laravel Route

Explicit Binding এ ডাটাবেস টেবিল এর আপনার পছন্দ মতো কোনো নির্দিষ্ট কলাম এর বিপরীতে ডাটা fetch করতে চান। তাহলে আপনি আপনার নিজস্ব model binding resolution logic ব্যবহার করতে পারেন। এবং এর জন্য Route::bind method ব্যবহার করতে পারেন। এতে আপনি bind method এ যে ক্লোজারটি পাস করবেন সেটি URI সেগমেন্টের value পাবে এবং রুটে ইনজেকশন দেওয়া ক্লাসের instance ফেরত দেবে। আর , এই কাজটি আপনি আপনার অ্যাপ্লিকেশনের RouteServiceProvider-এর Boot Method এ লিখতে হবে:

use App\Models\Customers;
use Illuminate\Support\Facades\Route;
 
/**
 * Define your route model bindings, pattern filters, etc.
 *
 * @return void
 */
public function boot()
{
    Route::bind('customers', function ($value) {
        return Customers::where('phone', $value)->firstOrFail();
    });
 
    // ...
}

আপনার route টি হবে নিম্নরূপ :

Route::get('/getinfo/{customers}',function($customers){
    dd($customers);
});

এখন আপনি আপনার কাস্টমারের তথ্য তার Id এর পরিবর্তে phone নম্বর দিয়ে fetch করতে পারবেন।

Customizing Resolution Login in Laravel Explicit Binding

Customizing Resolution Login in Laravel Explicit Binding

2 comments to “Laravel Framework Basics পর্ব-৩: Laravel Routes”
  1. Route::get(‘/’, function (){
    echo “This is Home Page”; //here ” was missing above
    });
    Route::get(‘/about’, function (){
    echo ” This is About Page”;
    });
    Route::get(‘/contact’, function (){
    echo ” This is Contact Page”;
    });

Leave a Reply