成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

通過實(shí)現(xiàn)依賴注入和路由,構(gòu)建一個(gè)自己的現(xiàn)代化PHP框架

waltr / 2961人閱讀

摘要:依賴注入通過構(gòu)造注入,函數(shù)調(diào)用或者屬性的設(shè)置來提供組件的依賴關(guān)系。這段代碼可以用依賴注入重構(gòu),從而解耦現(xiàn)在我們通過外界給予類的依賴,而不是讓它自己產(chǎn)生依賴的對象。根據(jù)依賴注入的概念,我們的框架實(shí)現(xiàn)了這些特性。

如何提高自己編寫代碼的能力呢?我們首先想到的是閱讀學(xué)習(xí)優(yōu)秀的開源項(xiàng)目,然后寫一個(gè)自己的web框架或類庫組件。作為web開發(fā)者,我們通常都是基于面向?qū)ο驩OP來開發(fā)的,所以面向?qū)ο蟮脑O(shè)計(jì)能力或者說設(shè)計(jì)模式的運(yùn)用能力尤為重要,當(dāng)然還有開發(fā)語言本身特性和基礎(chǔ)的靈活運(yùn)用。

我們可以去閱讀一些優(yōu)秀的開源項(xiàng)目,理解里面的代碼設(shè)計(jì),去學(xué)習(xí)和造輪子來提高自己。

在優(yōu)秀成熟的web framework中,路由和http處理是web框架必不可少的,整個(gè)框架的服務(wù)對象依賴解析也是很重要的,有了依賴注入容器可以實(shí)現(xiàn)類很好的解耦。

依賴注入容器 Dependency Injection Container

先來說下什么是依賴注入,依賴注入是一種允許我們從硬編碼的依賴中解耦出來,從而在運(yùn)行時(shí)或者編譯時(shí)能夠修改的軟件設(shè)計(jì)模式(來自維基百科 Wikipedia)。
依賴注入通過構(gòu)造注入,函數(shù)調(diào)用或者屬性的設(shè)置來提供組件的依賴關(guān)系。

下面的代碼中有一個(gè) Database 的類,它需要一個(gè)適配器來與數(shù)據(jù)庫交互。我們在構(gòu)造函數(shù)里實(shí)例化了適配器,從而產(chǎn)生了耦合。這會(huì)使測試變得很困難,而且 Database 類和適配器耦合的很緊密。

adapter = new MySqlAdapter;
    }
}

class MysqlAdapter {}

這段代碼可以用依賴注入重構(gòu),從而解耦

adapter = $adapter;
    }
}

class MysqlAdapter {}

現(xiàn)在我們通過外界給予 Database 類的依賴,而不是讓它自己產(chǎn)生依賴的對象。我們甚至能用可以接受依賴對象參數(shù)的成員函數(shù)來設(shè)置,或者如果 $adapter 屬性本身是 public的,我們可以直接給它賦值。

根據(jù)依賴注入的概念,我們的框架實(shí)現(xiàn)了這些特性。

Dependency injection Container基于PSR-11規(guī)范實(shí)現(xiàn),使用了PHP的類反射功能,去實(shí)例化類定義的對象依賴。定義類的對象依賴包括3種注入實(shí)現(xiàn)方式:構(gòu)造方法注入(Constructor Injection)、setter方法或?qū)傩宰⑷耄⊿etter Injection)、匿名回調(diào)函數(shù)注入,代碼示例如下:

1.構(gòu)造方法注入(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); // true
2.方法注入(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); // true
3.匿名回調(diào)函數(shù)注入(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
自動(dòng)裝配(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為可選參數(shù) */
$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來由用戶自由擴(kuò)展。

項(xiàng)目地址 https://github.com/parvinShi/...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/30992.html

相關(guān)文章

  • 前端面試題(3)現(xiàn)代技術(shù)

    摘要:什么是單頁面應(yīng)用單頁面應(yīng)用是指用戶在瀏覽器加載單一的頁面,后續(xù)請求都無需再離開此頁目標(biāo)旨在用為用戶提供了更接近本地移動(dòng)或桌面應(yīng)用程序的體驗(yàn)。流程第一次請求時(shí),將導(dǎo)航頁傳輸?shù)娇蛻舳耍溆嗾埱笸ㄟ^獲取數(shù)據(jù)實(shí)現(xiàn)數(shù)據(jù)的傳輸通過或遠(yuǎn)程過程調(diào)用。 什么是單頁面應(yīng)用(SPA)? 單頁面應(yīng)用(SPA)是指用戶在瀏覽器加載單一的HTML頁面,后續(xù)請求都無需再離開此頁 目標(biāo):旨在用為用戶提供了更接近本地...

    EasonTyler 評論0 收藏0
  • 前端面試題(3)現(xiàn)代技術(shù)

    摘要:什么是單頁面應(yīng)用單頁面應(yīng)用是指用戶在瀏覽器加載單一的頁面,后續(xù)請求都無需再離開此頁目標(biāo)旨在用為用戶提供了更接近本地移動(dòng)或桌面應(yīng)用程序的體驗(yàn)。流程第一次請求時(shí),將導(dǎo)航頁傳輸?shù)娇蛻舳?,其余請求通過獲取數(shù)據(jù)實(shí)現(xiàn)數(shù)據(jù)的傳輸通過或遠(yuǎn)程過程調(diào)用。 什么是單頁面應(yīng)用(SPA)? 單頁面應(yīng)用(SPA)是指用戶在瀏覽器加載單一的HTML頁面,后續(xù)請求都無需再離開此頁 目標(biāo):旨在用為用戶提供了更接近本地...

    trigkit4 評論0 收藏0
  • 從0開始構(gòu)建一個(gè)屬于你自己PHP框架

    摘要:如何構(gòu)建一個(gè)自己的框架為什么我們要去構(gòu)建一個(gè)自己的框架可能絕大多數(shù)的人都會(huì)說市面上已經(jīng)那么多的框架了,還造什么輪子。 showImg(https://segmentfault.com/img/bVNg9F?w=500&h=500); 如何構(gòu)建一個(gè)自己的PHP框架 為什么我們要去構(gòu)建一個(gè)自己的PHP框架?可能絕大多數(shù)的人都會(huì)說市面上已經(jīng)那么多的框架了,還造什么輪子?。我的觀點(diǎn)造輪子不是目...

    vpants 評論0 收藏0
  • Laravel中核心概念

    摘要:可以為服務(wù)提供者的方法設(shè)置類型提示。方法將在所有其他服務(wù)提供者均已注冊之后調(diào)用。所有服務(wù)提供者都在配置文件中注冊??梢赃x擇推遲服務(wù)提供者的注冊,直到真正需要注冊綁定時(shí),這樣可以提供應(yīng)用程序的性能。 本文最早發(fā)布于 Rootrl的Blog 導(dǎo)言 Laravel是一款先進(jìn)的現(xiàn)代化框架,里面有一些概念非常重要。在上手Laravel之前,我認(rèn)為先弄懂這些概念是很有必要的。你甚至需要重溫下PHP...

    ddongjian0000 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<