源碼解析Laravel依賴注入步驟詳解

來源:互聯網
上載者:User
這次給大家帶來源碼解析Laravel依賴注入步驟詳解,源碼解析Laravel依賴注入的注意事項有哪些,下面就是實戰案例,一起來看一下。

前言

眾所周知,php的架構數不勝數,近幾年,一個以優雅著稱的架構,漸漸被國內phper所知道,並且開始使用,但是larave有一個很明顯的缺點就是,他的文檔內容少的可憐。

本文將給大家詳細介紹關於Laravel依賴注入的相關內容,分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹吧。

在 Laravel 的控制器的構造方法或者成員方法,都可以通過類型約束的方式使用依賴注入,如:

public function store(Request $request){ //TODO}

這裡 $request 參數就使用了類型約束,Request 是一個類:\Illuminate\Http\Request,表示參數必須是這個類或子類。

本文通過分析 Laravel 的源碼,看為什麼方法中不需要傳入執行個體就可以直接使用 Request 呢?只是架構自動幫我們執行個體化並傳參了。

1.路由定義

從源頭開始看起,在路由定義檔案中定義了這麼一個路由:

Route::resource('/role', 'Admin\RoleController');

這是一個資源型的路由,Laravel 會自動產生增刪改查的路由入口。

本文開頭的 store 方法就是一個控制器的方法,圖中可見路由定義的 Action 也是:App\Http\Controllers\Admin\RoleController@store

路由方法解析

根據路由定義找到控制器和方法,執行具體的方法在 dispatch 方法中實現。

(檔案:vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php)

public function dispatch(Route $route, $controller, $method){ $parameters = $this->resolveClassMethodDependencies(  $route->parametersWithoutNulls(), $controller, $method );  if (method_exists($controller, 'callAction')) {  return $controller->callAction($method, $parameters); }  return $controller->{$method}(...array_values($parameters));}

首先 resolveClassMethodDependencies 方法,“顧名思義”是根據類的方法參數擷取依賴對象,然後再調用類的方法並把對象參數注入。

如果有多個依賴對象,也會 foreach 依次解析出來作為參數注入。

擷取依賴對象樣本的代碼:

protected function resolveClassMethodDependencies(array $parameters, $instance, $method){ if (! method_exists($instance, $method)) {  return $parameters; }  return $this->resolveMethodDependencies(  $parameters, new ReflectionMethod($instance, $method) );}

這裡重點就是用到了 PHP 的反射,注意 RelectionMethod 方法,它擷取到類的方法參數列表,可以知道參數的類型約束,參數名稱等等。

這裡的 $instance 參數就是 RoleController 控制器類,$method 參數就是方法名稱 strore.

2.擷取依賴對象的樣本

從方法的參數中擷取了依賴對象的約束類型,就可以執行個體化這個依賴的對象。

protected function transformDependency(ReflectionParameter $parameter, $parameters){ $class = $parameter->getClass();  // If the parameter has a type-hinted class, we will check to see if it is already in // the list of parameters. If it is we will just skip it as it is probably a model // binding and we do not want to mess with those; otherwise, we resolve it here. if ($class && ! $this->alreadyInParameters($class->name, $parameters)) {  return $parameter->isDefaultValueAvailable()   ? $parameter->getDefaultValue()   : $this->container->make($class->name); }}

根據類名從容器中擷取對象,這個綁定對象執行個體的過程在服務提供者中先定義和了。

然後把執行個體化的對象傳入到 store 方法中,就可以使用依賴的對象了。

3.關於 PHP 反射

舉個使用 ReflectionMethod 的例子。

class Demo{ private $request; public function store(Request $request) { }}

列印出 new ReflectionMethod(Demo::class, ‘store') 的內容

可以得出這個方法的參數列表,參數的約束類型,如 typeHint,Illuminate\Http\Request.

根據類名可以從容器中擷取一開始通過服務提供者綁定的執行個體。

相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

php資料結構與順序鏈錶鏈式線性表使用詳解

php實現統計二進位內1的個數演算法步驟詳解

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.