国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

香港云服务器
服務器之家 - 編程語言 - PHP教程 - 淺析PHP類的反射來實現依賴注入過程

淺析PHP類的反射來實現依賴注入過程

2019-10-22 11:17laozhang PHP教程

這篇文章主要介紹了PHP類的反射來實現依賴注入過程以及相關知識點分享,對此有興趣的朋友跟著小編學習下吧。

PHP具有完整的反射 API,提供了對類、接口、函數、方法和擴展進行逆向工程的能力。通過類的反射提供的能力我們能夠知道類是如何被定義的,它有什么屬性、什么方法、方法都有哪些參數,類文件的路徑是什么等很重要的信息。也正式因為類的反射很多PHP框架才能實現依賴注入自動解決類與類之間的依賴關系,這給我們平時的開發帶來了很大的方便。 本文主要是講解如何利用類的反射來實現依賴注入(Dependency Injection),并不會去逐條講述PHP Reflection里的每一個API,詳細的API參考信息請查閱官方文檔

為了更好地理解,我們通過一個例子來看類的反射,以及如何實現依賴注入。

下面這個類代表了坐標系里的一個點,有兩個屬性橫坐標x和縱坐標y。

01/**
02 * Class Point
03 */
04class Point
05{
06  public $x;
07  public $y;
08 
09  /**
10   * Point constructor.
11   * @param int $x horizontal value of point's coordinate
12   * @param int $y vertical value of point's coordinate
13   */
14  public function __construct($x = 0, $y = 0)
15  {
16    $this->x = $x;
17    $this->y = $y;
18  }
19}

接下來這個類代表圓形,可以看到在它的構造函數里有一個參數是Point類的,即Circle類是依賴與Point類的。

01class Circle
02{
03  /**
04   * @var int
05   */
06  public $radius;//半徑
07 
08  /**
09   * @var Point
10   */
11  public $center;//圓心點
12 
13  const PI = 3.14;
14 
15  public function __construct(Point $point, $radius = 1)
16  {
17    $this->center = $point;
18    $this->radius = $radius;
19  }
20   
21  //打印圓點的坐標
22  public function printCenter()
23  {
24    printf('center coordinate is (%d, %d)', $this->center->x, $this->center->y);
25  }
26 
27  //計算圓形的面積
28  public function area()
29  {
30    return 3.14 * pow($this->radius, 2);
31  }
32}

ReflectionClass

下面我們通過反射來對Circle這個類進行反向工程。

把Circle類的名字傳遞給reflectionClass來實例化一個ReflectionClass類的對象。

1$reflectionClass = new reflectionClass(Circle::class);
2//返回值如下
3object(ReflectionClass)#1 (1) {
4 ["name"]=>
5 string(6) "Circle"
6}

反射出類的常量

1$reflectionClass->getConstants();

返回一個由常量名稱和值構成的關聯數組

1array(1) {
2 ["PI"]=>
3 float(3.14)
4}

通過反射獲取屬性

1$reflectionClass->getProperties();

返回一個由ReflectionProperty對象構成的數組

01array(2) {
02 [0]=>
03 object(ReflectionProperty)#2 (2) {
04  ["name"]=>
05  string(6) "radius"
06  ["class"]=>
07  string(6) "Circle"
08 }
09 [1]=>
10 object(ReflectionProperty)#3 (2) {
11  ["name"]=>
12  string(6) "center"
13  ["class"]=>
14  string(6) "Circle"
15 }
16}

反射出類中定義的方法

1$reflectionClass->getMethods();

返回ReflectionMethod對象構成的數組

01array(3) {
02 [0]=>
03 object(ReflectionMethod)#2 (2) {
04  ["name"]=>
05  string(11) "__construct"
06  ["class"]=>
07  string(6) "Circle"
08 }
09 [1]=>
10 object(ReflectionMethod)#3 (2) {
11  ["name"]=>
12  string(11) "printCenter"
13  ["class"]=>
14  string(6) "Circle"
15 }
16 [2]=>
17 object(ReflectionMethod)#4 (2) {
18  ["name"]=>
19  string(4) "area"
20  ["class"]=>
21  string(6) "Circle"
22 }
23}

我們還可以通過getConstructor()來單獨獲取類的構造方法,其返回值為一個ReflectionMethod對象。

1$constructor = $reflectionClass->getConstructor();

反射出方法的參數

1$parameters = $constructor->getParameters();

其返回值為ReflectionParameter對象構成的數組。

01array(2) {
02 [0]=>
03 object(ReflectionParameter)#3 (1) {
04  ["name"]=>
05  string(5) "point"
06 }
07 [1]=>
08 object(ReflectionParameter)#4 (1) {
09  ["name"]=>
10  string(6) "radius"
11 }
12}

依賴注入

好了接下來我們編寫一個名為make的函數,傳遞類名稱給make函數返回類的對象,在make里它會幫我們注入類的依賴,即在本例中幫我們注入Point對象給Circle類的構造方法。

01//構建類的對象
02function make($className)
03{
04  $reflectionClass = new ReflectionClass($className);
05  $constructor = $reflectionClass->getConstructor();
06  $parameters = $constructor->getParameters();
07  $dependencies = getDependencies($parameters);
08   
09  return $reflectionClass->newInstanceArgs($dependencies);
10}
11 
12//依賴解析
13function getDependencies($parameters)
14{
15  $dependencies = [];
16  foreach($parameters as $parameter) {
17    $dependency = $parameter->getClass();
18    if (is_null($dependency)) {
19      if($parameter->isDefaultValueAvailable()) {
20        $dependencies[] = $parameter->getDefaultValue();
21      } else {
22        //不是可選參數的為了簡單直接賦值為字符串0
23        //針對構造方法的必須參數這個情況
24        //laravel是通過service provider注冊closure到IocContainer,
25        //在closure里可以通過return new Class($param1, $param2)來返回類的實例
26        //然后在make時回調這個closure即可解析出對象
27        //具體細節我會在另一篇文章里面描述
28        $dependencies[] = '0';
29      }
30    } else {
31      //遞歸解析出依賴類的對象
32      $dependencies[] = make($parameter->getClass()->name);
33    }
34  }
35 
36  return $dependencies;
37}

定義好make方法后我們通過它來幫我們實例化Circle類的對象:

01$circle = make('Circle');
02$area = $circle->area();
03/*var_dump($circle, $area);
04object(Circle)#6 (2) {
05 ["radius"]=>
06 int(1)
07 ["center"]=>
08 object(Point)#11 (2) {
09  ["x"]=>
10  int(0)
11  ["y"]=>
12  int(0)
13 }
14}
15float(3.14)*/

通過上面這個實例我簡單描述了一下如何利用PHP類的反射來實現依賴注入,Laravel的依賴注入也是通過這個思路來實現的,只不過設計的更精密大量地利用了閉包回調來應對各種復雜的依賴注入。

源碼分享:https://github.com/kevinyan815/php_reflection_dependency_injection_demo/blob/master/reflection.php

延伸 · 閱讀

精彩推薦
446
主站蜘蛛池模板: 婷婷精品久久久久久久久久不卡 | 99久久夜色精品国产网站 | 日韩欧美精品一区二区三区 | 欧美在线观看一区 | 91精品国产九九九久久久亚洲 | 精品视频在线视频 | 我要看免费黄色片 | 黑人中文字幕一区二区三区 | 亚洲视频三区 | 黄色网日本| 亚洲精品乱码 | 欧美 亚洲 一区 | 九九久久影视 | 日韩精品免费在线视频 | 欧美一级片在线 | 国产一级黄色av | 一区二区三区高清视频在线观看 | 91精品久久久久久久 | 国产欧美日韩一区二区三区四区 | 欧美专区在线 | 一区二区三区四区视频 | 特黄网站 | 欧美jjzz| 久久久精品视频免费观看 | 亚洲视频 欧美视频 | 免费一级电影 | 国产一区二区三区免费在线 | 99久久影院| 久久久美女 | 精品国产精品三级精品av网址 | 成人免费毛片aaaaaa片 | 成人午夜电影在线观看 | 欧美成人福利 | 国产中文字幕一区 | 亚洲欧美久久 | 国产在线观看一区 | 亚洲免费看片 | 亚洲精品国产a久久久久久 99热少妇 | 欧美黄色一区二区 | 亚洲视频中文字幕 | 蜜桃视频一区二区 |