| AmirHossein | – Telegram
| AmirHossein |
592 subscribers
44 photos
8 videos
2 files
73 links
نوشته‌های یک برنامه‌نویس ناشی

🫂 @StartUnity
Download Telegram
بعد مدت‌ها اومدم دوره لاراول رو ادامه بدم که برق رفت
چند وقته کانال خوابیده و محتوایی نداره، فردا هر طور شده شروع می‌کنم
11🔥1🍓1
انقدر از پست قبلی لاراول می‌گذره که یادم نبود کجای بحث بودیم.
بعد یک دوساعتی دیدم که از ولیدیشن‌ها همه چیز رو گفتم و صرفا Ruleها باقی مونده که به خودتون و داکیومنت می‌سپارم، چون واقعا تعدادشون زیاد هست و مناسب پست نوشتن نیست.

درنتیجه وارد فصل 7 می‌شیم، مبحث Dependency Injection و Services که بحث مورد علاقه‌م هم هست.

از این فصل به بعد دیگه مباحث حرفه‌ای لاراول به حساب میاد.

پستش رو می‌نویسم و تا یک ساعت دیگه ارسال می‌کنم🤝
12🙉2🍓1
فصل هفت - Services و Dependency Injection

بخش اول - سرویس کانتینر


‏Service Container (IoC Container) یکی از قدرتمندترین ابزارها در لاراول هست، وظیفه این سرویس قدرتمند Dependency Injection و Inversion of Control می‌باشد.

یعنی اگر کلاسی نیاز به یک سرویس یا کلاس دیگه‌ای داشته باشه، لاراول به کمک سرویس کانتینر خودش اون نیاز رو براش فراهم می‌کنه.

همونطور که گفته شد لاراول به صورت خودکار کلاس‌هایی که وابستگی ندارن، یا فقط به کلاس‌های کامل (concrete) وابسته‌ان رو بدون نیاز به تنظیم دستی و به صورت خودکار resolve بکنه. مثلا:
Route::get('/', function (Service $service) {
dd($service::class);
});

وقتی یک کلاس ساده مثل Service به صورت type-hint تعریف شده باشه، کانتینر خودش اون رو instantiate و inject می‌کنه بدون این که ما جای دیگه‌ای مشخص کنیم.

اما همه این دپندنسی ها به صورت خودکار فراهم نمی‌شوند، به همین دلیل Service Providerها به کمک ما می‌آیند.
لاراول به صورت پیشفرض یک پروایدر در مسیر App\Providers\AppServiceProvider.php دارد، شما نیز می‌توانید پروایدرهای خود را با دستور زیر در همین مسیر ایجاد کنید:
php artisan make:provider MyServiceProvider


گفته شد که لاراول همیشه نمی‌تواند یک سرویس را بدون تنظیم قبلی inject کند. اما در چه زمان هایی؟

1- وقتی برای یک interface چند پیاده سازی داریم و می‌خواهیم مشخص کنیم که لاراول از کدام پیاده‌سازی استفاده کند.
2- وقتی که یک پکیج برای لاراول توسعه داده‌ایم و می‌خواهیم سرویس‌هایی تعریف کنیم.

در این موارد کافی است در یکی از متدهای boot یا register (بسته به نیاز که بعدا توضیح داده می‌شود) در سرویس پروایدر خود آن پیاده‌سازی را به کانتینر bind کنیم:
$this->app->bind(Transistor::class, function (Application $app) {
return new Transistor($app->make(PodcastParser::class));
});

در این کد گفته شده زمانی که Transistor نیاز شود، کالبک اجرا شود و یک نمونه از کلاس Transistor ایجاد و به کانتینر اضافه کند.

انواع binding

1- ‏bind
این نوع از binding در مثال قبل گفته شد. و در هر بار درخواست یک سرویس، یک نمونه جدید از آن را ایجاد می‌کند.

2- ‏singleton
همانطور که از نامش پیداست، تنها یک نمونه از کلاس را می‌سازد و در هر درخواست سرویس، از نمونه ایجاد شده قبلی استفاده می‌کند:
$this->app->singleton('RedisClient', function () {
return new RedisClient(config('redis'));
});


3- ‏instance
زمانی استفاده می‌شود که خودمان یک instance آماده از یک آبجکت داشته باشیم و بخواهیم آن را به کانتینر bind کنیم:
$logger = new \App\Services\CustomLogger();
$this->app->‏instance('logger', $logger);


4- ‏scoped
در اپ‌هایی که هر request (یا queue job) باید نسخه جداگانه‌ای از کلاس داشته باشند ولی در همون request بین کلاس‌ها مشترک باشند.
این نوع برای stateful کردن کلاس‌هایی مثل کانکشن دیتابیس بسیار مهم است.
$this->app->scoped(MyService::class, function ($app) {
return new MyService(now());
});

در پروژه‌های Laravel Octane یا اپ‌های multi-tenant یا زمانی که Queue Jobها به ایزولاسیون نیاز دارن کاربرد دارد.

5- ‏bindIf
فقط زمانی bind رو انجام میده که کلاس یا کلیدی با اون نام bind نشده باشه:
$this->app->bindIf(SomeInterface::class, DefaultImplementation::class);


6- ‏singletonIf
مشابه bindIf عمل خواهد کرد با این تفاوت که نمونه‌ای که ایجاد می‌کند از نوع singleton خواهد بود.

7- ‏scopedIf
مشابه bindIf و ‏singletonIf برای scoped bindigها.

‏Interface Binding
ما می‌توانیم مشخص کنیم که وقتی یک کلاس خاص (یا Interface) خواسته شد، چه پیاده‌سازی (concrete class) برایش استفاده شود.
فرض کنید:
interface PaymentGateway {
public function charge($amount);
}

class StripeGateway implements PaymentGateway {
public function charge($amount) {
//
}
}

در این صورت کافی است در سراسر برنامه از PaymentGateway استفاده کنیم و لاراول خودش تصمیم می‌گیرد چه چیز را inject کند.
برای این کار کافی است در سرویس پروایدر خود به صورت زیر عمل کنیم:
$this->app->bind(PaymentGateway::class, StripeGateway::class);

در این صورت اگر PaymentGateway نیاز شود، یک نمونه از StripeGateway ساخته و inject می‌شود.

در قسمت‌های بعدی با سایر Injectionها آشنا خواهیم شد.

#laravel #لاراول #فصل_۷
@AmirhDeveloper
.
🔥5🙉21🍓1
بعد از ۱۳ ماه تلاش، 🎉 LaraGram 3 منتشر شد!

در این نسخه به یک ورژن پایدار رسیدیم که دیگه قرار نیست تغییرات ساختاری یا سینتکسی داشته باشیم.

فیچرهای زیادی اضافه شده که توسعه ربات رو به ساده‌ترین شکل ممکن می‌رسونه 🚀
در ادامه، یه توضیح کوتاه از قابلیت‌های مهم نسخه جدید می‌بینید:

🔐 سیستم کنترل مجوز با قابلیت تعریف Gate و Policy (برای کنترل دسترسی به عملیات‌های پایگاه‌داده)

🧠 سیستم کشینگ با پشتیبانی از ۷ درایور مختلف برای ذخیره داده‌های موقتی
📋 همچنین، Step Manager بر پایه همین سیستم پیاده‌سازی شده

🔁 کالکشن‌ها برای کار حرفه‌ای و راحت با Iterable‌ها

⚙️ سیستم Concurrency برای پردازش همزمان چند درخواست در پس‌زمینه

⚙️ بهبود سیستم کانفیگ و اضافه شدن فایل .env برای مدیریت بهتر تنظیمات

💻 کرنل کنسول برای ایجاد و اجرای راحت کامندها، به‌علاوه زمان‌بندی اجرای تسک‌ها

📦 بازنویسی کامل Eloquent ORM به صورت اختصاصی با پشتیبانی از ۵ دیتابیس مختلف و انواع روابط
📐 همراه با قابلیت‌های Migrations، Seeders و Factory

🔒 سیستم‌های Crypt و Hash برای رمزنگاری

📢 Event Dispatcher برای تعریف و مدیریت رویدادها

📁 سیستم File برای کار با فایل‌ها و پوشه‌ها

🎛 بهبود چشم‌گیر در کیبورد بیلدر و سهولت استفاده

🧭 سیستم Listening الهام‌گرفته از Routing لاراول با امکاناتی مثل:
▪️ پردازش ورودی‌ها
▫️ ایجاد گروه و کنترلر
▪️ اعمال محدودیت و Middleware
▫️ ریدایرکت بین بخش‌ها
▪️ نام‌گذاری مسیرها
▫️ و...

📝 سیستم Log برای ثبت لاگ‌ها با درایورهای متنوع

📨 سیستم Queue و Job برای ایجاد صف و زمان‌بندی اجرای کارها

🧰 اینترفیس جامع Redis با پشتیبانی کامل

🧬 پردازش هر درخواست در یک Pipeline مستقل برای کنترل بهتر

🧩 موتور قالب‌سازی پیشرفته الهام‌گرفته از Blade برای ساخت پیام‌ها

🌍 سیستم Translation برای ساخت ربات‌های چندزبانه

سیستم اعتبارسنجی داده‌ها با قوانین متنوع و قابلیت تعریف Rule سفارشی

🤖 امکان تعریف چندین کانکشن و مدیریت هم‌زمان چند ربات

🧹 امکان کش کردن کانفیگ‌ها، لیسنرها، ایونت‌ها، تمپلیت‌ها، سرویس‌ها و پکیج‌ها برای بهبود عملکرد ربات

و اما معرفی دو پکیج قدرتمند و جذاب:


‌‏🗓 Tempora: مشابه Carbon برای کار با تاریخ و زمان، به صورت چندزبانه و بازنویسی‌شده اختصاصی برای LaraGram

⚡️ LaraGram Surge: مشابه Octane برای اجرای ربات بر پایه Swoole و OpenSwoole
(و به‌زودی با پشتیبانی از RoadRunner و FrankenPHP!)

در آینده‌ای نزدیک LaraGram Installer برای ایجاد حرفه‌ای تر پروژه و همچنین پشتیبانی از MongoDB را نیز خواهیم داشت.

اگر خوشتون اومد، لطفاً به پروژه ⭐️ بدید، به دوستاتون معرفی کنید و حمایتتون رو نشون بدید
خودتون استفاده کنید، ایرادی دیدید بگید تا برطرف کنیم
یا حتی بیاید در توسعه کمک کنید ❤️

📌 پروژه در گیت‌هاب:
♦️ LaraGram
🔹 Laraquest
♦️ LaraGram Surge
🔹 Tempora
♦️ Core

@AmirhDeveloper🔰
.
19🍓1
⚜️ پکیج LaraGram Installer به‌طور کامل آماده شده و با استفاده از آن می‌توانید تنها با چند دستور ساده، یک پروژه لاراگرامی کاملاً کانفیگ‌شده ایجاد کنید.

تنها یک‌بار پکیج را به صورت گلوبال نصب کنید:
composer global require laraxgram/installer

پس از نصب، در هر مسیری که باشید، تنها با اجرای دستور زیر:
laragram new

می‌توانید یک پروژه جدید لاراگرامی ایجاد کنید.

این ابزار به‌صورت پیش‌فرض قابلیت‌های زیر را دارد و به‌صورت خودکار برای شما انجام می‌دهد:

🔹 کانفیگ Git
♦️ ساخت ریپازیتوری و Push در GitHub
🔹 تنظیم دیتابیس
♦️ ست‌کردن Webhook
🔹 نصب پکیج LaraGram Surge

در نهایت یک پروژه کاملاً آماده و کانفیگ‌شده در اختیار شما خواهد بود.

——————

📚 مستندات رسمی LaraGram نیز منتشر شده و از طریق لینک زیر در دسترس است:
🔗 laraxgram.github.io

📌 پروژه در گیت‌هاب:
♦️ LaraGram
🔹 Laraquest
♦️ LaraGram Surge
🔹 Tempora
♦️ Core

@AmirhDeveloper
.
5🔥15🍓3👍1
شرمنده یه چند وقتیه سرم خیلی شلوغ شده و خیلی سخت می‌تونم پست بنویسیم
هر وقت هم می‌خوام بنویسم برق می‌ره

برای همینه که دوره لاراول خوابیده، و پست هم زیاد نداریم

و خب سوالم اینه که برای ادامه فعالیت کانال کمیت محتوا رو ترجیح می‌دید یا کیفیت؟
8💔1🍓1🙉1
Forwarded from جادی | Jadi
💌 پیام وارده


جادی عزیزم سلام

ما کمپین رایگان شدن دوره های مکتب‌خونه رو با پیام همدلی در مسیر یادگیری شروع کردیم
۱۰۰ تا دوره تو حوزه های مختلف رو رایگان کردیم
از برنامه نویسی گرفته تا شبکه و هوش مصنوعی و کلی مهارت های نرم و حتی مثلا گیتار و فرانسوی و تعمیر خودرو و غیره
خلاصه بهترین دوره های مکتب‌خونه رو گلچین کردیم و رایگان کردیم تا آدما یادگیریشون رو متوقف نکنند
چون یادگیری باعث رشد همه و حال خوب و حس پیش رفتن و زنده بودن میده

این لینک دوره CEH شماس
https://mktb.me/3w7y/

اگه از کل کمپین هم حمایت کنی ممنونت میشم. هرچقدر آدمای بیشتری ببینن و بیام ازشون استفاده کنند ما حالمون بهتر میشه

این لندینگ همه دوره های رایگان شده س
https://mktb.me/txvk/

کد HAMDELI
7🍓2
پکیج جدیدی برای LaraGram منتشر شد به نام LaraGram MongoDB.

این پکیج به شما این امکان رو میده که از دیتابیس MongoDB با استفاده از Eloquent ORM استفاده کنید. یعنی می‌تونید از مدل‌ها، مایگریشن‌ها، سیدرها و فکتوری‌های Eloquent استفاده کنید.

همچنین تمامی روابط مثل یک به یک و چند به چند برای دیتابیس MongoDB رو شبیه‌سازی می‌کنه و می‌تونید در یک دیتابیس غیررابطه‌ای از روابط استفاده کنید.

از طرفی، درایورهای MongoDB برای سیستم کش و صف‌ها هم در اختیارتون میذاره.

برای نصب و اضافه کردن به پروژه‌تون کافیه این دستور رو اجرا کنید:
composer require laraxgram/mongodb

بعد از اون کافیه کانکشن دیتابیس رو تغییر بدید، بدون نیاز به تغییر در مدل‌ها و کوئری‌ها، دیتابیس به MongoDB تغییر می‌کنه.

گیت‌هاب پروژه هم اینجاست اگر مایل بودید حمایت کنید:
LaraGram MongoDB

@AmirhDeveloper
.
🔥82🍓1
فصل هفت - Services و Dependency Injection

بخش اول - سرویس کانتینر (قسمت دوم)


‏Contextual Binding (وابسته به موقعیت)


وقتی یک کلاس یا اینترفیس در یک زمینه (context) خاص نیاز به یک وابستگی (dependency) داره، از کدوم پیاده‌سازی (implementation) استفاده بشه. این ویژگی به‌ویژه زمانی مفیده که چند کلاس به یک اینترفیس نیاز دارن، اما هرکدوم باید پیاده‌سازی متفاوتی از اون اینترفیس رو دریافت کنن.

فرض کن دو کلاس داریم که هرکدوم به LoggerInterface نیاز دارن:
interface LoggerInterface {
public function log(string $message);
}

class FileLogger implements LoggerInterface {
public function log(string $message) {

}
}

class DatabaseLogger implements LoggerInterface {
public function log(string $message) {

}
}


حالا می‌خواهیم برای هر کلاس پیاده‌سازی متفاوتی از LoggerInterface تزریق کنیم:
$this->app->when(OrderService::class)
->needs(LoggerInterface::class)
->give(FileLogger::class);

$this->app->when(UserService::class)
->needs(LoggerInterface::class)
->give(DatabaseLogger::class);

با این تنظیمات:
در ‏OrderService‏، کلاس FileLogger تزریق میشه.
در UserService‏، کلاس DatabaseLogger تزریق میشه.

‏Binding Primitives

گاهی اوقات ممکنه کلاسی نیاز به تزریق مقادیر ساده‌ای مثل اعداد، رشته‌ها یا آرایه‌ها داشته باشه. در این مواقع، می‌تونیم با استفاده از Contextual Binding، این مقادیر رو به‌صورت دقیق برای هر کلاس یا متد مشخص کنیم.

فرض کن یک کلاس OrderProcessor داریم که به یک مقدار حداکثر تعداد سفارش نیاز داره:
class OrderProcessor {
public function __construct(
protected int $maxOrders
) {}

public function process() {

}
}


برای تزریق مقدار maxOrders، می‌تونیم از needs() و give() استفاده کنیم:
$this->app->when(OrderProcessor::class)
->needs('$maxOrders')
->give(100);


با این کار، هنگام ساخت نمونه‌ای از OrderProcessor، مقدار 100 به‌عنوان maxOrders به سازنده تزریق میشه.

‏Binding Typed Variadics

می‌تونیم متدهایی با پارامترهای متغیر (variadic) و تایپ‌شده داشته باشیم. این ویژگی به ما این امکان رو می‌ده که وابستگی‌هایی با تعداد و نوع مشخص رو به‌صورت دقیق تزریق کنیم.

فرض کن یک کلاس ReportGenerator داریم که به تعدادی فیلتر نیاز داره:
class ReportGenerator {
public function __construct(
protected FilterInterface ...$filters
) {}

public function generate() {

}
}


برای تزریق فیلترها، می‌تونیم از needs() و give() استفاده کنیم:
$this->app->when(ReportGenerator::class)
->needs(FilterInterface::class)
->give(function ($app) {
return [
new DateFilter(),
new StatusFilter(),
];
});


با این کار، هنگام ساخت نمونه‌ای از ReportGenerator، آرایه‌ای از فیلترها به‌عنوان وابستگی‌ها تزریق میشه.


متدهای مرتبط با Contextual Binding

1- متد when
این متد مشخص می‌کنه که binding در چه کلاسی اعمال بشه.

2- متد needs
با این متد مشخص می‌کنیم که کدوم وابستگی نیاز به تزریق داره.

3- متد give
با این متد پیاده‌سازی مورد نظر رو برای وابستگی مشخص می‌کنیم.

4- متد giveConfig
یک متد راحت برای تزریق مقادیر تنظیماتی به کلاس‌هاست، به‌ویژه زمانی که کلاس نیاز به مقادیر ساده (primitive) داره. درواقع نسخه‌ی مخصوص برای give() هست که با config() همخوانی داره.
$this->app->when(PaymentGateway::class)
->needs('$apiKey')
->giveConfig('services.stripe.key');


5- متد giveTagged
برای تزریق تمام instanceهای مرتبط با یک tag به کلاس‌ها یا متدها استفاده میشه. این زمانی مفیده که یک کلاس نیاز به مجموعه‌ای از وابستگی‌ها (مثلاً چندین سرویس، middleware، فیلتر و…) داره.
$this->app->tag([DateFilter::class, StatusFilter::class], 'filters');

$this->app->when(ReportGenerator::class)
->needs('$filters')
->giveTagged('filters');


تمام instanceهای تگ شده با 'filters' رو به $filters تزریق می‌کنه.

نکته: درمورد تگ‌ها در قسمت بعدی توضیح کامل داده می‌شود.

در قسمت‌های بعدی با سایر Injectionها آشنا خواهیم شد.

#laravel #لاراول #فصل_۷
@AmirhDeveloper
.
5🍓1
This media is not supported in your browser
VIEW IN TELEGRAM
| AmirHossein |
دنبال کننده های واقعیش موندن😉🤓
دقیقا
بقیه به لاراول خیانت کردن
🤣1
فصل هفت - Services و Dependency Injection

بخش اول - سرویس کانتینر (قسمت سوم)

‏Contextual Attributes


این قابلیت امکان استفاده از PHP Attributes را در سازنده‌ها و متدها فراهم می‌کند تا تزریق وابستگی‌ها در Service Container به شکل ساده‌تر، شفاف‌تر و قابل خواندن‌تری انجام شود.

این ویژگی در عمل جایگزین بسیاری از مواردی است که پیش‌تر تنها از طریق Contextual Binding (مانند when()->needs()->give()) امکان‌پذیر بود.

فرض کنید در یک کنترلر نیاز دارید از یک دیسک خاص برای ذخیره‌سازی استفاده کنید. پیش‌تر لازم بود این موضوع را در Service Provider تعریف کنید، اما اکنون کافی است از Attribute استفاده نمایید:
use Illuminate\Container\Attributes\Storage;
use Illuminate\Contracts\Filesystem\Filesystem;

class PhotoController extends Controller
{
public function __construct(
#[Storage('local')] protected Filesystem $filesystem
) {}
}


در این مثال، لاراول به‌طور خودکار دیسک با نام local را پیدا کرده و به متغیر $filesystem تزریق می‌کند.

لاراول چندین Attribute داخلی پرکاربرد ارائه کرده است، از جمله:

‏1- ‎#[Storage('disk-name')]
برای تزریق یک دیسک ذخیره‌سازی مشخص.

‏2- ‎#[Config('config.key')]
برای تزریق مستقیم مقادیر پیکربندی.

‏3- ‎#[DB('connection-name')]
برای تزریق یک اتصال پایگاه‌داده خاص.

‏4- ‎#[Auth('guard-name')]
برای تزریق گارد احراز هویت مشخص.

‏5- ‎#[Cache('store-name')]
برای تزریق یک cache store.

‏6- ‎#[Log('channel')]
برای تزریق یک کانال لاگ.

‏7- ‎#[RouteParameter('param')]
برای تزریق پارامترهای مسیر.

‏8- ‎#[Tag('tag-name')]
برای تزریق مجموعه‌ای از سرویس‌های تَگ‌شده.

‏9- ‎#[CurrentUser]
برای تزریق مستقیم کاربر احراز هویت‌شدهٔ فعلی.

مثال:
Route::get('/user', function (#[CurrentUser] User $user) {
return $user;
})->middleware('auth');

در این مثال، Attribute CurrentUser باعث می‌شود که نمونه‌ای از مدل User که معادل کاربر احراز هویت‌شدهٔ جاری است، بدون هیچ کد اضافه‌ای تزریق گردد.

تعریف Attributes سفارشی
در برخی پروژه‌ها ممکن است نیاز به منطق خاصی داشته باشید. در این حالت می‌توانید Attribute سفارشی خود را تعریف کنید.

برای ساخت یک Attribute سفارشی یک کلاس با annotation #[Attribute] تعریف کنید و رابط ContextualAttribute را پیاده‌سازی کنید.
namespace App\Attributes;

use Attribute;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Container\ContextualAttribute;

#[Attribute(Attribute::TARGET_PARAMETER)]
class AppConfig implements ContextualAttribute
{
public function __construct(
public string $key,
public mixed $default = null
) {}

public static function resolve(self $attribute, Container $container)
{
return $container->make('config')->get($attribute->key, $attribute->default);
}
}


نمونه استفاده:
public function __construct(
#[AppConfig('app.name')] protected string $appName
) {}


‏Tagging
در سرویس کانتینر، Tagging این امکان را فراهم می‌کند که چندین کلاس یا binding را تحت یک نام مشترک گروه‌بندی کنید و بعداً همه آن‌ها را با یک فراخوانی ساده دریافت نمایید. این ویژگی به‌ویژه زمانی مفید است که چند پیاده‌سازی از یک interface یا کلاس وجود داشته باشد و بخواهید همه یا تعدادی از آن‌ها را در یک زمان استفاده کنید.
$this->app->bind(SlackMessenger::class, function ($app) {
return new SlackMessenger(/* ... */);
});

$this->app->bind(TwilioMessenger::class, function ($app) {
return new TwilioMessenger(/* ... */);
});

$this->app->tag([SlackMessenger::class, TwilioMessenger::class], 'messengers');

در این مثال، دو کلاس مربوط به پیام‌رسانی با تگ 'messengers' علامت‌گذاری می‌شوند.

در جایی از اپ که نیاز به اجرای عملیات روی همه‌ی پیام‌رسان‌ها دارید:
$messengers = $this->app->tagged('messengers');

تمام instanceهای مربوط به تگ 'messengers' را برمی‌گرداند.

در قسمت‌های بعدی با سایر Injectionها آشنا خواهیم شد.

#laravel #لاراول #فصل_۷
@AmirhDeveloper
.
5🔥2🍓1
Forwarded from </DevLogIR >
📌 سلام به همه‌ی اونایی که شب‌ها با ترمینال خوابشون می‌بره!

اینجا DevLogIR ـه. یه کانال برای اونایی که عاشق کدنویسی‌ان، با لینوکس حال می‌کنن، و از روزمرگی‌های فنی نمی‌ترسن.

من ابوالفضل هستم. اینجا قراره از تجربه‌های واقعی‌م بگم—از باگ‌هایی که دیوونه‌م کردن، از تم‌هایی که دسکتاپم رو خوشگل کردن و از چالش‌هایی که هر هفته خودم رو باهاش تست می‌کنم.

اگه دنبال یه فضای خودمونی، فنی، و الهام‌بخش هستی، خوش اومدی.
هر هفته منتظر یه پست جدید باش—گاهی یه نکته‌ی لینوکسی، گاهی یه کد کوچیک، گاهی یه روایت از دل ترمینال.

#DevLogIR #LinuxLife #CodeAndCoffee@dev_logir
🔥41🍓1
روزتون مبارک ❤️ به امید پیشرفت
1🔥119🍓4
فصل هفت - Services و Dependency Injection

بخش اول - سرویس کانتینر (قسمت چهارم)


‏Extending Bindings‏

گاهی اوقات شما می‌خواهید یک سرویس را که قبلاً در Service Container ثبت (bind) شده است، تغییر دهید یا چیزی به آن اضافه کنید. به جای اینکه کل آن را از نو بنویسید، می‌توانید از متد extend استفاده کنید. این متد به شما اجازه می‌دهد تا سرویس اصلی را دریافت کرده، آن را تغییر دهید و سپس نسخه تغییریافته را برگردانید.
$this->app->singleton(ApiClient::class, function () {
return new ApiClient();
});

$this->app->extend(ApiClient::class, function ($client, $app) {
$client->config['timeout'] = 10;
return $client;
});


‏Resolving

متد make برای دریافت (resolve) یک نمونه از یک کلاس یا اینترفیس از Service Container استفاده می‌شود. هر زمان که شما به یک نمونه از کلاسی که در کانتینر ثبت شده نیاز دارید، می‌توانید از این متد استفاده کنید.
فرض کنید یک کلاس برای مدیریت کاربران دارید.
$this->app->bind('UserManager', function ($app) {
return new UserManager();
});

// Resolving
$userManager = app()->make('UserManager');


تزریق خودکار (Automatic Injection)

لاراول به قدری هوشمند است که می‌تواند وابستگی‌های (dependencies) یک کلاس را به صورت خودکار از روی Type-Hint در سازنده (constructor) یا متدهای آن تشخیص داده و آن‌ها را تزریق کند. این یعنی در اکثر موارد شما نیازی به استفاده از متد make ندارید.

به جای اینکه در مثال قبل به صورت دستی UserManager را make کنیم، می‌توانیم آن را به سازنده کنترلر تزریق کنیم.
public function __construct(UserManager $userManager)
{
$this->userManager = $userManager;
}

در این حالت، لاراول به صورت خودکار UserManager را برای شما make کرده و به عنوان آرگومان به سازنده پاس می‌دهد.

فراخوانی متد و تزریق وابستگی (Method Invocation & Injection)

علاوه بر تزریق وابستگی در سازنده، لاراول می‌تواند وابستگی‌ها را مستقیماً به متدهای کلاس نیز تزریق کند. این قابلیت به خصوص در کنترلرها بسیار مفید است، زمانی که یک وابستگی فقط در یک متد خاص مورد نیاز است.

فرض کنید یک سرویس برای اعتبارسنجی ورودی‌ها دارید که فقط در متد store از آن استفاده می‌کنید.
public function store(Request $request, UserValidator $validator)
{
// Request and UserValidator injected.
}


رویدادهای کانتینر (Container Events)

‏‌‎Service Container هنگام دریافت (resolve) هر آبجکت، یک رویداد (event) را فراخوانی می‌کند. شما می‌توانید به این رویداد گوش دهید تا هر زمان که یک آبجکت خاص از کانتینر گرفته شد، یک عملیات دلخواه را انجام دهید. این قابلیت برای دیباگ کردن یا اضافه کردن منطق‌های خاص بسیار کاربردی است.

فرض کنید می‌خواهیم هر زمان که یک آبجکت از کلاس MyService ساخته شد، یک پیام در لاگ ثبت کنیم.
$this->app->resolving(MyService::class, function ($service, $app) {
Log::info('MyService resolved!');
});

همچنین می‌توانید به تمام resolving ها گوش دهید
$this->app->resolving(function ($object, $app) {
Log::info('Resolved: ' . get_class($object));
});


‏Rebinding

گاهی اوقات شما نیاز دارید تا بعد از اینکه یک سرویس ساخته و استفاده شد، اگر دوباره bind شد، یک عملیات خاص را انجام دهید. برای مثال، فرض کنید یک سرویس دارید که به اطلاعات کاربر لاگین شده وابسته است. وقتی کاربر لاگ اوت کرده و یک کاربر دیگر لاگین می‌کند، شما نیاز دارید که این سرویس با اطلاعات کاربر جدید به‌روزرسانی شود.
$this->app->rebinding('UserData', function ($app, $instance) {
// logic
});


#laravel #لاراول #فصل_۷
@AmirhDeveloper
.
7🍓2
حمایت کنید از کانال بیایم روی 1K بعد 2 سال و خورده‌ای
کلا ۲۰۰ تا ممبر فعال داریم
17
| AmirHossein |
حمایت کنید از کانال بیایم روی 1K بعد 2 سال و خورده‌ای کلا ۲۰۰ تا ممبر فعال داریم
کانال های خودتونم بذارید اینجا
درسته ممبرهام کمه ولی خب
5🍓1
| AmirHossein |
کانال های خودتونم بذارید اینجا درسته ممبرهام کمه ولی خب
کانالتون رو بذارید، ولی در مقابل قرار بود یه حمایتی هم از اینجا بکنید
🍓6🤣3👍21