<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                * * * * * [TOC] ## 簡介 Laravel 服務容器是管理類依賴和運行依賴注入的有力工具。依賴注入是一個花俏的名詞,它實質上是指:類的依賴通過構造器或在某些情況下通過「setter」方法進行「注入」。 來看一個簡單的例子: ~~~ <?php namespace App\Http\Controllers; use App\User; use App\Repositories\UserRepository; use App\Http\Controllers\Controller; class UserController extends Controller { /** * User Repository 的實現。 * * @var UserRepository */ protected $users; /** * 創建新的控制器實例。 * * @param UserRepository $users * @return void */ public function __construct(UserRepository $users) { $this->users = $users; } /** * 顯示指定用戶的詳細信息。 * * @param int $id * @return Response */ public function show($id) { $user = $this->users->find($id); return view('user.profile', ['user' => $user]); } } ~~~ 在這個例子中,控制器?`UserController`?需要從數據源中獲取 users 。因此,我們要?**注入**?可以獲取 users 的服務。在這種情況下,?`UserRepository`?可能是通過使用?[Eloquent](Eloquent 入門.md)?來從數據庫中獲取 user 信息。因為?`UserRepository`?是通過注入獲取,所以我們可以容易地切換為其他實現。當測試應用程序時,我們還可以輕松地 「mock」 ,或創建假的?`UserRepository`?實例。 在構建強大的應用程序,和為 Laravel 核心貢獻代碼時,必須深入理解 Laravel 的服務容器。 ## 綁定 ### 綁定基礎 幾乎所有服務容器的綁定都是在?[服務提供者](服務提供者.md)?中進行的,所以下面的例子將示范在該情景中使用容器。 > {tip} 但是,如果類沒有依賴任何接口,那么就沒有必要將類綁定到容器中了。容器綁定時,并不需要指定如何構建這些類,因為容器中會通過 PHP 的反射自動解析對象。 #### 簡單綁定 在服務提供者中,你經常可以通過?`$this->app`?屬性訪問容器。我們可以通過?`bind`?方法注冊一個綁定,通過傳遞注冊類或接口的名稱、及返回該實例的?`Closure`?作為參數: ~~~ $this->app->bind('HelpSpot\API', function ($app) { return new HelpSpot\API($app->make('HttpClient')); }); ~~~ 注意,我們將獲得的容器本身作為參數傳遞到解析器中,這樣就可以使用容器來解決綁定對象對容器的子依賴。 #### 綁定一個單例 通過?`singleton`?方法可以綁定一個只會被解析一次的類或接口到容器中。且后面的調用都會從容器中返回相同的實例: ~~~ $this->app->singleton('HelpSpot\API', function ($app) { return new HelpSpot\API($app->make('HttpClient')); }); ~~~ #### 綁定實例 你也可以使用?`instance`?方法綁定一個已經存在的對象至容器中。后面的調用都會從容器中返回指定的實例: ~~~ $api = new HelpSpot\API(new HttpClient); $this->app->instance('HelpSpot\Api', $api); ~~~ #### 綁定初始數據 有時,你的類不僅需要注入類,還需要注入一些原始數據,如一個整數。此時,你可以容易地通過情景綁定注入需要的任何值: ~~~ $this->app->when('App\Http\Controllers\UserController') ->needs('$variableName') ->give($value); ~~~ ### 綁定接口至實現 服務容器有一個強大的功能,就是將一個指定接口的實現綁定到接口上。例如,如果我們有一個?`EventPusher`?接口和一個它的實現類?`RedisEventPusher`?。編寫完接口的?`RedisEventPusher`?實現類后,我們就可以在服務容器中像下面例子一樣注冊它: ~~~ $this->app->bind( 'App\Contracts\EventPusher', 'App\Services\RedisEventPusher' ); ~~~ 這么做會告訴容器當一個類需要?`EventPusher`?接口的實例時,?`RedisEventPusher`?的實例將會被容器注入。現在我們就可以在構造函數中,或者任何其他需要通過容器注入依賴的地方,使用?`EventPusher`?接口的類型提示: ~~~ use App\Contracts\EventPusher; /** * Create a new class instance. * * @param EventPusher $pusher * @return void */ public function __construct(EventPusher $pusher) { $this->pusher = $pusher; } ~~~ ### 情境綁定 有時候,你可能有兩個類使用到相同的接口,但你希望每個類都能注入不同的實現。例如,兩個控制器可能需要依賴不同的?`Illuminate\Contracts\Filesystem\Filesystem`?[契約](Contracts.md)?的實現類。 Laravel 為此定義了一種簡單、平滑的接口: ~~~ use Illuminate\Support\Facades\Storage; use App\Http\Controllers\PhotoController; use App\Http\Controllers\VideoController; use Illuminate\Contracts\Filesystem\Filesystem; $this->app->when(PhotoController::class) ->needs(Filesystem::class) ->give(function () { return Storage::disk('local'); }); $this->app->when(VideoController::class) ->needs(Filesystem::class) ->give(function () { return Storage::disk('s3'); }); ~~~ ### 標記 有時候,你可能需要解析某個「分類」下的所有綁定。例如,你正在構建一個報表的聚合器,它需要接受不同?`Report`接口的實例。分別注冊了?`Report`?實例后,你可以使用?`tag`?方法為他們賦予一個標簽: ~~~ $this->app->bind('SpeedReport', function () { // }); $this->app->bind('MemoryReport', function () { // }); $this->app->tag(['SpeedReport', 'MemoryReport'], 'reports'); ~~~ 一旦服務被標記后,你可以通過?`tagged`?方法輕松地將它們全部解析: ~~~ $this->app->bind('ReportAggregator', function ($app) { return new ReportAggregator($app->tagged('reports')); }); ~~~ ## 解析 #### `make`?方法 你可以在服務容器外使用?`make`?方法來獲得一個實例化的類。它接受你希望解析的類或是接口名稱作為參數: ~~~ $api = $this->app->make('HelpSpot\API'); ~~~ 如果你的代碼不能直接使用?`$app`?變量,你可以使用全局的?`resolve`?助手: ~~~ $api = resolve('HelpSpot\API'); ~~~ #### 自動注入 另外,并且也是重要的,你可以在類的構造函數中對依賴使用「類型提示」,依賴的類將會被容器自動進行解析,包括在?[控制器](控制器.md)?,?[事件監聽器](事件系統.md)?,?[隊列任務](隊列.md)?,?[中間件](中間件.md)?等地方。 事實上,這也是大部分類被容器解析的方式。 例如,你可以在控制器的構造函數中對應用程序定義的?`Repository`?使用類型提示。這樣?`Repository`?實例會被自動解析并注入到類中: ~~~ <?php namespace App\Http\Controllers; use App\Users\Repository as UserRepository; class UserController extends Controller { /** * user repository 實例。 */ protected $users; /** * 控制器構造方法。 * * @param UserRepository $users * @return void */ public function __construct(UserRepository $users) { $this->users = $users; } /** * 顯示指定 ID 的用戶信息。 * * @param int $id * @return Response */ public function show($id) { // } } ~~~ ## 容器事件 每當服務容器解析一個對象時就會觸發一個事件。你可以使用?`resolving`?方法監聽這個事件: ~~~ $this->app->resolving(function ($object, $app) { // 解析任何類型的對象時都會調用該方法... }); $this->app->resolving(HelpSpot\API::class, function ($api, $app) { // 解析「HelpSpot\API」類型的對象時調用... }); ~~~ 如你所見,被解析的對象會被傳遞至回調中,讓你在對象被傳遞到消費者前可以設置任何額外屬性到對象上。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看