- سهشنبه 6 آذر 1397 ساعت 20:34
- 5.6.29
- در حال تکمیل
- منقضی شده
مقدمه
سرویس پروویدارها قلب عملیات راهاندازی تمام اپلیکیشنهای لاراول هستند. سرویسهای اپلیکیشنتان و همچنین تمام سرویسهای هسته لاراول توسط سرویس پرووایدرها راهاندازی میشوند.
اما، منظور از "راهاندازی" یا "بوتاسترپینگ" چیست؟ به طور کلی، منظور از بوتاسترپینگ، رجیستر کردن چیزهایی مانند سرویس کانتینر بایندینگها (service container bindings)، اِوِنتلِسِنرها (event listeners)، میدلور (middleware) و حتی روتها (routes) است. سرویسپرووایدرها مکان اصلی پیکربندی اپلیکیشنتان هستند.
اگر فایل config/app.php
که در لاراول گنجانده شده را باز کنید، آرایه providers
را خواهید دید. کلاسهای گنجانده شده در این آرایه، تمامی سرویس پرووایدرهایی هستند که برای اپلیکیشنتان لود خواهند شد. طبیعتا، تعدادی از این پرووایدرها دیفرد (deferred) هستند، بدین معنی که برای تمام ریکوئستها لود نخواهند شد و تنها هنگامی که سرویسی که ارائه میدهند در عمل مورد نیاز باشد، لود میشوند.
در این پست، مروری کلی بر سرویس پرووایدرها خواهیم داشت، در نتیجه نحوه نوشتن و رجیستر کردن سرویس پرووایدرها در اپلیکیشن خود را خواهید آموخت.
نوشتن سرویس پرووایدرها
تمام سرویس پرووایدرها از کلاس Illuminate\Support\ServiceProvider
مشتق میشوند. اغلب سرویس پرووایدرها دارای یک متد register
و یک متد boot
هستند. در بدنه متد register
، تنها باید چیزهایی را به سرویس پرووایدر بایند کنید. هرگز سعی نکنید که هیچ اِوِنت لِسِنر، روت، یا هر بخش دیگری از عملکرد اپلیکیشن را در متد register
، رجیستر کنید.
رابط خط فرمان آرتیزان با استفاده از کامند make:provider
میتواند یک پرووایدر جدید را برای اپلیکیشنتان ایجاد کند:
php artisan make:provider RiakServiceProvider
متد Register
همانطور که قبلا بیان گردید، تنها باید چیزهایی را داخل متد register
، به سرویس کانتینر بایند کنید. هرگز سعی نکنید تا هیچ اِوِنت لِسِنر، روت، یا هر بخش دیگری از عملکرد اپلیکیشن را در متد register
، رجیستر کنید. در غیر اینصورت، ممکن است به صورت غیرمنتظره از سرویسی، قبل از لود شدن سرویس پرووایدر آن استفاده کنید.
بیایید نگاهی به یک سرویس پرووایدر ساده بیندازیم. داخل هر کدام از متدهای سرویس پرووایدرتان، همیشه به پراپرتی $app
دسترسی دارید که امکان دسترسی به سرویس کانتینر را فراهم میکند:
<?php
namespace App\Providers;
use Riak\Connection;
use Illuminate\Support\ServiceProvider;
class RiakServiceProvider extends ServiceProvider
{
/**
* Register bindings in the container.
*
* @return void
*/
public function register()
{
$this->app->singleton(Connection::class, function ($app) {
return new Connection(config('riak'));
});
}
}
در این سرویس پرووایدر تنها متد register
، تعریف شده است و از این متد برای تعریف یک پیادهسازی (implementation) از Riak\Connection
در سرویس کانتینر استفاده میشود. اگر نحوه کار سرویس کانتینر را نمیدانید، داکیومنت آن را مطالعه کنید.
پراپرتیهای bindings
و singletons
اگر سرویس پرووایدرتان بایندینگهای ساده بسیاری را رجیستر کند، ممکن است بخواهید به جای رجیستر کردن دستی تک تک کانتینر بایندینگها، از پراپرتیهای bindings
و singletons
استفاده کنید. هنگامی که سرویس پرووایدری توسط فریمورک لود شود، به صورت اتوماتیک این پراپرتیها را بررسی کرده و بایندینگهای آنها را رجیستر میکند:
<?php
namespace App\Providers;
use App\Contracts\ServerProvider;
use App\Contracts\DowntimeNotifier;
use Illuminate\Support\ServiceProvider;
use App\Services\PingdomDowntimeNotifier;
use App\Services\DigitalOceanServerProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* All of the container bindings that should be registered.
*
* @var array
*/
public $bindings = [
ServerProvider::class => DigitalOceanServerProvider::class,
];
/**
* All of the container singletons that should be registered.
*
* @var array
*/
public $singletons = [
DowntimeNotifier::class => PingdomDowntimeNotifier::class,
];
}
متد Boot
بسیار خب، اما اگر بخواهیم یک ویو کامپوزر را درون سرویس پرووایدرمان رجیستر کنیم، باید چه کاری انجام دهیم؟ این کار باید داخل متد boot
انجام شود. این متد پس از اینکه تمامی سرویس پرووایدرها رجیستر شوند، فراخوانی خواهد شد، به این معنی که به تمامی سرویسهای دیگری که توسط فریمورک رجیستر شدهاند، دسترسی خواهید داشت:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
view()->composer('view', function () {
//
});
}
}
دیپندنسی اینجکشن برای متد Boot
میتوانید وابستگیها را به متد boot
سرویس پرووایدرتان type-hint کنید. سرویس کانتینر به صورت خودکار تمامی دیپندنسیهای مورد نیازتان را اینجکت میکند:
use Illuminate\Contracts\Routing\ResponseFactory;
public function boot(ResponseFactory $response)
{
$response->macro('caps', function ($value) {
//
});
}
رجیستر کردن پرووایدرها
تمامی سرویس پرووایدرها در فایل کانفیگ config/app.php
رجیستر شدهاند. این فایل حاوی آرایه providers
است که لیستی از نام کلاسهای سرویس پرووایدرتان را میتوانید در آن ببینید. به صورت پیشفرض، مجموعهای از سرویس پرووایدرهای هسته لاراول در این آرایه لیست شدهاند. این پرووایدرها، کامپوننتهای هسته لاراول از جمله mailer و queue و cache و سایر کامپوننتها را راهاندازی میکنند.
برای افزودن پرووایدر خود، کد زیر را به این آرایه اضافه کنید:
'providers' => [
// Other Service Providers
App\Providers\ComposerServiceProvider::class,
],
پرووایدرهای دیفر شده
اگر پرووایدرتان تنها بایندینگها را در سرویس کانتینر رجیستر میکند، میتوانید آن را جدا کنید در نتیجه تا زمانی که در عمل به بایندینگهای رجیستر شده نیاز باشد، عملیات رجیستر کردن آن دیفر شود، یعنی به تاخیر افتد. دیفر کردن لودینگِ این قبیل پرووایدرها، پرفورمنس اپلیکیشنتان را بهبود میبخشد، زیرا این سرویس پروایدرها برای هر ریکوئست از filesystem لود نمیشوند.
لاراول لیستی از تمامی سرویسهای ارائه شده توسط سرویس پرووایدرهای دیفر شده را به همراه نام کلاس سرویس پرووایدرشان، کامپایل و ذخیره میکند. سپس، تنها هنگامی که سعی کنید تا یکی از این سرویسها را resolve کنید، لاراول سرویس پرووایدر مربوط به آن سرویس را لود میکند.
برای دیفر کردن عملیات لودینگِ یک پرووایدر، مقدار پراپرتی defer
آن را true
قرار دهید و متد provides
را برای آن تعریف کنید. متد provides
باید سرویس کانتینر بایندینگهای رجیستر شده توسط پرووایدر را برگرداند.
<?php
namespace App\Providers;
use Riak\Connection;
use Illuminate\Support\ServiceProvider;
class RiakServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton(Connection::class, function ($app) {
return new Connection($app['config']['riak']);
});
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [Connection::class];
}
}
سایر پستهای داکیومنت
- پیشگفتار
- Release Notes ترجمه در ورژنهای بعدی
- راهنمای آپگرید ترجمه در ورژنهای بعدی
- Contribution Guide ترجمه در ورژنهای بعدی
- شروع
- نصب
- پیکربندی
- ساختار دایرکتوری ترجمه در ورژنهای بعدی
- Laravel Homestead ترجمه در ورژنهای بعدی
- Laravel Valet ترجمه در ورژنهای بعدی
- دپلویمنت ترجمه در ورژنهای بعدی
- مفاهیم معماری
- چرخه کار ریکوئستها
- Service Container ترجمه در ورژنهای بعدی
- سرویس پرووایدرها
- فسادها ترجمه در ورژنهای بعدی
- Contracts ترجمه در ورژنهای بعدی
- اصول اولیه
- مسیریابی
- میدلور
- حفاظت در مقابل حملات CSRF
- کنترلرها
- HTTP Requests ترجمه در ورژنهای بعدی
- HTTP Responses ترجمه در ورژنهای بعدی
- ویوها
- تولید URL
- HTTP Session ترجمه در ورژنهای بعدی
- Validation ترجمه در ورژنهای بعدی
- Error Handling ترجمه در ورژنهای بعدی
- Logging ترجمه در ورژنهای بعدی
- فرانتاند
- تمپلتهای Blade
- محلیسازی
- JavaScript & CSS Scaffolding ترجمه در ورژنهای بعدی
- Compiling Assets (Laravel Mix) ترجمه در ورژنهای بعدی
- امنیت
- Authentication ترجمه در ورژنهای بعدی
- API Authentication (Passport) ترجمه در ورژنهای بعدی
- Authorization ترجمه در ورژنهای بعدی
- Encryption ترجمه در ورژنهای بعدی
- Hashing ترجمه در ورژنهای بعدی
- Resetting Passwords ترجمه در ورژنهای بعدی
- مباحث عمیقتر
- Artisan Console ترجمه در ورژنهای بعدی
- Broadcasting ترجمه در ورژنهای بعدی
- Cache ترجمه در ورژنهای بعدی
- Collections ترجمه در ورژنهای بعدی
- Events ترجمه در ورژنهای بعدی
- File Storage ترجمه در ورژنهای بعدی
- Helpers ترجمه در ورژنهای بعدی
- Mail ترجمه در ورژنهای بعدی
- Notifications ترجمه در ورژنهای بعدی
- Package Development ترجمه در ورژنهای بعدی
- Queues ترجمه در ورژنهای بعدی
- Task Scheduling ترجمه در ورژنهای بعدی
- دیتابیس
- دیتابیس: شروع ترجمه در ورژنهای بعدی
- Database: Query Builder ترجمه در ورژنهای بعدی
- دیتابیس: صفحهبندی
- دیتابیس: مایگریشن
- دیتابیس: سیدینگ
- Redis ترجمه در ورژنهای بعدی
- Eloquent ORM
- Eloquent: Getting Started ترجمه در ورژنهای بعدی
- Eloquent: Relationships ترجمه در ورژنهای بعدی
- Eloquent: Collections ترجمه در ورژنهای بعدی
- Eloquent: Mutators ترجمه در ورژنهای بعدی
- Eloquent: API Resources ترجمه در ورژنهای بعدی
- Eloquent: Serialization ترجمه در ورژنهای بعدی
- Testing
- Testing: Getting Started ترجمه در ورژنهای بعدی
- HTTP Tests ترجمه در ورژنهای بعدی
- Browser Tests (Laravel Dusk) ترجمه در ورژنهای بعدی
- Database Testing ترجمه در ورژنهای بعدی
- Mocking ترجمه در ورژنهای بعدی
- Official Packages
- Laravel Cashier ترجمه در ورژنهای بعدی
- Envoy Task Runner ترجمه در ورژنهای بعدی
- Laravel Horizon ترجمه در ورژنهای بعدی
- API Authentication (Passport) ترجمه در ورژنهای بعدی
- Laravel Scout ترجمه در ورژنهای بعدی
- Laravel Socialite ترجمه در ورژنهای بعدی