# ইনভায়রনমেন্ট ডিটেকশন

## ইনভায়রনমেন্ট ডিটেকশন

এই চ্যাপ্টার এ আমরা ইনভায়রনমেন্ট নিয়ে বিস্তারিত আলোচনা করব।

## ইনভায়রনমেন্ট সেটআপ কেন জরুরী?

বড় কোন অ্যাপ্লিকেশন এর বিভিন্ন স্টেজ থাকে । এবং প্রত্যেক স্টেজ এর জন্য সার্ভার ইন্সটলেশন অথবা ওয়েব হেড থাকে। উদাহারন হিসাবে আমরা একটা আইডিয়াল কেস চিন্তা করি।

ধরা যাক আমাদের অ্যাপ্লিকেশন এর গিট রিপো তে তিনটা ব্রাঞ্চ আছে যথাক্রমে `dev`, `staging` এবং `master ( which is also maybe the main production branch)` এবং তিনটা ব্রাঞ্চ এর জন্য তিনটা ওয়েব ইন্সটলেশন আছে যথাক্রমে `dev.application.com` `staging.application.com` এবং `application.com` এবং গিট হুক ব্যাবহার করে আমরা সহজেই অটো ডিপ্লয়মেন্ট সেট করতে পারি যেন ডেভলপাররা গিট রিপো তে নতুন কোড কমিট করার সাথে সাথেই আমারা corresponding ইন্সটলেশন এ গিয়ে ইফেক্ট দেখে চেক করতে পারি ।

ওর ম্যাবি প্রজেক্ট এর `QA` টিম ঐ ফিচারটা টেস্ট করা শুরু করে দিতে পারে । এখন কোন ফিচার প্রথমে `dev` এ যায়, সেখানে অন্য ডেভলপাররা অথবা `QA` টিম চেক করে গ্রিন সিগনাল দিলে, সেই ফিচার ম্যানেজার/বিজনিজ ওনার কে দেখানোর জন্য `staging` এ পুশ করা হয়। এবং সবাই ফাইনালি এপ্রুভ করলে `production` এ এন্ড ইউজার দের জন্য সেই ফিচারটা ওপেন করা হয়।

এখন আমাদের `codebase` তো একটা কিন্তু আমাদের তিন ধরনের কনফিগারেশন দরকার। কারণ `dev`, `staging` এবং `production` এর আলাদা আলাদা ডেটাবেজ থাকবে, `dev` এ দেখা গেল আমরা সুবিধার জন্য `sqlite` ব্যাবহার করলাম, বাট স্টেজিং এ মাই সিকিউএল লাগবে। প্রোড এ অন্য কোন `DBMS` । কিংবা ডেভ এ আমরা ফাইল বেইসড ক্যাশিং ব্যাবহার করলাম কিন্তু সার্ভার এ `memcached` অথবা `redis` লাগবে। এইসব এক্সটার্নাল সার্ভিস ব্যাবহার করার জন্য আমাদের কোন `php` প্যাকেজ বা লাইব্রেরী ব্যাবহার করতে হবে। বেশির ভাগ ক্ষেত্রেই এইসব প্যাকেজ এর কনফিগ ফাইল থাকে যেখানে ভিভিন্ন প্যারামিটার সেট অথবা দরকার মত বদলানো যায়।

কিংবা ধরুন আপনারা দুইজন একটা প্রোজেক্ট এ কাজ করতেসেন কিন্তু আপনাদের ডেটাবেজ এর কনফিগ ফাইল একটা। এখন কি হবে প্রত্যেক বার গিট থেকে কোড আপডেট করার পর আপনাকে ঐ ফাইল চেঞ্জ করতে হবে যেন অ্যাপ্লিকেশন আপনার লোকাল ডেটাবেজ এ কানেক্ট করতে পারে।

আরও একটা কমন কেইস হল, সেন্ডিং ইমেইল ফ্রম লোকাল মেশিন। সো আমারা চাই লোকাল ইনভায়রনমেন্ট এ মেইল ফাংশান কল করলে সেইটা শুধু লগ ফাইলে মেইল এর কন্টেন্ট লগ করবে যেহুতু লোকাল মেশিন থেকে মেইল পাঠানো সহজ না , কিন্তু সার্ভার এ যেহুতু মেইল সেন্ড করতে কোন সমস্যা নাই সেখানে যেন ঠিকমত মেইল সেন্ড হয় ।

এইরকম অবস্থায় আমাদের যা দরকার তা হল মাল্টিপল সেট অফ কনফিগ ফাইলস যা কিছু কন্ডিশন এর উপর বেইজ করে অটোম্যাটিকালি লোড হবে এবং আমারা গিট এ কোড পুশ করা মাত্রই অন্য কোন কিছু চেঞ্জ করা ছাড়াই আমাদের কমিট করা নতুন ফিচার কারেসপন্ডিং ওয়েব হেড এ কাজ করবে।

সো ইনভায়রনমেন্ ম্যানেজমেন্ট হল আমাদের অ্যাপ্লিকেশন কে কোন সময় কি করতে হবে তা ডিসাইড করতে সাহায্য করা।

## লারাভেল কিভাবে ইনভায়রনমেন্ট ডিটেক্ট করে ?

প্রত্যেকটি লারাভেল অ্যাপ্লিকেশন যখন রান করে তখন বুটস্ট্র্যাপিং এর প্রথম দিকে লারাভেল ইনভায়রনমেন্ট ডিটেক্ট করে। এবং এর পর ওই রিকুয়েস্ট সাইকেল এর পরবর্তী অনেক কাজে ওই ইনভায়রনমেন্ট এর উপর নির্ভর করে বিভিন্ন ডিসিশান নেয়।

আমি এই সিরিজ এ লারাভেল এর 4.2.\* ভার্শন নিয়ে কথা বলব। আমার জানি লারাভেল এর সব রিকুয়েস্ট `public/index.php` এর মাধ্যমে প্রসেস হয়। এই প্যাটার্ন `Front Controller Pattern` নামে পরিচিত। লারাভেল সহ সব `MVC` framework ই এই প্যাটার্ন ফলো করে। আচ্ছা আমরা লারাভেল রিকুয়েস্ট সাইকেল নিয়ে অন্য কোন পোষ্ট এ কথা বলব।

লারাভেল ডিফল্ট ইন্সটলেশন এ `bootstrap/start.php` ফাইল এ ইনভায়রনমেন্ট ডিটেকশন হয় যা `public/index.php` ফাইল এ `autolaoder` এর পরই লোড করা হয়। সো বলা যায় ইনভায়রনমেন্ট ডিটেকশন লারাভেল রিকুয়েস্ট লাইফ সাইকেল এর একদম প্রথম দিকেই ঘটে, কারণ ইনভায়রনমেন্ট এর উপর নির্ভর করে লারাভেল কনফিগ ফাইল লোড করে।

```php
$env = $app->detectEnvironment(array(

    'local' => array('homestead'),

));
```

বাই ডিফল্ট `local` ইনভায়রনমেন্ট এর জন্য হোস্টনেম `homestead` থাকে কারণ যারা `homestead` ব্যাবহার করে তাদের যেন কিছু পরিবর্তন করতে না হয়। এইরকম অনেক ক্ষেত্রেই লারাভেল বিভিন্ন কনভেনশন ব্যাবহার করে। এই কাজটার জন্য একটা ডেডিকেটেড টার্ম আছে `Convention Over Configuration` যেই কাজটা মেবি রেইলস প্রথমে শুরু করেছিল। এইটার উদ্দেশ্য হল প্রচলিত আলিখিত কিছু নিয়ম ফলো করলে কাজ অনেক সহজ হয়ে যাবে। কাইন্ড অফ দ্যা ফ্রেমওয়ার্ক উইল থিংক এহেড ফর ইয় ইন ম্যানি কেজেস টু ম্যাইক ইউর লাইফ ইজিয়ার।

লারাভেল ইনভায়রনমেন্ট ডিটেক্ট করার জন্য `hostname` ব্যাবহার করে। বাট লাইক ম্যানি আদার থিংস, ইউ ক্যান ইউজ ইউর ওন ওয়ে টু।

## নতুন ইনভায়রনমেন্ট যোগ করা

ইনভায়রনমেন্ট যোগ করার সহজ উপায় হল `hostname` ব্যাবহার করা। লিনাক্স অথবা ম্যাক এ টার্মিনাল এ `hostname` কমান্ড ব্যাবহার করে হোস্টনেম বের করা যায়। আমরা নিচের মত করে আরও ইনভায়রনমেন্ট যোগ করতে পারি।

```php
$env = $app->detectEnvironment(array(

    'local' => array('homestead'),
    'staging' => array('staging-host-name'),
    'prod' => array('prod-host-name')

));
```

এইভাবে ইনভায়রনমেন্ট যোগ করলে লারাভেল হোস্টনেম চেক করে ঠিকমত ইনভায়রনমেন্ট ডিটেক্ট ও সেট করবে। কিন্তু আমাদের `staging` আর `prod` যদি একই সার্ভার এ থাকে তাহলে `hostname` ব্যাবহার করে তাদের আলাদাভাবে ডিটেক্ট করা সম্ভব না।

সো আরও সুন্দরভাবে ইনভায়রনমেন্ট যোগ করার জন্য আমরা `$app->detectEnvironment()` মেথড এ এরে এর পরিবর্তে পরিবর্তে `closure` ব্যাবহার করে আমাদের সুবিধামত ইনভায়রনমেন্ট ডিটেকশন কোড যোগ করতে পারি।

```php
$env = $app->detectEnvironment(function(){

    return getenv('LARAVEL_ENV') ?: 'local';

});
```

উপরের ফাংশনটি প্রথমে `genenv()` ফাংশান এর মাধ্যমে `LARAVEL_ENV` নামে কোন `key` ইনভায়রনমেন্ট ভ্যারিয়েবল এ আছে কিনা এবং যদি পায় তাহলে তার ভ্যালু রিটার্ন করে এবং ঐ ভ্যালূই ইনভায়রনমেন্ট হিসাবে সেট করে। আর যদি ঐ `key` Exist না করে তাহলে `local` রিটার্ন করে, অর্থাৎ ঐ `key` না থাকলে `local` ইনভায়রনমেন্ট সেট হয়।

## আমারা কিভাবে ইনভায়রনমেন্ট ভ্যারিয়েবল সেট করতে পারি?

এপাচি তে ইনভায়রনমেন্ট ভ্যারিয়েবল সেট করা খুব সহজ। `vhost` অথবা `htaccess` ফাইল এ নিচের মত করে ইনভায়রনমেন্ট ভ্যারিয়েবল সেট করতে পারি।

```bash
SetEnv LARAVEL_ENV dev
```

অথবা আপনি যদি `nginx` ব্যাবহার করেন তাহলে আপনাকে `php-fpm, or php-cgi` এর মাধ্যমে ইনভায়রনমেন্ট ভ্যারিয়েবল সেট করতে হবে কারণ `nginx`, `apache` এর মত নিজে `php` প্রসেস নিজে ম্যানেজ করেনা ।

```bash
php-fpm

...
env[LARAVEL_ENV] = dev
...
php-cgi

location / {
    ...
    fastcgi_param LARAVEL_ENV dev; 
    ...
}
```

আমরা পরের পোষ্ট এ লারাভেল কিভাবে মাল্টিপল কনফিগ ফাইল ইনভায়রনমেন্ট এর উপর বেইজ করে লোড করে তা দেখব।


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://laravel.howtocode.dev/better-environment/environment-detection.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
