用品

Laravel 中的服務提供者:它們是什麼以及如何在 Laravel 中使用服務提供者

Laravel 服務提供者是應用程序啟動的中心位置。 即laravel核心服務和應用服務、類及其依賴通過提供者推送到服務容器中。 

換句話說,服務提供者就像一個漏斗,通過它我們將“類”燃料倒入名為 Laravel 的引擎的稱為“服務容器”的罐中。

例子

如果我們打開 config/app.php,我們將看到一個名為“provider”的數組

'providers' => [

        /*
        * Laravel Framework Service Providers...
        */
        Illuminate\Auth\AuthServiceProvider::class,
        Illuminate\Broadcasting\BroadcastServiceProvider::class,
        Illuminate\Bus\BusServiceProvider::class,
        Illuminate\Cache\CacheServiceProvider::class,
        Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
        Illuminate\Cookie\CookieServiceProvider::class,
        .
        .
        .
],

這些是laravel一起提供的一些服務提供者,即放在服務容器中的基本服務。

當我 service provider 他們執行了嗎?

如果我們查看文檔 根據請求生命週期 ,以下文件在開始時執行:

  • public/index.php
  • bootstrap/app.php
  • app/Http/Kernel.php 和他的 Middlewares
  • Service Providers: 本文內容

什麼 service provider 他們加載了嗎? 

他們就是那些 defi數組中的尼特斯 config/app.php:

return [
 
    // ... other configuration values
 
    'providers' => [
 
        /*
         * Laravel Framework Service Providers...
         */
        Illuminate\Auth\AuthServiceProvider::class,
        Illuminate\Broadcasting\BroadcastServiceProvider::class,
 
        // ... other framework providers from /vendor
        Illuminate\Validation\ValidationServiceProvider::class,
        Illuminate\View\ViewServiceProvider::class,
 
        /*
         * PUBLIC Service Providers - the ones we mentioned above
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,
 
    ],
 
];

正如我們所見,有一個列表 service provider 在文件夾中不公開 /vendor,我們不應觸摸或修改它們。 我們感興趣的在下面, BroadcastServicerProvider 默認情況下禁用,可能是因為它很少使用。

所有這些服務提供商從上到下運行,重複列表 兩次:

  • 第一次迭代是尋找一個可選的方法 register(),對於(最終)執行在方法之前配置的東西很有用 boot().
  • 第二次迭代執行該方法 boot() 所有供應商。 再次,數組的一個接一個,從上到下 'providers'.
  • 最後,在處理完所有服務提供者之後,Laravel 繼續解析路徑(路由)、運行控制器、使用模板等。

服務提供商 Laravel 預defi尼蒂

I Service Providers 包含在 Laravel 中,所有這些都存在於文件夾中 app/Providers:

  • AppServiceProvider
  • AuthServiceProvider
  • BroadcastServiceProvider
  • EventServiceProvider
  • RouteServiceProvider

它們都是 PHP 類,每個都與自己的主題相關: App, Auth, Broadcasting, Events e Routes. 但它們都有一個共同點:方法 boot().

在該方法中,我們可以編寫與任何這些部分相關的任何代碼: auth, events, route, ETC。 換句話說,服務提供者只是註冊一些全局功能的類。

它們作為“提供者”是分開的,因為它們在應用程序生命週期的早期運行,所以在執行腳本到達模型或控制器之前,全局的東西在這裡很方便。

大多數功能都在 RouteServiceProvider 中,這裡是代碼:

class RouteServiceProvider extends ServiceProvider
{
    public const HOME = '/dashboard';
 
    public function boot()
    {
        $this->configureRateLimiting();
 
        $this->routes(function () {
            Route::prefix('api')
                ->middleware('api')
                ->group(base_path('routes/api.php'));
 
            Route::middleware('web')
                ->group(base_path('routes/web.php'));
        });
    }
 
    protected function configureRateLimiting()
    {
        RateLimiter::for('api', function (Request $request) {
            return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
        });
    }
}

這是配置文件的類 route,帶 routes/web.phproutes/api.php 默認包含defi妮塔。 請注意,對於 API 也有不同的配置: 端點前綴 /api 和中間件 api 對全部 routes.

我們可以編輯 service providers, 不在文件夾中 /vendor. 當您有很多路徑並希望將它們分成特定文件時,可以自定義這些文件。 你創造 routes/auth.php 並將路徑放在那裡,然後在方法中“啟用”該文件 boot() di RouteServiceProvider,加上第三句:

`Route::middleware('web') // or maybe you want another middleware?
    ->group(base_path('routes/auth.php'));

AppServiceProvider 它是空的。 添加代碼的典型示例 AppServiceProvider, 是關於在 Eloquent 中禁用延遲加載。 為此,您只需要 添加兩行 在方法中 boot():

創新通訊
不要錯過有關創新的最重要新聞。 註冊以通過電子郵件接收它們。
// app/Providers/AppServiceProvider.php
use Illuminate\Database\Eloquent\Model;
 
public function boot()
{
    Model::preventLazyLoading(! $this->app->isProduction());
}

如果未加載關係模型,這將引發異常。

創建自己的 service provider 定制

除了預置文件之外defi奈特,我們可以輕鬆創建一個新的 Service Provider,與預主題之外的其他主題相關defi完成為 auth/event/routes.

一個相當典型的例子是視圖配置 Blade. 我們可以創建一個指令 Blade,然後將該代碼添加到方法中 boot() 任何 service provider,包括默認 AppServiceProvider. 現在讓我們創建一個 ViewServiceProvider 分離。

我們可以用這個命令生成它:

php artisan make:provider ViewServiceProvider

這將生成這樣的類defi晚上:

namespace App\Providers;
 
use Illuminate\Support\ServiceProvider;
 
class ViewServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
 
    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

我們可以看到裡面有兩種方法:

註冊()方法

register() 方法允許我們 defi完成我們服務容器的鏈接。 例如,在以下代碼中:

public function register()
{
    $this->app->singleton(my_class, function($app){
        return new MyClass($app);
    });
}

$this->app 是 laravel 中的全局變量,單例類可以通過 app 訪問。

單例是一個特性。 應用此功能時,我們通知應用程序在應用程序中作為參數傳遞的任何類在整個應用程序中都應該只有一個實例。 這意味著 MyClass 將被解析一次並且只有一個實例,可以使用 my_class 變量訪問它。

引導()方法

boot() 方法允許您訪問之前使用 register 方法註冊的所有服務。 然後,您可以使用此方法將整個服務包含在您的應用程序中。

回到前面的例子,讓我們刪除方法 register() 並在 boot() 添加 Blade 指令代碼:

use Illuminate\Support\Facades\Blade;
 
public function boot()
{
    Blade::directive('datetime', function ($expression) {
        return "<?php echo ($expression)->format('m/d/Y H:i'); ?>";
    });
}

的另一個例子 ViewServiceProvider 它涉及 View Composers, 這是片段 來自 Laravel 官方網站 :

use App\View\Composers\ProfileComposer;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
 
class ViewServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // Using class based composers...
        View::composer('profile', ProfileComposer::class);
 
        // Using closure based composers...
        View::composer('dashboard', function ($view) {
            //
        });
    }
}

要運行,必須將此新提供程序添加/註冊到 in provider 數組 config/app.php:

return [
    // ... other configuration values
 
    'providers' => [
 
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,
 
        // Add your provider here
        App\Providers\ViewServiceProvider::class,
    ],
];

Ercole Palmeri

您也可能對。。。有興趣:

創新通訊
不要錯過有關創新的最重要新聞。 註冊以通過電子郵件接收它們。

最近的文章

未來已來:航運業如何徹底改變全球經濟

海軍部門是真正的全球經濟力量,已邁向 150 億美元的市場…

1五月2024

出版商與 OpenAI 簽署協議以規範人工智慧處理的資訊流

上週一,英國《金融時報》宣布與 OpenAI 達成協議。英國《金融時報》授予其世界級新聞報道許可…

30月2024

線上支付:串流服務如何讓您永遠付款

數百萬人為串流媒體服務付費,每月支付訂閱費用。人們普遍認為您...

29月2024

Veeam 為勒索軟體提供最全面的支持,從保護到回應和恢復

Veeam 的 Coveware 將繼續提供網路勒索事件回應服務。 Coveware 將提供取證和修復功能…

23月2024