هرچی باید دربارهٔ Context Facade لاراول بدونی
خلاصهٔ کاملتر
به گفتهٔ نویسنده، دیباگ اپلیکیشنهای پروداکشن بهندرت دربارهٔ یه خط لاگ تنهاست؛ چیزی که واقعاً لازم داریم داستانِ دور اون خطه: کدوم درخواست باعثش شد، کدوم تننت یا کاربر درگیر بود و کدوم جاب کار رو بعداً ادامه داد. مدتها این رو با پاس دادن دستیِ آرایه به Log::info() یا ساختن سیستم همبستگیِ خودمون حل میکردیم که تکراری و خستهکنندهست.
نویسنده Context رو یه «مخزن کلید-مقدار برای هر اجرا» توصیف میکنه. یه بار داده رو اضافه میکنی و بعد هر لاگی که تو همون اجرا نوشته شه میتونه خودکار اون داده رو شامل شه. نتیجه اینه که لاگ نهایی دو جور اطلاعات داره: کانتکستی که مستقیم به همون فراخوانی لاگ داده شده، و دادهٔ مشترکِ Context. این جداسازی مهمه؛ فراخوانی لاگ «چی همونجا اتفاق افتاد» رو توصیف میکنه و مخزن Context «اجرای گستردهتر دور اون» رو.
طبق مطلب، Context خوب تو چرخهٔ عمر درخواست جا میگیره، چون میشه زود پُرش کرد و دیرتر خوندش. رایجترین جا برای اضافه کردن کانتکست HTTP هم میدلوِره؛ مثلاً یه middleware که یه trace_id، نام روت، URL و شناسهٔ کاربر رو یه بار ست میکنه و بعدش هر لاگی عمیقتر تو درخواست، لازم نیست دوباره اینها رو پاس بده.
API عمومیش عمداً کوچیک و کاربردیه. یه یا چند مقدار رو با add() اضافه میکنی و اگه کلید موجود باشه جایگزین میشه؛ اگه فقط بخوای وقتی کلید نیست ست کنی از addIf() استفاده میکنی. متدهای get()، has() و missing() هم برای خوندن و بررسی وجود کلیدن. نویسنده به یه جزئیات از پیادهسازی اشاره میکنه: has() از array_key_exists() استفاده میکنه نه یه بررسی truthy، پس یه کلید با مقدار null هم هنوز «وجود داره».
یه نکتهٔ ظریف اینه که کلیدهای Context آرایهای سادهان، نه نُتگذاری نقطهای؛ یعنی کلیدی مثل payment.gateway فقط یه رشتهٔ کلیده و آرایهٔ تودرتو نمیسازه. نویسنده ترجیح میده کلیدهای تخت و صریح مثل trace_id و tenant_id به کار ببره.
وقتی یه مقدار کافی نیست، استکها کمک میکنن؛ مثلاً برای ثبت لیستی از چیزهایی که تو یه درخواست اتفاق افتادن مثل مرحلهها یا بردکرامبها. با push() مقدار اضافه میکنی و با pop() آخرین مقدار رو برمیداری. نویسنده هشدار میده لاراول فقط وقتی استک رو مجاز میدونه که کلید یا موجود نباشه یا از قبل یه آرایهٔ لیستی باشه؛ اگه قبلش یه مقدار اسکالر زیر اون کلید ذخیره کرده باشی، push() و pop() یه استثنای زماناجرا پرت میکنن.
نویسنده جمعبندی میکنه که دلیل اصلیِ وجود این قابلیت اینه که Context میتونه زود پُر شه، تو لاگها استفاده شه و به جابهای صفبندیشده هم حمل شه؛ داده موقع دیسپچ جاب dehydrate میشه و موقع پردازش دوباره hydrate میشه تا لاگهای جاب هم کانتکست اصلی رو داشته باشن. پیام کلیدی اینه که Context جایگزین آرایهٔ کانتکستِ لاگ نیست، بلکه متادیتای اجرای مشترکیه که لاراول برات حمل و ضمیمه میکنه.
نکات کلیدی:
- Context یه مخزن کلید-مقدار برای هر اجراست که خودکار به لاگها ضمیمه میشه
- کانتکستِ لاگ «همونجا چی شد» و Context «اجرای گستردهتر» رو توصیف میکنه
- APIش با add، addIf، get، has و forget عمداً کوچیک نگه داشته شده
- کلیدها آرایهای سادهان، نه نُتگذاری نقطهای تودرتو
- استکها لیست رخدادها رو نگه میدارن و Context به جابهای صف عبور میکنه




