摘要:依賴注入通過構造注入,函數調用或者屬性的設置來提供組件的依賴關系。這段代碼可以用依賴注入重構,從而解耦現在我們通過外界給予類的依賴,而不是讓它自己產生依賴的對象。根據依賴注入的概念,我們的框架實現了這些特性。
如何提高自己編寫代碼的能力呢?我們首先想到的是閱讀學習優秀的開源項目,然后寫一個自己的web框架或類庫組件。作為web開發者,我們通常都是基于面向對象OOP來開發的,所以面向對象的設計能力或者說設計模式的運用能力尤為重要,當然還有開發語言本身特性和基礎的靈活運用。
我們可以去閱讀一些優秀的開源項目,理解里面的代碼設計,去學習和造輪子來提高自己。
在優秀成熟的web framework中,路由和http處理是web框架必不可少的,整個框架的服務對象依賴解析也是很重要的,有了依賴注入容器可以實現類很好的解耦。
依賴注入容器 Dependency Injection Container先來說下什么是依賴注入,依賴注入是一種允許我們從硬編碼的依賴中解耦出來,從而在運行時或者編譯時能夠修改的軟件設計模式(來自維基百科 Wikipedia)。
依賴注入通過構造注入,函數調用或者屬性的設置來提供組件的依賴關系。
下面的代碼中有一個 Database 的類,它需要一個適配器來與數據庫交互。我們在構造函數里實例化了適配器,從而產生了耦合。這會使測試變得很困難,而且 Database 類和適配器耦合的很緊密。
adapter = new MySqlAdapter; } } class MysqlAdapter {}
這段代碼可以用依賴注入重構,從而解耦
adapter = $adapter; } } class MysqlAdapter {}
現在我們通過外界給予 Database 類的依賴,而不是讓它自己產生依賴的對象。我們甚至能用可以接受依賴對象參數的成員函數來設置,或者如果 $adapter 屬性本身是 public的,我們可以直接給它賦值。
根據依賴注入的概念,我們的框架實現了這些特性。
Dependency injection Container基于PSR-11規范實現,使用了PHP的類反射功能,去實例化類定義的對象依賴。定義類的對象依賴包括3種注入實現方式:構造方法注入(Constructor Injection)、setter方法或屬性注入(Setter Injection)、匿名回調函數注入,代碼示例如下:
1.構造方法注入(Constructor Injection)bar = $bar; } } /*class Bar { }*/ class Bar { public $baz; public function __construct(Baz $baz) { $this->baz = $baz; } } class Baz { } $container = new Container; $container->set(Foo::class)->addArguments(Bar::class); $container->set(Bar::class)->addArguments(Baz::class); $foo = $container->get(Foo::class); var_dump($foo, $foo->bar); var_dump($foo instanceof Foo); // true var_dump($foo->bar instanceof Bar); // true var_dump($foo->bar->baz instanceof Baz); // true2.方法注入(Setter Injection)
model = $model; } } class Model { public $pdo; public function setPdo(PDO $pdo) { $this->pdo = $pdo; } } $container = new Container; $container->set(Controller::class)->addArguments(Model::class); $container->set(Model::class)->addInvokeMethod("setPdo", [PDO::class]); $container->set(PDO::class) ->addArguments(["mysql:dbname=test;host=localhost", "root", "111111"]); $controller = $container->get(Controller::class); var_dump($controller instanceof Controller); // true var_dump($controller->model instanceof Model); // true var_dump($controller->model->pdo instanceof PDO); // true3.匿名回調函數注入(Closure callable Injection)
model = $model; } } class Model { public $pdo; public function setPdo(PDO $pdo) { $this->pdo = $pdo; } } $container = new Container; $container->set(Controller::class, function () { $pdo = new PDO("mysql:dbname=test;host=localhost", "root", "111111"); $model = new Model; $model->setPdo($pdo); return new Controller($model); }); $controller = $container->get(Controller::class); var_dump($controller instanceof Controller); // true var_dump($controller->model instanceof Model); // true var_dump($controller->model->pdo instanceof PDO); // true自動裝配(auto wiring)
bar = $bar; $this->baz = $baz; } } class Bar { /** * @var AutoWiringBam */ public $bam; /** * Construct. * * @param AutoWiringBam $bam */ public function __construct(Bam $bam) { $this->bam = $bam; } } class Baz { // .. } class Bam { // .. } $container = new ContainerBuilder; $container = $container->build(); $foo = $container->get(Foo::class); var_dump($foo instanceof Foo); // true var_dump($foo->bar instanceof Bar); // true var_dump($foo->baz instanceof Baz); // true var_dump($foo->bar->bam instanceof Bam); // true路由 Route
再介紹下路由的使用,route可以使用symfony的http foundation組件來處理HTTP請求(http messages)。
get("/articles", function () { return "This is articles list"; }); $router->get("/articles/{id:d+}", function ($id) { return "Article id: " . $id; }); /* title為可選參數 */ $router->get("/articles/{id:d+}[/{title}]", function ($id, $title) { return "Article id: " . $id . ", title: " . $title; }); /*匹配處理路由組*/ $router->group("/articles", function () use ($router) { $router->get("/list", function() { return "This is articles list"; }); $router->get("/detail", function ($id, $title) { return "Article detail id: " . $id . ", title: " . $title; }); }); $request = new Request(); $routeHandler = $router->getRouteHandler(); $response = $routeHandler->handle($request); echo $response;
其它的ORM、cache、filesystem、session、validation等組件可以使用composer來由用戶自由擴展。
項目地址 https://github.com/parvinShi/...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/30992.html
摘要:什么是單頁面應用單頁面應用是指用戶在瀏覽器加載單一的頁面,后續請求都無需再離開此頁目標旨在用為用戶提供了更接近本地移動或桌面應用程序的體驗。流程第一次請求時,將導航頁傳輸到客戶端,其余請求通過獲取數據實現數據的傳輸通過或遠程過程調用。 什么是單頁面應用(SPA)? 單頁面應用(SPA)是指用戶在瀏覽器加載單一的HTML頁面,后續請求都無需再離開此頁 目標:旨在用為用戶提供了更接近本地...
摘要:什么是單頁面應用單頁面應用是指用戶在瀏覽器加載單一的頁面,后續請求都無需再離開此頁目標旨在用為用戶提供了更接近本地移動或桌面應用程序的體驗。流程第一次請求時,將導航頁傳輸到客戶端,其余請求通過獲取數據實現數據的傳輸通過或遠程過程調用。 什么是單頁面應用(SPA)? 單頁面應用(SPA)是指用戶在瀏覽器加載單一的HTML頁面,后續請求都無需再離開此頁 目標:旨在用為用戶提供了更接近本地...
摘要:如何構建一個自己的框架為什么我們要去構建一個自己的框架可能絕大多數的人都會說市面上已經那么多的框架了,還造什么輪子。 showImg(https://segmentfault.com/img/bVNg9F?w=500&h=500); 如何構建一個自己的PHP框架 為什么我們要去構建一個自己的PHP框架?可能絕大多數的人都會說市面上已經那么多的框架了,還造什么輪子?。我的觀點造輪子不是目...
摘要:可以為服務提供者的方法設置類型提示。方法將在所有其他服務提供者均已注冊之后調用。所有服務提供者都在配置文件中注冊。可以選擇推遲服務提供者的注冊,直到真正需要注冊綁定時,這樣可以提供應用程序的性能。 本文最早發布于 Rootrl的Blog 導言 Laravel是一款先進的現代化框架,里面有一些概念非常重要。在上手Laravel之前,我認為先弄懂這些概念是很有必要的。你甚至需要重溫下PHP...
閱讀 1721·2021-11-22 15:33
閱讀 2097·2021-10-08 10:04
閱讀 3549·2021-08-27 13:12
閱讀 3425·2019-08-30 13:06
閱讀 1474·2019-08-29 16:43
閱讀 1399·2019-08-29 16:40
閱讀 790·2019-08-29 16:15
閱讀 2749·2019-08-29 14:13