一婿滓、容器與依賴注入的原理
- 任何的URL訪問,最終都是定位到控制器啊研,由控制器中某個具體的方法去執(zhí)行
- 一個控制器對應(yīng)著一個類,如果這些類需要進行統(tǒng)一管理鸥拧,怎么辦党远?
- 容器來進行類管理,還可以將類的實例(對象)作為參數(shù)住涉,傳遞給類方法麸锉,自動觸發(fā)依賴注入
- 依賴注入:將對象類型的數(shù)據(jù)钠绍,以參數(shù)的方式傳到方法的參數(shù)列表
- URL訪問:通過GET方式將數(shù)據(jù)傳到控制器指定的方法中舆声,但是只能傳字符串,數(shù)值
- 如果要傳一個對象到當前方法中柳爽?怎么辦媳握?
- 依賴注入:解決了向類中的方法傳遞對象的問題
依賴注入示例
protected $user;
public function __construct(UserModel $user)
{
$this->user = $user;
}
/* 和上面是等價的
public function __construct(){
$user = new UserModel();
return $user->name;
}
*/
public function hello()
{
return 'Hello,' . $this->user->name . '!';
}
在ThinkPHP
的設(shè)計中磷脯,think\App
類雖然自身不是容器蛾找,但卻是一個容器管理類,可以完成容器的所有操作赵誓。
V5.1.14+
版本開始打毛,應(yīng)用類自身就是一個容器實例柿赊。
這里演示的是通過助手函數(shù)來進行綁定,當然也可以用think\Container
操作
- 調(diào)用和綁定的標識必須保持一致(包括大小寫)
- 你可以綁定一個類到容器中(第一個參數(shù)直接傳入類名)
- 只要調(diào)用過一次后就會自動綁定
- 綁定的類標識可以自己定義(只要不沖突)
容器綁定示例
public function bind()
{
// 綁定類庫標識
bind('user','app\demo\model\UserModel');
// 快速調(diào)用(自動實例化)
$user = app('user');
$user->name = '123';
echo '$user->name , ' . $user->name . '幻枉!<br>';
//容器中已經(jīng)調(diào)用過的類會自動使用單例
//除非你使用下面的方式強制重新實例化碰声。
//每次調(diào)用都會重新實例化
$user = app('user',true);
echo '$user->name , ' . $user->name . '!<br>';
$user = app('user',['帶參數(shù)實例'],true);
echo '$user->name , ' . $user->name . '熬甫!';
}
閉包綁定
/**
* 綁定閉包
* 可以把一個閉包方法綁定到容器中
* \think\Container 方式
*/
public function bindClosure()
{
\think\Container::set('sayHello', function ($name) {
return 'hello,' . $name;
});
return \think\Container::get('sayHello',['name'=>'yuan']);
}
二胰挑、靜態(tài)代理
門面(Facade
)為容器中的類提供了一個靜態(tài)調(diào)用接口,相比于傳統(tǒng)的靜態(tài)方法調(diào)用椿肩,帶來了更好的可測試性和擴展性瞻颂,你可以為任何的非靜態(tài)類庫定義一個Facade
類。
系統(tǒng)已經(jīng)為大部分核心類庫定義了Facade郑象,所以你可以聽過Facade來訪問這些系統(tǒng)類贡这,當然也可以為你的應(yīng)用類庫添加靜態(tài)代理。
靜態(tài)代理示例
創(chuàng)建示例類Facade.php
<?php
namespace app\demo\controller;
// use app\demo\model\UserModel;
class Facade
{
public function index($name='yuan')
{
// $user = new UserModel();
// return $user->sayHello('everyBody');
/**
* 如果靜態(tài)調(diào)用一個動態(tài)方法扣唱,需要給當前的類綁定一個靜態(tài)代理類
*/
return \app\facade\UserModel::sayHello('everyBody');
}
}
創(chuàng)建文件app\facade\UserModel.php
<?php
namespace app\facade;
class UserModel extends \think\Facade
{
protected static function getFacadeClass()
{
return 'app\demo\model\UserModel';
}
}
也可以修改app\facade\UserModel.php
<?php
namespace app\facade;
class UserModel extends \think\Facade
{
}
修改app\demo\controller\Facade.php
<?php
namespace app\demo\controller;
class Facade
{
public function index($name='yuan')
{
/*如果沒有在靜態(tài)代理類中顯示要指定要綁定的類名藕坯,就需要動態(tài)顯示綁定一下
\think\Facade::bind()
*/
\think\Facade::bind('app\facade\UserModel','app\demo\model\UserModel');
return \app\facade\UserModel::sayHello('everyBody');
}
}
打印效果一樣
三、請求對象
- 正常情況下噪沙,控制器不依賴于父類
Controller.php
- 推薦繼承于父類炼彪,可以很方便的使用在父類中封裝好的一些方法和屬性
-
Controller.php
沒有靜態(tài)代理 - 控制器中的輸出,字符串全部用
return
返回正歼,不要用echo
- 如果輸出的是復(fù)雜類型辐马,我們可以用
dump()
函數(shù) - 默認輸出的格式為
html
,可以指定為其他格式json
調(diào)用方式
- 傳統(tǒng)的
new Request
- 靜態(tài)代理:
think\facade\Request
- 依賴注入:
Request $request
- 父類
Controller
中的屬性$request:$this->request
示例代碼
class Controller extends \think\Controller
{
//依賴注入
public function test(Request $request)
{
dump($request->get());
}
//父類屬性
public function test2()
{
dump($this->request->get());
}
//靜態(tài)代理
public function test3()
{
return (json_encode(Request::get()));
}
}
示例效果
返回json
總結(jié)
這一章講了容器/依賴注入/靜態(tài)代理/請求對象
技術(shù)相關(guān)操作局义,
-
ThinkPHP5.1
中使用了注冊樹模式
喜爷,這里的容器就是注冊樹模式,之前講過應(yīng)該很熟悉了萄唇。 -
依賴注入
就是將對象類型的數(shù)據(jù)檩帐,以參數(shù)的方式傳到方法的參數(shù)列表,沒什么高深的東西另萤。 -
靜態(tài)代理
為容器中的類提供了一個靜態(tài)調(diào)用接口湃密,相比于傳統(tǒng)的靜態(tài)方法調(diào)用,帶來了更好的可測試性和擴展性 -
請求對象
介紹了四種方式獲取請求參數(shù)
同時感謝PHP中文網(wǎng) 的教學(xué)資源...
以上均是自學(xué)過程的積累四敞,學(xué)到哪記到哪
原創(chuàng)文章泛源,轉(zhuǎn)載請注明出處,謝謝忿危!