国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Laravel中的核心概念

ddongjian0000 / 1491人閱讀

摘要:可以為服務提供者的方法設置類型提示。方法將在所有其他服務提供者均已注冊之后調用。所有服務提供者都在配置文件中注冊。可以選擇推遲服務提供者的注冊,直到真正需要注冊綁定時,這樣可以提供應用程序的性能。

本文最早發布于 Rootrl的Blog

導言

Laravel是一款先進的現代化框架,里面有一些概念非常重要。在上手Laravel之前,我認為先弄懂這些概念是很有必要的。你甚至需要重溫下PHP OOP知識。我相信很多人對比如getter setter以及__invoke、__call、__callStatic這些魔術方法甚至this、
self、static這些關鍵字作用都還是很模糊的(我上一個老大喜歡問這種基礎問題,然后答不上來-_-")。

DI & IoC

首先名詞解釋,DI全稱是Dependency injection,依賴注入的意思。而IoC是Inversion of control 控制反轉。

要了解依賴注入和控制反轉,首先我們不得不提到面向對象設計中的五大設計原則:S.O.L.I.D。

S.O.L.I.D - 面向對象五大設計原則

SRP The Single Responsibility Principle 單一責任原則
OCP The Open Closed Principle 開放封閉原則
LSP The Liskov Substitution Principle 里氏替換原則
ISP The Interface Segregation Principle 接口分離原則
DIP The Dependency Inversion Principle 依賴倒置原則

這五種思想原則對我們平常的軟件開發設計非常重要,大家可以具體去了解下。

依賴倒置原則

這里我們重點講下依賴倒置原則:實體必須依靠抽象而不是具體實現。它表示高層次的模塊不應該依賴于低層次的模塊,它們都應該依賴于抽象。

在傳統軟件設計中,我們一般都是上層代碼依賴下層代碼,當下層代碼變動時,我們上層代碼要跟著變動,維護成本比較高。這時我們可以上層定義接口,下層來實現這個接口,從而使得下層依賴于上層,降低耦合度。(PC主板和鼠標鍵盤接口就是一個很好的例子,各數據廠商根據主板上的接口來生產自己的鼠標鍵盤產品,這樣鼠標壞了后我們可以隨便換個符合接口要求的鼠標,而不用修改主板上的什么東西)

控制反轉

上面講的依賴倒置是一種原則,而控制反轉就是實現依賴倒置的一種具體方法。控制反轉核心是把上層(類)所依賴單元的實例化過程交由第三方實現,而類中不允許存在對所依賴單元的實例化語句。舉個例子:

class Comment
{
    ...

    public function afterInsert()
    {
        $notification = new EmailNotification(...);
        $notification->send(...);
    }
}

如上,假如我們在用戶提交評論后通知被評論者,這里通知方式是郵件,而且是直接在類中實例化郵件通知類,這樣代碼耦合度高,如果換個短信通知方式就不得不改這里面代碼,具體好的實現我們下面會講到。

依賴注入

依賴注入是一種設計模式,是一種IoC的具體實現,實現了IoC自然就符合依賴倒置原則。依賴注入的核心思想是把類中所依賴單元的實例化過程放到類外面中去實現,然后把依賴注入進來。常用的依賴注入方式有屬性注入和構造函數注入。比如用構造函數注入解耦上面代碼:

// 通知接口
interface Notifaction
{
    public function send(...);
}


// 短信通知實現通知接口
class SmsNotification implements Notification
{
    public function send(...)
    {
        ...
    }
}

// 評論類
class Comment
{
    ...

    protected $notification;

    public function __construct(Notification $smsNotification)
    {
        $this->notification = $smsNotification;
    }

    public function afterInsert()
    {
        $this->notification->send(...);
    }
}

// 實例化短信通知類
$smsNotification = new SmsNotification(...);

// 通過構造函數方法注入
$comment = new Comment($smsNotification);

...

$comment->save();

這樣,我們先定義Notification接口,里面有個send方法,讓后面的通知者不管是郵件類還是短信類都實現這個接口,然后在外面通過構造函數方式注入進來,這樣就解決了Comment類對具體通知方法的依賴,只要是實現了Notification接口的,都可以通過構造函數傳進來,Comment類完全不用做任何修改。這樣無論對于代碼維護還是單元測試(可以模擬實現一個Notification類),都非常方便。

依賴注入是IoC的一種具體實現,是一種解耦手段。當然IoC不止這一種實現,比如Yii中的Service Locator(服務定位器)

IoC container/DI container

當項目比較大時,就會有許多類似上面評論類和通知類這種依賴關系,整個項目會非常復雜。這時候就需要一個集中的地方來管理這些依賴,我們把它叫IoC container 控制反轉容器,它提供了動態地創建、注入依賴單元、映射依賴關系等功能。這樣可以集中管理依賴關系,也減少很多代碼量。

Service container 服務容器

Laravel官方文檔這樣定義服務容器:Laravel服務容器是用于管理類的依賴和執行依賴注入的工具。

首先,服務容器通過DI依賴注入方式實現了IoC,然后它還支持另一種實現:綁定與解析。

綁定

幾乎所有服務容器綁定操作都是Service provider(服務提供器)中注冊綁定的,服務提供器中可以通過$this->app方式獲取服務容器,然后通過服務容器提供的方法比如$this->app->bind(...)等進行具體服務綁定。類似支持的綁定方式還有:

簡單綁定

綁定單例

綁定實例

綁定初始數據

綁定接口到實現

上下文綁定

標記

擴展綁定

具體可以查看官方文檔:https://laravel.com/docs/5.6/...

解析

綁定后可以從服務容器中解析出對象才能夠使用。解析方法包括:

通過 make 方法,接收一個你想要解析的類或者接口

通過數組方式從容器中解析對象

自動注入

示例

我們先定義一個自己的類

class Foo
{
    public function bar()
    {
        ...
    }
}

我們把Foo類簡單綁定到服務容器:

App::bind("foo", function($app){
    return new Foo();
})

平時在上下文獲取這個實例:

$foo = App::make("foo");    // $foo就是Foo類的實例

當然,這種綁定和解析平時我們在代碼中隨便可以寫到哪里,但是多了的話就亂起來了。所以我開頭說幾乎所有這種依賴服務綁定操作都是在Service provider中進行的。

下面就給大家介紹Service provider。

Service provider 服務提供器

為了讓依賴注入的代碼不至于混亂,Laravel提供了一個服務提供器(Service Provider),它將這些依賴聚集在了一塊,統一申明和管理,讓依賴變得更加容易維護。

下面都是一些抄來的官話、套話(-_-"),大家可以直接跳到代碼示例,后續再查看官方文檔加深理解。

所有服務提供者都需要繼承IlluminateSupportServiceProvider類。大多數服務提供者都包含 register 和 boot 方法。register方法中,只能將事務綁定到服務容器。不應該在register方法中嘗試注冊任何事件監聽器,路由或者任何其他功能。可以為服務提供者的boot方法設置類型提示。服務容器會自動注入需要的任何依賴。boot方法將在所有其他服務提供者均已注冊之后調用。

所有服務提供者都在 config/app.php 配置文件中注冊。可以選擇推遲服務提供者的注冊,直到真正需要注冊綁定時,這樣可以提供應用程序的性能。

示例

上一個示例我們是自己在上下文中隨意定義、獲取。下面我們以服務提供者的方式進行:

use IlluminateSupportServiceProvider;

class FooServiceProvider extends ServiceProvider {

    public function register()
    {
        $this->app->bind("foo", function()
        {
            return new Foo();
        });
    }

}

上面實現了一個Foo的服務提供,我們可以手動注入到上下文中:

App::register("FooServiceProvider");

當然我們更多的是通過配置文件來完成的,在app/config/app.php中的providers數組里面增加一行:

"providers" => [
    …
       ‘FooServiceProvider’,
],

這樣我們可以在上下文中直接獲取實例:

App::make(‘foo’)

當然,我們還可以通過門面方式,更方便的操作Foo類。

Facades 門面

門面實際上是應用了設計模式中的外觀模式:

外觀模式(Facade),他隱藏了系統的復雜性,并向客戶端提供了一個可以訪問系統的接口。這種類型的設計模式屬于結構性模式。為子系統中的一組接口提供了一個統一的訪問接口,這個接口使得子系統更容易被訪問或者使用。

Laravel中隨處可見這些靜態方法的調用:

$value = Cache::get("key");

這些靜態調用實際上調用的并不是靜態方法,而是通過PHP的魔術方法 __callStatic() 將請求轉到了相應的方法上。

比如如果我們看一下 IlluminateSupportFacadesCache 這個類,你會發現類中根本沒有 get 這個靜態方法:

class Cache extends Facade
{
    /**
     * 獲取組件的注冊名稱。
     *
     * @return string
     */
    protected static function getFacadeAccessor() { return "cache"; }
}

這其中的奧秘在基類Facade中:

public static function __callStatic($method, $args)
{
    // 獲取實例
    $instance = static::getFacadeRoot();

    if (!$instance) {
        throw new RuntimeException("A facade root has not been set.");
    }

    // 真正調取對應的方法
    return $instance->$method(...$args);
}

這里面有一個獲取實例的過程,然后去調用具體方法。

示例

接上一個示例,我們平常是通過App::make("foo")來獲取實例,然后再調用具體方法。現在我們通過門面的方式簡化這個流程:

先定義一個門面:

use IlluminateSupportFacadesFacade;

class Foo extends Facade {

    protected static function getFacadeAccessor() { return ‘foo’; }

}

然后我們可以很方便的使用Foo類某個方法:

Foo::bar();
Contracts 契約

Laravel的契約是一組定義框架提供的核心服務的接口。后續針對這個接口可以有多種實現,解耦了具體實現的依賴,在不改變代碼邏輯的情況下獲得更加多態的結果。

比如你只需在配置文件中指明你需要的緩存驅動(redis,memcached,file等),Laravel會自動幫你切換到這種驅動,而不需要你針對某種驅動更改邏輯和代碼。

總結

這些都是些基礎的抽象概念,但是是非常重要的,Laravel中隨處可見這些思想,是一切實現的基石。

學習的過程中基礎是非常重要的,知其然必知其所以然。就像道與術,道是在術之前的,老子說過:”有道無術,術尚可求也,有術無道,止于術“。不過實際中應該是相輔相成的關系,“以道統術,以術得道”。

引用

https://laravel.com/docs/5.6/...
https://laravel-china.org/doc...
http://www.digpage.com/di.html
http://yansu.org/2014/12/06/i...

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/28823.html

相關文章

  • Laravel思維導圖之Laravel核心概念

    摘要:的核心概念包括服務容器服務提供者門面契約。所有服務提供者都需要繼承類。可以為服務提供者的方法設置類型提示。方法將在所有其他服務提供者均已注冊之后調用。同樣會整理成思維導圖的形式以方便記憶與回顧。 showImg(https://segmentfault.com/img/remote/1460000010771201); Laravel 的核心概念包括:服務容器、服務提供者、門面(Fac...

    wthee 評論0 收藏0
  • 深入剖析 Laravel 服務容器

    摘要:劃下重點,服務容器是用于管理類的依賴和執行依賴注入的工具。類的實例化及其依賴的注入,完全由服務容器自動的去完成。 本文首發于 深入剖析 Laravel 服務容器,轉載請注明出處。喜歡的朋友不要吝嗇你們的贊同,謝謝。 之前在 深度挖掘 Laravel 生命周期 一文中,我們有去探究 Laravel 究竟是如何接收 HTTP 請求,又是如何生成響應并最終呈現給用戶的工作原理。 本章將帶領大...

    abson 評論0 收藏0
  • Laravel 深入核心系列教程

    摘要:前言年底了不太忙,最近一段時間也一直在研究,就想寫篇關于比較深一點的教程系列啥的,于是就找到站長給開了寫教程的渠道。優點的就是為藝術家創造的框架,它也是工程化的趨勢。項目維護方便也是事實。如果有遇到問題可以直接在教程下面留言。 前言 年底了不太忙,最近一段時間也一直在研究laravel,就想寫篇關于laravel比較深一點的教程系列啥的,于是就找到站長給開了寫教程的渠道。由于第一次寫,...

    wemall 評論0 收藏0
  • Laravel 5.4 入門系列 13. 終篇: 小白也能看懂的 Laravel 核心概念講解

    摘要:但是服務通常由服務提供者來管理的。小結通過上述的例子,基本上可以理解服務容器和服務提供者的使用。懂得了服務容器和服務提供者,理解門面也就不難了。 自動依賴注入 什么是依賴注入,用大白話將通過類型提示的方式向函數傳遞參數。 實例 1 首先,定義一個類: /routes/web.php class Bar {} 假如我們在其他地方要使用到 Bar 提供的功能(服務),怎么辦,直接傳入參數即...

    BenCHou 評論0 收藏0
  • PHP相關

    摘要:的機器學習庫的機器學習庫,包括算法交叉驗證神經網絡等內容。在即將到來的大會上,她將和大家分享在機器學習領域的全新可能。入門總結入門相關,如安裝配置基本使用等。 基于 Swoole 開發 PHP 擴展 Swoole-1.9.7 增加了一個新特性,可以基于 Swoole 使用 C++ 語言開發擴展模塊,在擴展模塊中可以注冊 PHP 內置函數和類。現在可以基于 Swoole 來編寫 PHP ...

    lewinlee 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<