DEV Community

Ruhul Amin Sujon
Ruhul Amin Sujon

Posted on

Laravel IQ - Level 1 - Part 6

প্রশ্ন ১ ঃ laravel এ access token & refresh token এর পার্থক্য কি?

কখন কোথায় কোনটা বেশি ব্যবহার হয়? কিভাবে ইম্পলিমেন্ট করবো?
route এ access token ব্যবহার করবো, নাকি refresh token ব্যবহার করবো?

Answer:

Laravel-এ Access Token আর Refresh Token—দুটোর role আলাদা। ঠিকভাবে ব্যবহার করলে security + UX দুটোই ভালো হয়।


🔐 1️⃣ Access Token কী?

👉 ছোট সময়ের জন্য valid token
👉 API access করার জন্য ব্যবহার হয়

বৈশিষ্ট্য:

  • ⏱️ Short lifetime (যেমন: 15 min / 1 hour)
  • 🔑 প্রতিটা protected route-এ লাগে
  • ⚡ Fast validation

🔄 2️⃣ Refresh Token কী?

👉 নতুন access token generate করার জন্য ব্যবহার হয়

বৈশিষ্ট্য:

  • ⏱️ Long lifetime (যেমন: 7 দিন / 30 দিন)
  • 🔒 বেশি secure ভাবে store করতে হয়
  • ❌ Direct API access-এ ব্যবহার করা হয় না
  • 🔍 Access vs Refresh Token (পার্থক্য)

🔍 Access vs Refresh Token (পার্থক্য)

বিষয় Access Token Refresh Token
কাজ API access নতুন token generate
Lifetime কম বেশি
Security risk বেশি (frequent use) কম (rare use)
কোথায় ব্যবহার Route/API call Auth endpoint
Expire হলে fail নতুন access token দেয়

🎯 3️⃣ কখন কোনটা ব্যবহার করবেন?
Access Token ব্যবহার:

  • সব protected API route
  • যেমন:
  • /api/user
  • /api/orders
  • /api/profile
Authorization: Bearer access_token
Enter fullscreen mode Exit fullscreen mode

Refresh Token ব্যবহার:

  • শুধু token renew করার সময়
POST /api/refresh-token
Enter fullscreen mode Exit fullscreen mode

গুরুত্বপূর্ণ প্রশ্ন:
👉 Route-এ কোনটা ব্যবহার করবো?

👉 শুধু Access Token
👉 Refresh Token কখনো route protect করতে ব্যবহার করা যাবে না


⚙️ 4️⃣ Laravel-এ Implementation (Simple Flow)

Laravel-এ তুমি use করতে পারো:

  • Laravel Sanctum (simple API)
  • Laravel Passport (OAuth2 full system)

🔥 Basic Flow
1️⃣ Login

$token = $user->createToken('api')->plainTextToken;
Enter fullscreen mode Exit fullscreen mode

👉 Access token return


2️⃣ API Route Protect

Route::middleware('auth:sanctum')->get('/profile', function () {
    return auth()->user();
});
Enter fullscreen mode Exit fullscreen mode

🔄 Refresh Token Flow (Custom Implementation)

Sanctum defaultভাবে refresh token দেয় না
তাই manually করতে হয় 👇


Step 1: Refresh Token Table

refresh_tokens:
- id
- user_id
- token (hashed)
- expires_at
Enter fullscreen mode Exit fullscreen mode

Step 2: Login Response

{
  "access_token": "...",
  "refresh_token": "..."
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Refresh API

Route::post('/refresh-token', function (Request $request) {
    // validate refresh token
    // issue new access token
});
Enter fullscreen mode Exit fullscreen mode

🔐 5️⃣ Security Best Practices

✔ Access token short রাখো
✔ Refresh token DB-তে store করো (hashed)
✔ Refresh token revoke করতে পারো
✔ HTTPS ব্যবহার করো
✔ Token rotation ব্যবহার করো


🧠 Interview-ready Answer

Access tokens are short-lived tokens used to authenticate API requests, while refresh tokens are long-lived tokens used to generate new access tokens. In Laravel, access tokens are used in route authentication, and refresh tokens are only used in token renewal endpoints. Refresh tokens should never be used to access protected APIs.


🏁 Final Summary

👉 Access Token = API access
👉 Refresh Token = Token renew
👉 Route-এ সবসময় Access Token


প্রশ্ন ২ ঃ laravel এ generator কি? কেন ব্যবহার করা হয়? কোন প্রবলেম টা সলভ করে? chunk vs generator?

Answer:

Laravel/ PHP-এ Generator বোঝা মানে তুমি memory-efficient data processing বুঝে গেছো — এটা interview-এ strong point।


🔹 1️⃣ Generator কী?

👉 Generator হলো এমন function যা একবারে সব data return না করে, ধাপে ধাপে (lazy way) data produce করে।

এটা yield keyword দিয়ে কাজ করে।


📌 Basic Example:

function numbers() {
    yield 1;
    yield 2;
    yield 3;
}

foreach (numbers() as $num) {
    echo $num;
}
Enter fullscreen mode Exit fullscreen mode

👉 এখানে:

  • সব data একসাথে memory-তে load হয় না
  • একটার পর একটা আসে

🧠 2️⃣ কেন Generator ব্যবহার করা হয়?

👉 মূল কারণ: Memory optimization + large data handling

Problem:

$users = User::all(); // 1 million rows 😱
Enter fullscreen mode Exit fullscreen mode

❌ সব data RAM-এ লোড হয়
❌ Memory crash হতে পারে


Solution (Generator):

function getUsers() {
    foreach (User::cursor() as $user) {
        yield $user;
    }
}
Enter fullscreen mode Exit fullscreen mode

✔ একবারে ১টা row memory-তে
✔ Huge data handle করা যায়


🔥 3️⃣ Generator কোন problem solve করে?

Problem Solution
Large dataset memory issue Lazy loading
High RAM usage Reduce memory
Streaming data Real-time process
Long loop processing Efficient iteration

⚡ 4️⃣ Laravel-এ Generator কোথায় use হয়?

Laravel internally use করে:

User::cursor()
Enter fullscreen mode Exit fullscreen mode

👉 এটা generator ব্যবহার করে


Example:

foreach (User::cursor() as $user) {
    // process
}
Enter fullscreen mode Exit fullscreen mode

✔ Memory efficient
✔ Large data safe


🔍 5️⃣ chunk vs generator (VERY IMPORTANT)

বিষয় chunk() generator (cursor)
Memory Medium Very Low
Data load batch (100/1000) one by one
Use case bulk processing huge streaming
Speed faster একটু slow
Control batch-based continuous

🔹 chunk() Example:

User::chunk(1000, function ($users) {
    foreach ($users as $user) {
        // process
    }
});
Enter fullscreen mode Exit fullscreen mode

👉 একবারে 1000 row memory-তে


🔹 cursor() Example:

foreach (User::cursor() as $user) {
    // process
}
Enter fullscreen mode Exit fullscreen mode

👉 একবারে ১টা row


🎯 কখন কোনটা ব্যবহার করবেন?
chunk() ব্যবহার:

  • Batch processing (email send, update)
  • Speed important
    generator / cursor ব্যবহার:

  • 1M+ data

  • Memory critical

  • Streaming process


🧠 Interview-ready Answer

A generator in PHP is a function that uses the yield keyword to return data lazily, one item at a time, instead of loading everything into memory. It solves memory issues when working with large datasets. In Laravel, cursor() uses generators, while chunk() processes data in batches. Generators are more memory efficient, while chunk is faster for batch operations.


🔥 Pro Insight (Impress Interviewer)

👉 তুমি বলতে পারো:

  • Generator uses lazy evaluation
  • Memory stays constant O(1)
  • cursor() internally uses PDO cursor
  • Best for large dataset streaming

প্রশ্ন ৩ ঃ laravel Model এ boot function কেন ব্যবহার করা হয়? কোন প্রবলেম টা সলভ করে? কোন সিচুয়েশনে ব্যবহার করবো?

Answer:

Laravel Model-এর boot() (এবং modern Laravel-এ booted()) হলো এমন জায়গা, যেখানে তুমি model-level global behavior একবারে define করতে পারো—যেমন events (creating/updating), global scopes, automatic field সেট করা ইত্যাদি।


🔹 1️⃣ boot() কী?

👉 Model class load হওয়ার সময় একবার run হয়
👉 এখানে তুমি model-এর events + global rules সেট করতে পারো

class Post extends Model
{
    protected static function boot()
    {
        parent::boot();

        static::creating(function ($post) {
            $post->slug = strtolower(str_replace(' ', '-', $post->title));
        });
    }
}
Enter fullscreen mode Exit fullscreen mode

✔ নতুন post create হলে auto slug generate হবে


🧠 2️⃣ কেন ব্যবহার করা হয়? (Problem it solves)
🎯 Problem:

তুমি যদি controller-এ বারবার এই logic লেখো:

$post->slug = ...
Enter fullscreen mode Exit fullscreen mode

❌ Code duplicate
❌ ভুলে গেলে bug
❌ Central control নেই


Solution (boot):

👉 এক জায়গায় define করো
👉 সব জায়গায় automatically apply হবে

✔ DRY (Don’t Repeat Yourself)
✔ Clean architecture
✔ Consistency


🔥 3️⃣ Common Use Cases
1. Auto Field Set করা (Very common)

static::creating(function ($model) {
    $model->user_id = auth()->id();
});
Enter fullscreen mode Exit fullscreen mode

2. Slug generate

static::saving(function ($model) {
    $model->slug = Str::slug($model->title);
});
Enter fullscreen mode Exit fullscreen mode

3. Soft restriction / validation

static::deleting(function ($model) {
    if ($model->orders()->count() > 0) {
        throw new Exception("Cannot delete");
    }
});
Enter fullscreen mode Exit fullscreen mode

4. Global Scope add করা

protected static function boot()
{
    parent::boot();

    static::addGlobalScope('active', function ($query) {
        $query->where('status', 1);
    });
}
Enter fullscreen mode Exit fullscreen mode

✔ সব query-তেই auto filter


5. Audit / Logging

static::updated(function ($model) {
    Log::info('Model updated', $model->toArray());
});
Enter fullscreen mode Exit fullscreen mode

⚡ 4️⃣ boot() vs booted() (Important)
🔹 boot()

  • Old style
  • parent::boot() call করতে হয় 🔹 booted() (Recommended)
protected static function booted()
{
    static::creating(function ($model) {
        $model->user_id = auth()->id();
    });
}
Enter fullscreen mode Exit fullscreen mode

✔ Cleaner
✔ No need parent call


🎯 5️⃣ কখন ব্যবহার করবো?

Situation Use boot
Same logic বারবার লাগে
Model lifecycle event দরকার
Auto field set
Global filter
Business logic centralize

কখন ব্যবহার করবো না?

  • Heavy logic ❌
  • External API call ❌
  • Complex business workflow ❌

👉 এগুলো Service class-এ রাখা better


🧠 Interview-ready Answer

The boot() method in Laravel models is used to hook into model lifecycle events and define global behaviors such as auto-setting fields, applying global scopes, or handling events like creating/updating. It helps avoid code duplication and centralizes model-related logic.


🔥 Pro Insight (Impress Interviewer)

👉 তুমি বলতে পারো:

  • It uses Eloquent model events
  • Helps enforce data consistency
  • Used for cross-cutting concerns
  • Alternative: Observer class (for cleaner architecture)

🏁 Bonus: Cleaner Way (Observer)

php artisan make:observer PostObserver
Enter fullscreen mode Exit fullscreen mode

👉 বড় project হলে observer use করা better


প্রশ্ন ৪ ঃ Laravel এ queue job চালানো জন্য production এ কোন কমেন্ট চালাতে হয়? কেন চালাতে হয়? এর সাথে redis এর সম্পর্ক কি?

Answer:

Laravel এ queue job production-এ চালানোর জন্য সাধারণত তুমি artisan command manually একবার চালিয়ে থেমে যাবে না—বরং একটা long-running worker process রাখতে হয়।

🔥 1. Production এ কোন কমান্ড চালানো হয়?

সবচেয়ে কমন কমান্ড:

php artisan queue:work
Enter fullscreen mode Exit fullscreen mode

Production এ সাধারণত এভাবে ব্যবহার করা হয়:

php artisan queue:work --sleep=3 --tries=3 --timeout=90
Enter fullscreen mode Exit fullscreen mode

বা daemon mode (পুরানো পদ্ধতি):

php artisan queue:work --daemon
Enter fullscreen mode Exit fullscreen mode

⚙️ কিন্তু আসল production setup এ এটা terminal এ চালিয়ে রাখা হয় না

Production এ সাধারণত ব্যবহার করা হয়:

Supervisor (Linux process manager)

Supervisor দিয়ে worker কে background service হিসেবে চালানো হয়:

command=php /var/www/html/artisan queue:work redis --sleep=3 --tries=3
autostart=true
autorestart=true
Enter fullscreen mode Exit fullscreen mode

👉 কারণ:

  • server restart হলে আবার auto start হবে
  • crash করলে auto restart হবে
  • background এ continuous run করবে

🚀 2. কেন queue worker চালাতে হয়?

Laravel queue system কাজ করে এভাবে:

১। তুমি job dispatch করো:

dispatch(new SendEmailJob());
Enter fullscreen mode Exit fullscreen mode

২। job database/redis এ “pending” হিসেবে জমা হয়
৩। worker ছাড়া job কখনো execute হবে না ❌

👉 তাই queue:work চালানো মানে:

“background থেকে queue থেকে job তুলে execute করা”


3. Redis এর সাথে এর সম্পর্ক কী?

Redis এখানে queue driver / storage + broker হিসেবে কাজ করে।

যদি তুমি Redis ব্যবহার করো:

.env:

QUEUE_CONNECTION=redis
Enter fullscreen mode Exit fullscreen mode

তখন flow হবে:

Laravel App → Redis Queue → Worker (queue:work) → Job execute
Enter fullscreen mode Exit fullscreen mode

🧠 Redis কেন ভালো?

Database queue এর তুলনায় Redis:

  • ⚡ খুব fast (RAM based)
  • 🔥 high traffic handle করতে পারে
  • ⏱ low latency
  • 🔁 real-time processing friendly

📦 Laravel Horizon (Redis এর জন্য best option)

Redis use করলে Laravel Horizon use করা best practice:

php artisan horizon
Enter fullscreen mode Exit fullscreen mode

👉 এটা দেয়:

  • queue monitoring dashboard
  • auto restart workers
  • performance tracking

🧾 Summary

বিষয় ব্যাখ্যা
queue:work job execute করে
Production এ Supervisor দিয়ে background এ চালানো হয়
Redis queue data store + fast processing engine
সম্পর্ক Redis queue থেকে worker job গুলো execute করে

⚠️ Bottom line

👉 Queue শুধু “dispatch” করলে কিছুই execute হবে না
👉 Worker (queue:work) না চালালে system dead queue হয়ে থাকবে
👉 Redis শুধু storage + speed layer, worker execution engine না


প্রশ্ন ৫ ঃ laravel 9 থেকে laravel 11 এ প্রজেক্ট মাইগ্রেশানে কি কি বেষ্ট প্রাক্টিস ফলো করা উচিত? laravel documentation দেখে ব্যাখ্যা করো?

Answer:

Laravel 9 থেকে Laravel 11-এ মাইগ্রেশনের সম্পূর্ণ গাইড নিচে দেওয়া হলো, official documentation-এর উপর ভিত্তি করে:


⚠️ প্রথমে জানা দরকার: সরাসরি 9 → 11 নয়
Laravel 9 থেকে সরাসরি 11-এ আপগ্রেড করা technically সম্ভব হলেও recommended নয়। একবারে এক ভার্সন করে আগানো উচিত: 9 → 10 → 11


ধাপ ১: প্রস্তুতি (Pre-Migration)
ব্যাকআপ নাও
যেকোনো পরিবর্তনের আগে সম্পূর্ণ অ্যাপ্লিকেশন ও ডেটাবেজের ব্যাকআপ নাও। যদি কিছু ভুল হয়, আগের অবস্থায় ফেরত যেতে পারবে। Medium
PHP ভার্সন আপডেট করো
Laravel 11-এর জন্য PHP 8.2.0 বা তার বেশি প্রয়োজন। এছাড়া Laravel-এর HTTP client-এর জন্য curl 7.34.0+ লাগবে। Laravel
Third-party প্যাকেজ চেক করো
সব third-party প্যাকেজ ও dependency যাচাই করো যে সেগুলো PHP 8.2 ও Laravel 11 সাপোর্ট করে কিনা।


ধাপ ২: composer.json আপডেট (High Impact)
composer.json-এ নিচের dependency-গুলো আপডেট করো:

"laravel/framework": "^11.0",
"nunomaduro/collision": "^8.1",
"laravel/sanctum": "^4.0",
"laravel/passport": "^12.0",
"laravel/cashier": "^15.0",
"laravel/telescope": "^5.0",
"laravel/breeze": "^2.0",
"livewire/livewire": "^3.4",
"inertiajs/inertia-laravel": "^1.0"
Enter fullscreen mode Exit fullscreen mode

ধাপ ৩: Vendor Migrations পাবলিশ করো (High Impact)
Cashier Stripe, Passport, Sanctum, Spark Stripe, ও Telescope আর নিজেদের migrations directory থেকে অটোমেটিক লোড করে না। তাই নিচের কমান্ডগুলো রান করতে হবে:

php artisan vendor:publish --tag=sanctum-migrations
php artisan vendor:publish --tag=passport-migrations
php artisan vendor:publish --tag=cashier-migrations
php artisan vendor:publish --tag=telescope-migrations
Enter fullscreen mode Exit fullscreen mode

ধাপ ৪: Database Migration-এর পরিবর্তন (High Impact)
Column Modify করার নিয়ম বদলেছে
কোনো column modify করার সময় এখন সব attributes explicitly লিখতে হবে। কোনো attribute বাদ গেলে সেটি drop হয়ে যাবে।

Laravel 9/10 এ কাজ করতো (এখন করবে না):

// শুধু nullable যোগ করলে unsigned ও default হারিয়ে যাবে!
$table->integer('votes')->nullable()->change();
Enter fullscreen mode Exit fullscreen mode

Laravel 11-এ সঠিক উপায়:

$table->integer('votes')
    ->unsigned()
    ->default(1)
    ->comment('The vote count')
    ->nullable()
    ->change(); // সব attributes পুনরায় লিখতে হবে
Enter fullscreen mode Exit fullscreen mode

Float/Double টাইপ বদলেছে
doublefloat column type rewrite করা হয়েছে। unsignedDecimal, unsignedDouble, এবং unsignedFloat methods সরিয়ে দেওয়া হয়েছে। পরিবর্তে ->unsigned() চেইন করতে হবে।

// আগের কোড
$table->unsignedDouble('amount');

// নতুন কোড
$table->double('amount')->unsigned();
Enter fullscreen mode Exit fullscreen mode

পুরনো migrations squash করো
যদি অনেক পুরনো migration থাকে, তাহলে:

php artisan schema:dump
Enter fullscreen mode Exit fullscreen mode

ধাপ ৫: Authentication পরিবর্তন
Password Rehashing
Laravel 11 authentication-এর সময় স্বয়ংক্রিয়ভাবে পাসওয়ার্ড rehash করবে যদি hashing algorithm-এর work factor পরিবর্তন হয়। যদি তোমার User model-এ password field-এর নাম password না হয়, তাহলে model-এ এটি specify করতে হবে:

protected $authPasswordName = 'custom_password_field';
Enter fullscreen mode Exit fullscreen mode

Passport-এ Password Grant Disable
Passport 12.0-এ password grant type ডিফল্টে disabled। চালু করতে AppServiceProvider-এ লিখতে হবে:

public function boot(): void
{
    Passport::enablePasswordGrant();
}
Enter fullscreen mode Exit fullscreen mode

ধাপ ৬: অন্যান্য গুরুত্বপূর্ণ পরিবর্তন
Carbon 3
Laravel 11, Carbon 2 ও Carbon 3 উভয়ই support করে। Carbon 3-এ diffIn* methods এখন floating-point number return করে এবং negative value-ও return করতে পারে — এটি Carbon 2 থেকে উল্লেখযোগ্য পার্থক্য।

Rate Limiting (Medium Impact)
Laravel 11-এ per-second rate limiting সাপোর্ট যুক্ত হয়েছে। Limit class constructor এখন minutes-এর বদলে seconds গ্রহণ করে। Laravel

// আগে (minutes)
new Limit($key, $attempts, 2);

// এখন (seconds)
new Limit($key, $attempts, 2 * 60);
Enter fullscreen mode Exit fullscreen mode

Doctrine DBAL সরানো হয়েছে
Laravel আর doctrine/dbal package-এর উপর নির্ভরশীল নয়। পুরনো Doctrine-ভিত্তিক schema methods সরানো হয়েছে। পরিবর্তে নতুন native methods ব্যবহার করো: Schema::getTables(), Schema::getColumns(), Schema::getIndexes()

MariaDB আলাদা Driver
Laravel 11 MariaDB-এর জন্য আলাদা dedicated driver যোগ করেছে। যদি MariaDB ব্যবহার করো, database.php config-এ driver পরিবর্তন করতে পারো। Laravel


ধাপ ৭: Application Structure (মাইগ্রেশন Optional)
Laravel 11-এ নতুন simplified application structure এসেছে, কিন্তু Laravel 10 থেকে আপগ্রেড করা অ্যাপকে নতুন structure-এ migrate করার দরকার নেই। Laravel 11 পুরনো Laravel 10 structure-কেও সাপোর্ট করে।


🛠️ Bonus: Laravel Shift ব্যবহার করো
বড় codebase-এ manually আপগ্রেড করা অনেক সময়সাপেক্ষ। Laravel Shift টুলটি automatically code adjust করে, composer conflicts resolve করে এবং dependencies align করে — কয়েক ক্লিকেই Laravel 9 থেকে 11-এ যাওয়া সম্ভব হয়।


📋 Quick Checklist

কাজ Priority
PHP 8.2+ install 🔴 High
composer.json আপডেট 🔴 High
Vendor migrations publish 🔴 High
Column modify migrations ঠিক করা 🔴 High
Float/Double type আপডেট 🔴 High
Carbon 3 compatibility চেক 🟡 Medium
Rate Limiter seconds-এ রাখঞ্জর 🟡 Medium
Passport password grant চেক 🟡 Medium
Doctrine DBAL লোড replace 🟢 Low

সবচেয়ে নিরাপদ পথ হলো staging environment-এ আগে সব পরীক্ষা করো, তারপর production-এ deploy করো।


প্রশ্ন ৬ ঃ laravel এ clouser কি? কেন ব্যবহার করা হয়? কোন প্রবলেম টা সলভ করে?
Php তে clouser & magic method কি?

Answer:

Laravel-এ Closure কী?
Closure হলো anonymous function (নামহীন ফাংশন) যেটাকে variable-এ store করা যায়, argument হিসেবে pass করা যায়, বা return করা যায়।
PHP-তে Closure হলো Closure class-এর একটি instance।

// সাধারণ named function
function add($a, $b) {
    return $a + $b;
}

// Closure (anonymous function)
$add = function($a, $b) {
    return $a + $b;
};

echo $add(2, 3); // 5
Enter fullscreen mode Exit fullscreen mode

কেন Closure ব্যবহার করা হয়?
১. Route Definition-এ

// ছোট logic-এর জন্য আলাদা Controller না বানিয়ে
Route::get('/hello', function () {
    return 'Hello World';
});

Route::get('/user/{id}', function ($id) {
    return User::find($id);
});
Enter fullscreen mode Exit fullscreen mode

২. Collection-এ (সবচেয়ে বেশি ব্যবহার)

$users = collect([
    ['name' => 'Rahim', 'age' => 25],
    ['name' => 'Karim', 'age' => 17],
    ['name' => 'Salam', 'age' => 30],
]);

// filter() - closure দিয়ে condition
$adults = $users->filter(function ($user) {
    return $user['age'] >= 18;
});

// map() - closure দিয়ে transform
$names = $users->map(function ($user) {
    return strtoupper($user['name']);
});
Enter fullscreen mode Exit fullscreen mode

৩. use keyword দিয়ে বাইরের variable ধরা
এটা Closure-এর সবচেয়ে গুরুত্বপূর্ণ feature।

$discount = 10;

$getPrice = function($price) use ($discount) {
    return $price - $discount;
};

echo $getPrice(100); // 90
echo $getPrice(200); // 190
Enter fullscreen mode Exit fullscreen mode

use ছাড়া Closure বাইরের variable দেখতে পায় না।

৪. Middleware-এ

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(function ($request, $next) {
    if (!auth()->check()) {
        return redirect('/login');
    }
    return $next($request);
});
Enter fullscreen mode Exit fullscreen mode

৫. Event & Queue-এ

Event::listen('user.registered', function ($user) {
    Mail::to($user->email)->send(new WelcomeMail($user));
});
Enter fullscreen mode Exit fullscreen mode

৬. Service Container Binding-এ

// AppServiceProvider
$this->app->bind('PaymentGateway', function ($app) {
    return new StripeGateway(config('services.stripe.key'));
});
Enter fullscreen mode Exit fullscreen mode

৭. Query Scope-এ (Eager Loading)

$users = User::with(['posts' => function ($query) {
    $query->where('published', true)
          ->orderBy('created_at', 'desc');
}])->get();
Enter fullscreen mode Exit fullscreen mode

কোন Problem Solve করে?
সমস্যা ১: ছোট কাজের জন্য আলাদা ফাংশন বানানো waste

// ❌ এভাবে প্রতিটার জন্য আলাদা ফাংশন বানানো অনেক verbose
function filterAdults($user) { return $user['age'] >= 18; }
function filterSeniors($user) { return $user['age'] >= 60; }

// ✅ Closure দিয়ে inline-এই লেখা যায়
$adults  = $users->filter(fn($u) => $u['age'] >= 18);
$seniors = $users->filter(fn($u) => $u['age'] >= 60);
Enter fullscreen mode Exit fullscreen mode

সমস্যা ২: Context/State ধরে রাখা

$tax = 0.15;
$shipping = 50;

// Closure-এ দুটো বাইরের variable একসাথে ব্যবহার
$totalPrice = function($price) use ($tax, $shipping) {
    return ($price * (1 + $tax)) + $shipping;
};

echo $totalPrice(1000); // 1200
Enter fullscreen mode Exit fullscreen mode

সমস্যা ৩: Lazy Evaluation (দরকার হলে তবেই execute)

// Closure পাস করলে সাথে সাথে execute হয় না
// যখন দরকার তখন call করা হয়

$this->app->bind('HeavyService', function () {
    // শুধুমাত্র এই service যখন resolve হবে তখনই চলবে
    return new HeavyService();
});
Enter fullscreen mode Exit fullscreen mode

Arrow Function (PHP 7.4+) — Closure-এর Short Syntax

// পুরনো Closure
$multiply = function($n) use ($factor) {
    return $n * $factor;
};

// Arrow Function - use ছাড়াই বাইরের variable পায়
$factor = 3;
$multiply = fn($n) => $n * $factor;

// Collection-এ
$doubled = $users->map(fn($u) => $u['age'] * 2);
Enter fullscreen mode Exit fullscreen mode

Interview-এ Summary বলার মতো করে

"Closure হলো anonymous function যেটা variable-এ রাখা যায় এবং argument হিসেবে পাস করা যায়। Laravel-এ এটা Route, Collection, Service Container, Event, Queue সহ প্রায় সব জায়গায় ব্যবহার হয়। এটা মূলত তিনটা সমস্যা সমাধান করে — ১) ছোট one-time logic-এর জন্য আলাদা function না বানিয়ে inline লেখা, ২) use keyword দিয়ে বাইরের context/state ধরে রাখা, এবং ৩) Lazy evaluation — মানে code তখনই execute হয় যখন দরকার।"


দুইটা টপিকই PHP-তে খুব গুরুত্বপূর্ণ 👍
আমি সহজভাবে Closure আর Magic Method—দুটোই উদাহরণসহ বুঝিয়ে দিচ্ছি।


🔹 1️⃣ PHP Closure কী?

👉 Closure (Anonymous Function) হলো এমন একটি function যার কোনো নাম নেই, এবং এটাকে variable-এ assign করে ব্যবহার করা যায়।


📌 Basic Example:

$greet = function($name) {
    return "Hello, $name";
};

echo $greet("Ruhul");
Enter fullscreen mode Exit fullscreen mode

🔥 Closure এর বিশেষ ক্ষমতা (use keyword)

👉 বাইরের variable ভিতরে ব্যবহার করা যায়

$message = "Hi";

$greet = function($name) use ($message) {
    return "$message, $name";
};

echo $greet("Sujon");
Enter fullscreen mode Exit fullscreen mode

use ($message) না দিলে কাজ করবে না


🚀 Laravel-এ Closure Example:

Route::get('/', function () {
    return "Welcome";
});
Enter fullscreen mode Exit fullscreen mode

👉 এখানে route-এর ভিতরের function টা closure


🎯 Closure কেন ব্যবহার করি?

  • Callback function
  • Route handling
  • Collection method (map, filter)
  • Clean & short code

🔹 2️⃣ PHP Magic Method কী?

👉 Magic Method হলো special method, যেগুলো automatically call হয় নির্দিষ্ট situation-এ।

👉 সব magic method শুরু হয় __ (double underscore) দিয়ে


🔥 Common Magic Methods


1️⃣ __construct() (Constructor)

class User {
    public function __construct() {
        echo "Object created";
    }
}
Enter fullscreen mode Exit fullscreen mode

👉 Object create হলে auto call হয়


2️⃣ __destruct()

public function __destruct() {
    echo "Object destroyed";
}
Enter fullscreen mode Exit fullscreen mode

3️⃣ __get() (Undefined property access)

class User {
    public function __get($name) {
        return "Property $name not found";
    }
}

$user = new User();
echo $user->email;
Enter fullscreen mode Exit fullscreen mode

4️⃣ __set() (Undefined property set)

public function __set($name, $value) {
    echo "Setting $name = $value";
}
Enter fullscreen mode Exit fullscreen mode

5️⃣ __call() (Undefined method call)

public function __call($method, $args) {
    echo "Method $method not found";
}
Enter fullscreen mode Exit fullscreen mode

6️⃣ __toString()

public function __toString() {
    return "User object";
}
Enter fullscreen mode Exit fullscreen mode

👉 Object print করলে call হয়


7️⃣ __invoke()

class Test {
    public function __invoke() {
        return "Called as function";
    }
}

$obj = new Test();
echo $obj(); // invoke
Enter fullscreen mode Exit fullscreen mode

🔍 Closure vs Magic Method

বিষয় Closure Magic Method
কী Anonymous function Special class method
কাজ Callback / inline logic Auto-trigger behavior
Scope Function level Class level
Laravel usage Route, Collection Model, Eloquent

🧠 Interview-ready Answer

👉 Closure:

Closure is an anonymous function that can capture variables from its parent scope using the use keyword.

👉 Magic Method:

Magic methods are special methods in PHP that are automatically invoked when certain actions occur, such as object creation, property access, or method calls.


🔥 Pro Insight (Impress Interviewer)

  • Laravel heavily uses closures (route, middleware, collections)
  • Eloquent uses magic methods (__get, __set) for dynamic properties

Top comments (0)