<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國際加速解決方案。 廣告
                # 服務容器 - [簡介](#introduction) - [綁定](#binding) - [綁定基礎](#binding-basics) - [綁定接口至實現](#binding-interfaces-to-implementations) - [情境綁定](#contextual-binding) - [標記](#tagging) - [解析](#resolving) - [Make 方法](#the-make-method) - [自動注入](#automatic-injection) - [容器事件](#container-events) <a name="introduction"></a> ## 簡介 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](/docs/{{version}}/eloquent) 來從數據庫中獲取 user 信息。因為 `UserRepository` 是通過注入獲取,所以我們可以容易地切換為其他實現。當測試應用程序時,我們還可以輕松地 「mock」 ,或創建假的 `UserRepository` 實例。 在構建強大的應用程序,和為 Laravel 核心貢獻代碼時,必須深入理解 Laravel 的服務容器。 <a name="binding"></a> ## 綁定 <a name="binding-basics"></a> ### 綁定基礎 幾乎所有服務容器的綁定都是在 [服務提供者](/docs/{{version}}/providers) 中進行的,所以下面的例子將示范在該情景中使用容器。 > {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); <a name="binding-interfaces-to-implementations"></a> ### 綁定接口至實現 服務容器有一個強大的功能,就是將一個指定接口的實現綁定到接口上。例如,如果我們有一個 `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; } <a name="contextual-binding"></a> ### 情境綁定 有時候,你可能有兩個類使用到相同的接口,但你希望每個類都能注入不同的實現。例如,兩個控制器可能需要依賴不同的 `Illuminate\Contracts\Filesystem\Filesystem` [契約](/docs/{{version}}/contracts) 的實現類。 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'); }); <a name="tagging"></a> ### 標記 有時候,你可能需要解析某個「分類」下的所有綁定。例如,你正在構建一個報表的聚合器,它需要接受不同 `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')); }); <a name="resolving"></a> ## 解析 <a name="the-make-method"></a> #### `make` 方法 你可以在服務容器外使用 `make` 方法來獲得一個實例化的類。它接受你希望解析的類或是接口名稱作為參數: $api = $this->app->make('HelpSpot\API'); 如果你的代碼不能直接使用 `$app` 變量,你可以使用全局的 `resolve` 助手: $api = resolve('HelpSpot\API'); <a name="automatic-injection"></a> #### 自動注入 另外,并且也是重要的,你可以在類的構造函數中對依賴使用「類型提示」,依賴的類將會被容器自動進行解析,包括在 [控制器](/docs/{{version}}/controllers) , [事件監聽器](/docs/{{version}}/events) , [隊列任務](/docs/{{version}}/queues) , [中間件](/docs/{{version}}/middleware) 等地方。 事實上,這也是大部分類被容器解析的方式。 例如,你可以在控制器的構造函數中對應用程序定義的 `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) { // } } <a name="container-events"></a> ## 容器事件 每當服務容器解析一個對象時就會觸發一個事件。你可以使用 `resolving` 方法監聽這個事件: $this->app->resolving(function ($object, $app) { // 解析任何類型的對象時都會調用該方法... }); $this->app->resolving(HelpSpot\API::class, function ($api, $app) { // 解析「HelpSpot\API」類型的對象時調用... }); 如你所見,被解析的對象會被傳遞至回調中,讓你在對象被傳遞到消費者前可以設置任何額外屬性到對象上。 ## 譯者署名 | 用戶名 | 頭像 | 職能 | 簽名 | |---|---|---|---| | [@yangjingqzp](https://phphub.org/users/5742) | <img class="avatar-66 rm-style" src="https://dn-phphub.qbox.me/uploads/avatars/5742_1473308107.jpeg?imageView2/1/w/100/h/100"> | 翻譯 | 大神們請多多指教,[@yangjingqzp](https://github.com/yangjingqzp) at Github |
                  <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>

                              哎呀哎呀视频在线观看