পিএইচপি ফ্রেমওয়ার্কস - লারাভেল আর্কিটেকচার (Senior Level)

লারাভেল শেখা সহজ, কিন্তু লারাভেলের "ম্যাজিক" এর পেছনের বিজ্ঞান বোঝা কঠিন। এই অধ্যায়ে আমরা লারাভেলের হুড খুলে দেখব ইঞ্জিন কীভাবে চলে। এটি ইন্টারভিউ এবং সিস্টেম ডিজাইনের জন্য ক্রুশিয়াল

১৪.১ সার্ভিস কন্টেইনার (The Heart of Laravel)

লারাভেলের হৃদপিণ্ড হলো Service Container। এটি মূলত একটি শক্তিশালী Dependency Injection (DI) Container।

🎯 এটি কেন দরকার? (Inversion of Control)

// Without Container (Hard Dependency)
$payment = new StripePayment(new Logger(), new Config());
$user = new UserService($payment);

✅ Laravel Way (Auto Resolution): লারাভেল পিএইচপির Reflection API ব্যবহার করে ক্লাসের কনস্ট্রাক্টর চেক করে এবং অটোমেটিক্যালি ডিপেন্ডেন্সি ইনজেক্ট করে।

class UserController {
    // লারাভেল দেখবে UserService দরকার, সে নিজে বানিয়ে দেবে
    public function __construct(UserService $service) { ... }
}

🔧 বাইন্ডিং মেথডস (Binding Methods):

  • bind(): প্রতিবার কল করলে নতুন অবজেক্ট তৈরি হয়
  • singleton(): পুরো অ্যাপ লাইফসাইকেলে একবারই অবজেক্ট তৈরি হয় (যেমন: DB Connection)
  • instance(): আগে থেকে তৈরি করা অবজেক্ট বাইন্ড করা

১৪.২ সার্ভিস প্রোভাইডার (The Bootstrapper)

লারাভেল অ্যাপ রান করার সময় কোথায় কনফিগারেশন লোড হয়? কোথায় রাউট রেজিস্টার হয়? সব ঘটে Service Provider-এ।

📝 register()

এখানে শুধু কন্টেইনারে বাইন্ডিং ($this->app->bind(...)) করবেন। অন্য কোনো সার্ভিস কল করবেন না। কারণ অন্য সার্ভিস তখনো লোড নাও হতে পারে।

🚀 boot()

সব প্রভাইডার রেজিস্টার হওয়ার পর এটি কল হয়। এখানে ইভেন্ট লিসেনার, রাউট বা ভিউ কম্পোজার কল করা নিরাপদ।

💡 Senior Tip (Deferred Providers):

সব প্রভাইডার সব রিকোয়েস্টে লোড করার দরকার নেই। protected $defer = true; করে দিলে লারাভেল কেবল তখনই প্রভাইডার লোড করবে যখন ওই সার্ভিসটি কল করা হবে। এতে পারফরম্যান্স বাড়ে

১৪.৩ ফ্যাসাড (Facades) - স্ট্যাটিক ম্যাজিক

ফ্যাসাড লারাভেলের সবচেয়ে বিতর্কিত কিন্তু জনপ্রিয় ফিচার। এটি দেখতে স্ট্যাটিক মেথডের মতো, কিন্তু কাজ করে ডাইনামিক্যালি।

⚙️ ইন্টারনাল মেকানিজম:

যখন আপনি Cache::get('key') কল করেন:

  1. Cache ফ্যাসাড ক্লাসে getFacadeAccessor() মেথড থাকে যা রিটার্ন করে স্ট্রিং 'cache'
  2. লারাভেলের __callStatic() ম্যাজিক মেথড ট্রিগার হয়
  3. সে কন্টেইনার থেকে 'cache' সার্ভিসটি বের করে আনে
  4. তারপর সেই অবজেক্টের ওপর get() মেথড চালায়

✅ Pros

কোড ক্লিন এবং রিডেবল

⚠️ Cons

ডিপেন্ডেন্সি লুকিয়ে রাখে (Constructor এ দেখা যায় না)

১৪.৪ ইলোকয়েন্ট ওআরএম (Deep Internals)

ইলোকয়েন্ট হলো ActiveRecord প্যাটার্নের ইমপ্লিমেন্টেশন।

📦 ১. কুয়েরি বিল্ডার লাইফসাইকেল

User::where('active', 1)->get() কল করলে:

  1. মডেল বুট হয় (Observe, Global Scopes অ্যাপ্লাই হয়)
  2. কুয়েরি বিল্ডার তৈরি হয়
  3. Grammar ক্লাস SQL জেনারেট করে
  4. ডাটাবেস থেকে stdClass অবজেক্ট আসে
  5. Hydration: লারাভেল সেই ডাটাকে User মডেল অবজেক্টে কনভার্ট করে

❌ ২. Lazy vs Eager Loading (N+1 Problem)

// ❌ Lazy Loading (N+1 Query)
$users = User::all(); // Query 1
foreach ($users as $user) {
    echo $user->profile->bio; // Query N (প্রতি ইউজারের জন্য ১টি করে)
}

// ✅ Eager Loading
$users = User::with('profile')->get(); // মাত্র ২টা কুয়েরি

✅ ৩. মেমোরি অপ্টিমাইজেশন

বড় ডাটাসেটের জন্য get() ব্যবহার করবেন না। ব্যবহার করুন cursor() বা chunk()

১৪.৫ কিউ সিস্টেম (Asynchronous Jobs)

ইউজারকে বসিয়ে রেখে ইমেইল পাঠানো বা ইমেজ প্রসেসিং করা যাবে না।

🏗️ আর্কিটেকচার:

  • Producer: জব ডিসপ্যাচ করে (SendEmail::dispatch())
  • Queue: জবটি রেডিস বা ডাটাবেসে জমা থাকে
  • Consumer (Worker): ব্যাকগ্রাউন্ডে (php artisan queue:work) জবটি নিয়ে এক্সিকিউট করে

💡 Senior Considerations:

  • Retry Logic: জব ফেইল করলে কতবার চেষ্টা করবে? (public $tries = 3;)
  • Idempotency: একই জব ভুলে দুইবার রান করলে যেন সমস্যা না হয় (যেমন দুইবার টাকা না কাটে)
  • Horizon: রেডিস কিউ মনিটর করার জন্য লারাভেল হরাইজন এন্টারপ্রাইজ স্ট্যান্ডার্ড

১৪.৬ ইভেন্ট এবং লিসেনার (Decoupling)

কোডকে অগোছালো হওয়া থেকে বাঁচায়। Scenario: ইউজার রেজিস্টার করলে ইমেইল পাঠাতে হবে এবং ওয়েলকাম এসএমএস দিতে হবে।

❌ Bad (Controller bloating):

$user->save();
Mail::send(...);
SMS::send(...);

✅ Good (Event Driven):

UserRegistered::dispatch($user);

// Listener 1: SendWelcomeEmail
// Listener 2: SendWelcomeSMS

এতে কন্ট্রোলার ক্লিন থাকে এবং লজিক আলাদা ফাইলে থাকে।

১৪.৭ মিডলওয়্যার এবং পাইপলাইন (The Onion)

লারাভেলের রিকোয়েস্ট সাইকেল একটি পেঁয়াজের (Onion) মতো। রিকোয়েস্ট কেন্দ্রে (Controller) পৌঁছানোর আগে অনেকগুলো লেয়ার (Middleware) পার হয়।

🔧 পাইপলাইন প্যাটার্ন (Pipeline Pattern)

লারাভেল ইন্টারনালি Pipeline ক্লাস ব্যবহার করে। এটি একটি অবজেক্টকে (Request) অনেকগুলো প্রসেসরের (Middleware) মধ্য দিয়ে পাস করে।

Request → Middleware 1 → Middleware 2 → Controller → Response

১৪.৮ কন্ট্রাক্টস (Interfaces)

লারাভেল "Program to an interface, not an implementation" নীতি ফলো করে।

Illuminate\Contracts\Cache\Repository ইন্টারফেসটি বলে দেয় ক্যাশ সিস্টেম দেখতে কেমন হবে। আপনি চাইলে রেডিসের বদলে মেমক্যাশ বা ফাইল ড্রাইভার ব্যবহার করতে পারেন, কোড পরিবর্তন ছাড়াই।

১৪.৯ ক্যাশিং এবং পারফরম্যান্স টিউনিং

লারাভেল স্লো—এই বদনাম ঘোচানোর উপায়:

  • 📦Config & Route Cache: php artisan config:cache এবং route:cache - বুট টাইম ৫০-৬০% কমায়
  • Composer Optimized Autoload: composer dump-autoload -o ক্লাস ম্যাপ অপ্টিমাইজ করে
  • 💾Query Caching: বারবার একই কুয়েরি না চালিয়ে রেডিসে ক্যাশ করে রাখা
  • 🚀Laravel Octane: Swoole বা RoadRunner ব্যবহার করে লারাভেলকে মেমোরিতে লোড করে রাখা (সুপার ফাস্ট)

১৪.১০ সিম্ফনি কম্পোনেন্টস (The Foundation)

লারাভেল শূন্য থেকে তৈরি হয়নি। এটি সিম্ফনির অনেকগুলো কম্পোনেন্টের ওপর দাঁড়িয়ে আছে।

  • HttpFoundation: Request এবং Response হ্যান্ডেল করে
  • Console: Artisan কমান্ড মূলত সিম্ফনি কনসোল
  • Routing: লারাভেলের রাউটিং ইঞ্জিন

একজন সিনিয়রের জানা উচিত কোনটি লারাভেলের নিজস্ব আর কোনটি সিম্ফনি থেকে এসেছে।

🎯 Senior Developer Interview Questions (Chapter 14)

Q: সার্ভিস কন্টেইনারে bind এবং singleton এর পার্থক্য কী?

bind প্রতিবার ডিপেন্ডেন্সি রিজলভ করার সময় নতুন ইনস্ট্যান্স তৈরি করে। singleton প্রথমবার তৈরি করে এবং পরবর্তী সব কলের জন্য সেই একই ইনস্ট্যান্স রিটার্ন করে (মেমোরি এফিশিয়েন্ট)।

Q: N+1 প্রবলেম কী এবং লারাভেলে এটি কীভাবে ডিটেক্ট ও সলভ করবেন?

যখন লুপের ভেতর রিলেশন এক্সেস করা হয় এবং প্রতিবার আলাদা কুয়েরি রান হয়। সলভ করার জন্য Eager Loading (with()) ব্যবহার করতে হয়। ডিটেক্ট করার জন্য Laravel Debugbar বা Model::preventLazyLoading() ব্যবহার করা যায়।

Q: ফ্যাসাড (Facade) কি অ্যান্টি-প্যাটার্ন? কেন ব্যবহার করব বা করব না?

পিওরিস্টদের মতে এটি অ্যান্টি-প্যাটার্ন কারণ এটি ডিপেন্ডেন্সি লুকিয়ে রাখে (Static Coupling)। তবে লারাভেলে এটি টেস্টিং-ফ্রেন্ডলি এবং র‍্যাপিড ডেভেলপমেন্টের জন্য খুবই কাজের। বড় এন্টারপ্রাইজ অ্যাপে Constructor Injection ব্যবহার করাই বেস্ট প্র্যাকটিস।

Q: php artisan config:cache কমান্ডটি চালালে কী হয়?

এটি config ফোল্ডারের সব ফাইলকে একটি সিঙ্গেল পিএইচপি ফাইলে মার্জ করে। ফলে প্রতি রিকোয়েস্টে লারাভেলকে ডজন ডজন কনফিগ ফাইল রিড করতে হয় না, যা বুট টাইম ফাস্ট করে

🎯 অধ্যায় ১৪ এর সারাংশ (Summary)

এই অধ্যায়ে আমরা শিখলাম:

  • Service Container: bind() vs singleton(), Reflection API-based auto-injection
  • Service Providers: register() vs boot(), Deferred Providers for performance
  • Facades: __callStatic() magic, getFacadeAccessor()
  • Eloquent: Hydration, N+1 Problem, Eager Loading, cursor()/chunk()
  • Queue: Producer/Consumer pattern, Retry Logic, Idempotency, Horizon
  • Events: Decoupling with Event/Listener pattern
  • Performance: config:cache, route:cache, Octane, composer optimize

✨ এখন আপনি লারাভেলের ইন্টারনাল আর্কিটেকচার সম্পর্কে ওয়াকিবহাল।

🚀 PHP Senior Journey: 14 Chapters Completed! 🎉

🔒 কপিরাইট সুরক্ষিত কন্টেন্ট 🔒

কপি, স্ক্রিনশট, প্রিন্ট করা সম্পূর্ণ নিষিদ্ধ।