{ Hello Magento 2 }

解决 Magento 2 应用问题,更注重深度挖掘。(ง •̀_•́)ง

0%

如何用 PHP 的反射类实现依赖注入

ReflectionClass 提供关于类的信息,它有什么属性、哪些方法、方法有哪些参数,类文件的路径是什么等等。 我们先定义两个类,然后熟悉下 ReflectionClass 的一些用法。最后我们写一个简单的函数来实现依赖注入。

ReflectionClass 的一些方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<?php

// Class Point
Class Point
{
public $x;
public $y;

public function __construct($x=0, $y=0)
{
$this->x = $x;
$this->y = $y;
}
}

Class Circle
{
// 半径
public $radius;

// 圆心点
public $center;

const PI = 3.14;

public function __construct(
Point $point,
$radius = 1
){
$this->center = $point;
$this->radius = $radius;
}

public function printCenter()
{
printf('center coordinate is (%d, %d)', $this->center->x, $this->center->y);
}

public function area()
{
return self::PI * pow($this->radius, 2);
}

}


// examples
$reflectionClass = new reflectionClass(Circle::class);
var_dump($reflectionClass);

// 反射出类的常量
var_dump($reflectionClass->getConstants());
// 通过反射获取属性
var_dump($reflectionClass->getProperties());
// 反射出类中定义的方法
var_dump($reflectionClass->getMethods());
// 文件路径
var_dump($reflectionClass->getFileName());


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

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

(结果就忽略掉了)

依赖注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<?php

// Class Point
Class Point
{
public $x;
public $y;

public function __construct($x=0, $y=0)
{
$this->x = $x;
$this->y = $y;
}
}

Class Circle
{
// 半径
public $radius;

// 圆心点
public $center;

const PI = 3.14;

public function __construct(
Point $point,
$radius = 1
){
$this->center = $point;
$this->radius = $radius;
}

public function printCenter()
{
printf('center coordinate is (%d, %d)', $this->center->x, $this->center->y);
}

public function area()
{
return self::PI * pow($this->radius, 2);
}

}




// 创建类的常规方法
// $p1 = new Point(2,2);
// $c1 = new Circle($p1, 2);

// $c1->printCenter();
// echo $c1->area();


// dependency injection
function make($className)
{
$reflectionClass = new reflectionClass($className);
$constructor = $reflectionClass->getConstructor();
$parameters = $constructor->getParameters();
$dependencies = getDependencies($parameters);

return $reflectionClass->newInstanceArgs($dependencies);
}

// 依赖解析
function getDependencies($parameters)
{
$dependencies = [];
foreach ($parameters as $parameter) {
$dependency = $parameter->getClass();

// var_dump($dependency);
// 第二个参数 radius 就没有类
if (is_null ($dependency)) {

if ($parameter->isDefaultValueAvailable()) {
$dependencies[] = $parameter->getDefaultValue();
} else {
// 简化的处理
$dependencies[] = '0';
}

} else {
// 递归解析出依赖类的对象
$dependencies[] = make($parameter->getClass()->name);
}
}
return $dependencies;
}

$c2 = make('Circle');
$area = $c2->area();
var_dump($c2, $area);

参考

ReflectionClass php mannual 参考链接