1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types = 1); |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Date: 25.08.2016 |
7
|
|
|
* Time: 14:50 |
8
|
|
|
* |
9
|
|
|
* @author : Korotkov Danila <[email protected]> |
10
|
|
|
* @copyright Copyright (c) 2016, Korotkov Danila |
11
|
|
|
* @license http://www.gnu.org/licenses/gpl.html GNU GPLv3.0 |
12
|
|
|
*/ |
13
|
|
|
|
14
|
|
|
namespace Rudra; |
15
|
|
|
|
16
|
|
|
|
17
|
|
|
use \ReflectionClass; |
18
|
|
|
|
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* Class ContainerInterface |
22
|
|
|
* |
23
|
|
|
* @package Rudra |
24
|
|
|
*/ |
25
|
|
|
class Container implements ContainerInterface |
26
|
|
|
{ |
27
|
|
|
|
28
|
|
|
use ContainerCookieTrait; |
29
|
|
|
use ContainerGlobalsTrait; |
30
|
|
|
use ContainerSessionTrait; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* @var ContainerInterface |
34
|
|
|
*/ |
35
|
|
|
public static $app; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @var array |
39
|
|
|
*/ |
40
|
|
|
protected $objects = []; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @var array |
44
|
|
|
*/ |
45
|
|
|
protected $bind = []; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* @return ContainerInterface |
49
|
|
|
*/ |
50
|
|
|
public static function app(): ContainerInterface |
51
|
|
|
{ |
52
|
|
|
if (!static::$app instanceof static) { |
53
|
|
|
static::$app = new static(); |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
return static::$app; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* @param $app |
61
|
|
|
*/ |
62
|
|
|
public function setServices(array $app): void |
63
|
|
|
{ |
64
|
|
|
foreach ($app['services'] as $name => $service) { |
65
|
|
|
foreach ($app['contracts'] as $interface => $contract) { |
66
|
|
|
$this->setBinding($interface, $contract); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
if (array_key_exists(1, $service)) { |
70
|
|
|
$this->set($name, $service[0], $service[1]); |
71
|
|
|
} else { |
72
|
|
|
$this->set($name, $service[0]); |
73
|
|
|
} |
74
|
|
|
} |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* @param $key |
79
|
|
|
* |
80
|
|
|
* @return mixed |
81
|
|
|
*/ |
82
|
|
|
public function get(string $key = null) |
83
|
|
|
{ |
84
|
|
|
return ($key === null) ? $this->objects : $this->objects[$key]; |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* @param string $key |
89
|
|
|
* @param $object |
90
|
|
|
* @param array $params |
91
|
|
|
* |
92
|
|
|
* @return object|void |
93
|
|
|
*/ |
94
|
|
|
public function set(string $key, $object, $params = null) |
95
|
|
|
{ |
96
|
|
|
if ('raw' == $params) { |
97
|
|
|
return $this->rawSet($key, $object); |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
return $this->iOc($key, $object, $params); |
|
|
|
|
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* @param string $key |
105
|
|
|
* @param $object |
106
|
|
|
*/ |
107
|
|
|
protected function rawSet(string $key, $object) |
108
|
|
|
{ |
109
|
|
|
$this->objects[$key] = $object; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* @param $key |
114
|
|
|
* @param $object |
115
|
|
|
* @param null $params |
116
|
|
|
* |
117
|
|
|
* @return object |
118
|
|
|
*/ |
119
|
|
|
protected function iOc(string $key, $object, $params = null) |
120
|
|
|
{ |
121
|
|
|
$reflection = new ReflectionClass($object); |
122
|
|
|
$constructor = $reflection->getConstructor(); |
123
|
|
|
|
124
|
|
|
if ($constructor) { |
125
|
|
|
if ($constructor->getNumberOfParameters()) { |
126
|
|
|
$paramsIoC = $this->getParamsIoC($constructor, $params); |
127
|
|
|
|
128
|
|
|
return $this->objects[$key] = $reflection->newInstanceArgs($paramsIoC); |
129
|
|
|
} else { |
130
|
|
|
return $this->objects[$key] = new $object; |
131
|
|
|
} |
132
|
|
|
} else { |
133
|
|
|
return $this->objects[$key] = new $object; |
134
|
|
|
} |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* @param $object |
139
|
|
|
* @param null $params |
140
|
|
|
* |
141
|
|
|
* @return object |
142
|
|
|
*/ |
143
|
|
|
public function new($object, $params = null) |
144
|
|
|
{ |
145
|
|
|
$reflection = new ReflectionClass($object); |
146
|
|
|
$constructor = $reflection->getConstructor(); |
147
|
|
|
|
148
|
|
|
if ($constructor) { |
149
|
|
|
if ($constructor->getNumberOfParameters()) { |
150
|
|
|
$paramsIoC = $this->getParamsIoC($constructor, $params); |
151
|
|
|
|
152
|
|
|
return $reflection->newInstanceArgs($paramsIoC); |
153
|
|
|
} else { |
154
|
|
|
return new $object; |
155
|
|
|
} |
156
|
|
|
} else { |
157
|
|
|
return new $object; |
158
|
|
|
} |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
/** |
162
|
|
|
* @param $constructor |
163
|
|
|
* @param $params |
164
|
|
|
* |
165
|
|
|
* @return array |
166
|
|
|
*/ |
167
|
|
|
protected function getParamsIoC($constructor, $params) |
168
|
|
|
{ |
169
|
|
|
$paramsIoC = []; |
170
|
|
|
foreach ($constructor->getParameters() as $key => $value) { |
171
|
|
|
if (isset($value->getClass()->name)) { |
172
|
|
|
$className = $this->getBinding($value->getClass()->name); |
173
|
|
|
$paramsIoC[$key] = (is_object($className)) ? $className : new $className; |
174
|
|
|
} else { |
175
|
|
|
$paramsIoC[$key] = ($value->isDefaultValueAvailable()) |
176
|
|
|
? $value->getDefaultValue() : $params[$value->getName()]; |
177
|
|
|
} |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
return $paramsIoC; |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
/** |
184
|
|
|
* @param $key |
185
|
|
|
* |
186
|
|
|
* @return bool |
187
|
|
|
*/ |
188
|
|
|
public function has(string $key): bool |
189
|
|
|
{ |
190
|
|
|
return isset($this->objects[$key]) ? true : false; |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* @param string $key |
195
|
|
|
* @param string $param |
196
|
|
|
* |
197
|
|
|
* @return mixed |
198
|
|
|
*/ |
199
|
|
|
public function getParam(string $key, string $param) |
200
|
|
|
{ |
201
|
|
|
if ($this->has($key)) { |
202
|
|
|
if (isset($this->get($key)->$param)) { |
203
|
|
|
return $this->get($key)->$param; |
204
|
|
|
} |
205
|
|
|
} |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* @param string $key |
210
|
|
|
* @param string $param |
211
|
|
|
* @param $value |
212
|
|
|
*/ |
213
|
|
|
public function setParam(string $key, string $param, $value): void |
214
|
|
|
{ |
215
|
|
|
if (isset($this->objects[$key])) { |
216
|
|
|
$this->get($key)->$param = $value; |
217
|
|
|
} |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
/** |
221
|
|
|
* @param string $key |
222
|
|
|
* @param string $param |
223
|
|
|
* |
224
|
|
|
* @return bool |
225
|
|
|
*/ |
226
|
|
|
public function hasParam(string $key, string $param) |
227
|
|
|
{ |
228
|
|
|
if ($this->has($key)) { |
229
|
|
|
return isset($this->get($key)->$param) ? true : false; |
230
|
|
|
} |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
/** |
234
|
|
|
* @param string $key |
235
|
|
|
* |
236
|
|
|
* @return mixed|string |
237
|
|
|
*/ |
238
|
|
|
public function getBinding(string $key) |
239
|
|
|
{ |
240
|
|
|
return $this->bind[$key] ?? $key; |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
/** |
244
|
|
|
* @param string $key |
245
|
|
|
* @param $value |
246
|
|
|
*/ |
247
|
|
|
public function setBinding(string $key, $value): void |
248
|
|
|
{ |
249
|
|
|
$this->bind[$key] = $value; |
250
|
|
|
} |
251
|
|
|
} |
252
|
|
|
|
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.