This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * (c) Paulus Gandung Prakosa ([email protected]) |
||
5 | */ |
||
6 | |||
7 | namespace DependencyInjection; |
||
8 | |||
9 | use Psr\Container\ContainerInterface; |
||
10 | use DependencyInjection\Exception\ContainerException; |
||
11 | use DependencyInjection\Exception\NotFoundException; |
||
12 | |||
13 | class Container implements \ArrayAccess, ContainerInterface |
||
14 | { |
||
15 | /** |
||
16 | * @var array |
||
17 | */ |
||
18 | private $bindings = []; |
||
19 | |||
20 | /** |
||
21 | * @var array |
||
22 | */ |
||
23 | private $resolved = []; |
||
24 | |||
25 | /** |
||
26 | * @var array |
||
27 | */ |
||
28 | private $aliases = []; |
||
29 | |||
30 | /** |
||
31 | * Resolving all dependencies in the supplied class or object instance constructor. |
||
32 | * |
||
33 | * @param string $instance The class name. |
||
34 | * @param array $parameters List of needed class dependency. |
||
35 | * @return object |
||
36 | */ |
||
37 | public function make($instance, $parameters = []) |
||
38 | { |
||
39 | return $this->resolve($instance, is_array($parameters) ? $parameters |
||
40 | : array_slice(func_get_args(), 1)); |
||
41 | } |
||
42 | |||
43 | /** |
||
44 | * Register a service alias. |
||
45 | * |
||
46 | * @param string $alias The alias name. |
||
47 | * @param string $abstract The class name. |
||
48 | */ |
||
49 | public function register($alias, $abstract) |
||
50 | { |
||
51 | if (!is_string($alias) || !is_string($abstract)) { |
||
52 | throw new \InvalidArgumentException( |
||
53 | sprintf("Parameter 1 and 2 of %s must be a string.", __METHOD__) |
||
54 | ); |
||
55 | } |
||
56 | |||
57 | if (!isset($this->aliases[$alias])) { |
||
58 | $this->aliases[$alias] = $this->make($abstract); |
||
59 | } |
||
60 | |||
61 | return $this; |
||
62 | } |
||
63 | |||
64 | /** |
||
65 | * Determine if registered alias were exists. |
||
66 | * |
||
67 | * @param string $alias The alias name. |
||
68 | */ |
||
69 | public function isAliasExists($alias) |
||
70 | { |
||
71 | return isset($this->aliases[$alias]); |
||
72 | } |
||
73 | |||
74 | /** |
||
75 | * Finds an entry of the container by its identifier and returns it. |
||
76 | * |
||
77 | * @param string $id Identifier of the entry to look for. |
||
78 | * |
||
79 | * @throws NotFoundExceptionInterface No entry was found for **this** identifier. |
||
80 | * @throws ContainerExceptionInterface Error while retrieving the entry. |
||
81 | * |
||
82 | * @return mixed Entry. |
||
83 | */ |
||
84 | public function get($id) |
||
85 | { |
||
86 | if (!$this->isAliasExists($id)) { |
||
87 | throw new NotFoundException( |
||
88 | sprintf("Identifier %s was not found in our service container stack.", $id) |
||
89 | ); |
||
90 | } |
||
91 | |||
92 | return $this->aliases[$id]; |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * Returns true if the container can return an entry for the given identifier. |
||
97 | * Returns false otherwise. |
||
98 | * |
||
99 | * `has($id)` returning true does not mean that `get($id)` will not throw an exception. |
||
100 | * It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`. |
||
101 | * |
||
102 | * @param string $id Identifier of the entry to look for. |
||
103 | * |
||
104 | * @return bool |
||
105 | */ |
||
106 | public function has($id) |
||
107 | { |
||
108 | return $this->isAliasExists($id); |
||
109 | } |
||
110 | |||
111 | /** |
||
112 | * {@inheritdoc} |
||
113 | */ |
||
114 | public function offsetExists($offset) |
||
115 | { |
||
116 | return $this->isBound($offset); |
||
117 | } |
||
118 | |||
119 | /** |
||
120 | * {@inheritdoc} |
||
121 | */ |
||
122 | public function offsetGet($offset) |
||
123 | { |
||
124 | return $this->make($offset); |
||
125 | } |
||
126 | |||
127 | /** |
||
128 | * {@inheritdoc} |
||
129 | */ |
||
130 | public function offsetSet($offset, $value) |
||
131 | { |
||
132 | $this->bind($offset, $value instanceof \Closure ? $value : $this->turnIntoResolvableClosure($offset, $value)); |
||
133 | } |
||
134 | |||
135 | /** |
||
136 | * {@inheritdoc} |
||
137 | */ |
||
138 | public function offsetUnset($offset) |
||
139 | { |
||
140 | unset($this->bindings[$offset], $this->resolved[$offset]); |
||
141 | } |
||
142 | |||
143 | /** |
||
144 | * Determine if defined abstract class name were in resolved concrete stack and it was a |
||
145 | * singleton. |
||
146 | * |
||
147 | * @param string $abstract The resolved abstract class name. |
||
148 | */ |
||
149 | public function hasResolvedSingleton($abstract) |
||
150 | { |
||
151 | $flag = $this->getResolvedConcreteFlag($abstract); |
||
152 | |||
153 | return in_array('singleton', $flag, true); |
||
154 | } |
||
155 | |||
156 | /** |
||
157 | * Get singleton resolved concrete from defined abstract class name. |
||
158 | * |
||
159 | * @param string $abstract The resolved abstract class name. |
||
160 | */ |
||
161 | public function getResolvedSingleton($abstract) |
||
162 | { |
||
163 | return ($this->hasResolvedSingleton($abstract) |
||
164 | ? $this->resolved[$abstract]['concrete'] |
||
165 | : null); |
||
166 | } |
||
167 | |||
168 | /** |
||
169 | * Determine if defined abstract class name were in resolved concrete stack. |
||
170 | * |
||
171 | * @param string $abstract The resolved abstract class name. |
||
172 | */ |
||
173 | public function hasResolvedConcrete($abstract) |
||
174 | { |
||
175 | return isset($this->resolved[$abstract]); |
||
176 | } |
||
177 | |||
178 | /** |
||
179 | * Get flag of resolved concrete behavior on abstract class name. |
||
180 | * |
||
181 | * @param string $abstract The resolved abstract class name. |
||
182 | */ |
||
183 | public function getResolvedConcreteFlag($abstract) |
||
184 | { |
||
185 | if (!$this->hasResolvedConcrete($abstract)) { |
||
186 | throw Internal\Exception\ReflectionExceptionFactory::invalidArgument( |
||
187 | sprintf( |
||
188 | "Parameter 1 of %s must be an abstract class name which exists in resolved concrete stack.", |
||
189 | __METHOD__ |
||
190 | ) |
||
191 | ); |
||
192 | } |
||
193 | |||
194 | return explode('|', $this->resolved[$abstract]['flag']); |
||
195 | } |
||
196 | |||
197 | /** |
||
198 | * Get resolved concrete from defined abstract class name. |
||
199 | * |
||
200 | * @param string $abstract The resolved abstract class name. |
||
201 | */ |
||
202 | public function getResolvedConcrete($abstract) |
||
203 | { |
||
204 | return ($this->hasResolvedConcrete($abstract) |
||
205 | ? $this->resolved[$abstract]['concrete'] |
||
206 | : null); |
||
207 | } |
||
208 | |||
209 | /** |
||
210 | * Get list of unresolved class name from class binding stack. |
||
211 | * |
||
212 | * @return string |
||
213 | */ |
||
214 | protected function getAbstracts() |
||
215 | { |
||
216 | return array_keys($this->bindings); |
||
217 | } |
||
218 | |||
219 | /** |
||
220 | * Determine if unresolved class name is exists. |
||
221 | * |
||
222 | * @param string $abstract The unresolved class name. |
||
223 | * @return bool |
||
224 | */ |
||
225 | public function isAbstractExists($abstract) |
||
226 | { |
||
227 | return array_key_exists($abstract, $this->bindings); |
||
228 | } |
||
229 | |||
230 | /** |
||
231 | * Determine if unresolved abstract is an interface. |
||
232 | * |
||
233 | * @param string $abstract The unresolved abstract name. |
||
234 | */ |
||
235 | public function isInterface($abstract) |
||
236 | { |
||
237 | $reflector = Internal\ReflectionClassFactory::create($abstract); |
||
238 | |||
239 | return $reflector->isInterface(); |
||
240 | } |
||
241 | |||
242 | /** |
||
243 | * Get concrete list of dependencies based on supplied class name. |
||
244 | * |
||
245 | * @param string $abstract The unresolved class name. |
||
246 | * @return array |
||
247 | */ |
||
248 | public function getAbstractDependencies($abstract) |
||
249 | { |
||
250 | return ($this->isAbstractExists($abstract) ? $this->bindings[$abstract] : null); |
||
251 | } |
||
252 | |||
253 | /** |
||
254 | * Resolve class dependencies in the supplied class name. |
||
255 | * |
||
256 | * @param string $instance The class name. |
||
257 | * @param array $parameters The needed class dependency. |
||
258 | * @return object |
||
259 | */ |
||
260 | protected function resolve($instance, $parameters = []) |
||
261 | { |
||
262 | // If the current abstract is an interface, |
||
263 | // just return the concrete implementation to the callee. |
||
264 | if ($this->isInterface($instance)) { |
||
265 | return $this->getConcreteFromInterface($instance); |
||
266 | } |
||
267 | |||
268 | // If the current abstract type being managed as a singleton, |
||
269 | // just return it to the caller instead of reinstantiating it. |
||
270 | try { |
||
271 | return $this->getResolvedSingleton($instance); |
||
272 | } catch (\Exception $e) { |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
![]() |
|||
273 | } |
||
274 | |||
275 | $concrete = $this->getConcrete($instance); |
||
276 | |||
277 | if (!is_null($concrete)) { |
||
278 | $object = $this->build($instance, |
||
279 | $concrete instanceof \Closure ? $concrete($this) : $concrete); |
||
280 | |||
281 | if ($this->isShared($instance)) { |
||
282 | $this->markAsResolved($instance, $object, 'singleton'); |
||
283 | } else { |
||
284 | $this->markAsResolved($instance, $object); |
||
285 | } |
||
286 | } else { |
||
287 | $object = $this->build($instance, $parameters); |
||
288 | } |
||
289 | |||
290 | return $object; |
||
291 | } |
||
292 | |||
293 | protected function build($instance, $parameters = []) |
||
294 | { |
||
295 | $parameters = (is_null($parameters) |
||
296 | ? [] |
||
297 | : (is_array($parameters) |
||
298 | ? $parameters |
||
299 | : array_slice(func_get_args(), 1))); |
||
300 | |||
301 | $reflector = Internal\ReflectionClassFactory::create($instance); |
||
302 | |||
303 | if (!$this->hasConstructor($reflector)) { |
||
304 | return $this->resolveInstanceWithoutConstructor($reflector); |
||
305 | } |
||
306 | |||
307 | if (is_array($parameters) && empty(sizeof($parameters))) { |
||
308 | $constructorParams = $this->getMethodParameters($reflector, '__construct'); |
||
309 | |||
310 | if (!is_null($constructorParams)) { |
||
311 | $params = $this->resolveMethodParameters($constructorParams); |
||
312 | } |
||
313 | } elseif (is_array($parameters) && !empty(sizeof($parameters))) { |
||
314 | $params = $this->resolveMethodParameters($parameters); |
||
315 | } |
||
316 | |||
317 | return $reflector->newInstanceArgs(!empty($parameters) ? $parameters : $params); |
||
0 ignored issues
–
show
The variable
$params does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
318 | } |
||
319 | |||
320 | /** |
||
321 | * Resolve method parameters. |
||
322 | * |
||
323 | * @param array $params The unresolvable method. |
||
324 | * @return array |
||
325 | */ |
||
326 | protected function resolveMethodParameters($params = []) |
||
327 | { |
||
328 | if (!is_array($params)) { |
||
329 | throw new \InvalidArgumentException( |
||
330 | sprintf("Parameter 1 of %s must be an array.", __METHOD__) |
||
331 | ); |
||
332 | } |
||
333 | |||
334 | foreach ($params as $key => $value) { |
||
335 | if ($value instanceof \ReflectionParameter) { |
||
336 | $class = $value->getClass(); |
||
337 | |||
338 | if ($class instanceof \ReflectionClass) { |
||
339 | View Code Duplication | if ($class->isInterface()) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
340 | $params[$key] = $this->getConcreteFromInterface($class->getName()); |
||
0 ignored issues
–
show
![]() |
|||
341 | } else { |
||
342 | $params[$key] = $this->circularDependencyResolver($class->getName()); |
||
0 ignored issues
–
show
![]() |
|||
343 | } |
||
344 | } else { |
||
345 | $params[$key] = ($value->isDefaultValueAvailable() |
||
346 | ? $value->getDefaultValue() : null); |
||
347 | } |
||
348 | } else { |
||
349 | if (is_string($value) && class_exists($value)) { |
||
350 | $params[$key] = $this->circularDependencyResolver($value); |
||
351 | } elseif ($value instanceof \Closure) { |
||
352 | $params[$key] = $value($this); |
||
353 | } else { |
||
354 | $params[$key] = $value; |
||
355 | } |
||
356 | } |
||
357 | } |
||
358 | |||
359 | return $params; |
||
360 | } |
||
361 | |||
362 | /** |
||
363 | * Recursively resolving class dependency. |
||
364 | * |
||
365 | * @param string $class The valid class name. |
||
366 | * @return object |
||
367 | */ |
||
368 | protected function circularDependencyResolver($class) |
||
369 | { |
||
370 | if (!is_string($class) && !class_exists($class)) { |
||
371 | throw Internal\Exception\ReflectionExceptionFactory::invalidArgument( |
||
372 | sprintf("Parameter 1 of %s must be a string of valid class name.", __METHOD__) |
||
373 | ); |
||
374 | } |
||
375 | |||
376 | $reflector = Internal\ReflectionClassFactory::create($class); |
||
377 | |||
378 | if (!$this->hasConstructor($reflector)) { |
||
379 | return $this->resolveInstanceWithoutConstructor($reflector); |
||
380 | } else { |
||
381 | $param = $this->getMethodParameters($reflector, '__construct'); |
||
382 | |||
383 | if (empty($param)) { |
||
384 | return $reflector->newInstance(); |
||
385 | } else { |
||
386 | foreach ($param as $key => $value) { |
||
387 | $class = $value->getClass(); |
||
388 | |||
389 | if ($class instanceof \ReflectionClass) { |
||
390 | View Code Duplication | if ($class->isInterface()) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
391 | $param[$key] = $this->getConcreteFromInterface($class->getName()); |
||
0 ignored issues
–
show
![]() |
|||
392 | } else { |
||
393 | $param[$key] = $this->circularDependencyResolver($class->getName()); |
||
0 ignored issues
–
show
![]() |
|||
394 | } |
||
395 | } |
||
396 | } |
||
397 | |||
398 | return $reflector->newInstanceArgs($param); |
||
399 | } |
||
400 | } |
||
401 | } |
||
402 | |||
403 | /** |
||
404 | * Get concrete implementation from given abstract. |
||
405 | * |
||
406 | * @param string $abstract |
||
407 | * @return \Closure|string|null |
||
408 | */ |
||
409 | public function getConcrete($abstract) |
||
410 | { |
||
411 | return (isset($this->bindings[$abstract]) |
||
412 | ? $this->bindings[$abstract]['concrete'] |
||
413 | : null); |
||
414 | } |
||
415 | |||
416 | /** |
||
417 | * Get concrete implementation from abstract. |
||
418 | * |
||
419 | * @param string $interface The interface name. |
||
420 | * @return object |
||
421 | */ |
||
422 | protected function getConcreteFromInterface($interface) |
||
423 | { |
||
424 | if (!$this->isAbstractExists($interface)) { |
||
425 | throw Internal\Exception\ReflectionExceptionFactory::runtime( |
||
426 | sprintf("%s has no concrete implementation in the class binding stack.", $interface) |
||
427 | ); |
||
428 | } |
||
429 | |||
430 | try { |
||
431 | return $this->getResolvedSingleton($interface); |
||
432 | } catch (\Exception $e) { |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
|
|||
433 | } |
||
434 | |||
435 | $concrete = $this->bindings[$interface]['concrete']; |
||
436 | |||
437 | $object = $concrete instanceof \Closure ? $concrete($this) : $this->build($concrete); |
||
438 | |||
439 | if ($this->isShared($interface)) { |
||
440 | $this->markAsResolved($interface, $object, 'singleton'); |
||
441 | } else { |
||
442 | $this->markAsResolved($interface, $object); |
||
443 | } |
||
444 | |||
445 | return $object; |
||
446 | } |
||
447 | |||
448 | /** |
||
449 | * Determine if current reflection object has constructor. |
||
450 | * |
||
451 | * @param \ReflectionClass $refl The current reflection class object. |
||
452 | * @return boolean |
||
453 | */ |
||
454 | protected function hasConstructor(Internal\ReflectionClassFactory $refl) |
||
455 | { |
||
456 | return $refl->hasMethod('__construct'); |
||
457 | } |
||
458 | |||
459 | /** |
||
460 | * Determine if unresolvable class name has cloneable. |
||
461 | * |
||
462 | * @param \ReflectionClass $refl The current reflection class object. |
||
463 | * @return boolean |
||
464 | */ |
||
465 | protected function isCloneable(Internal\ReflectionClassFactory $refl) |
||
466 | { |
||
467 | return $refl->hasMethod('__clone'); |
||
468 | } |
||
469 | |||
470 | /** |
||
471 | * Determine if unresolvable class name has serializable. |
||
472 | * |
||
473 | * @param \ReflectionClass $refl The current reflection class object. |
||
474 | * @return boolean |
||
475 | */ |
||
476 | protected function isSerializable(Internal\ReflectionClassFactory $refl) |
||
477 | { |
||
478 | return $refl->hasMethod('__sleep'); |
||
479 | } |
||
480 | |||
481 | /** |
||
482 | * Resolving class name without constructor. |
||
483 | * |
||
484 | * @param \ReflectionClass $refl An instance of \ReflectionClass |
||
485 | */ |
||
486 | protected function resolveInstanceWithoutConstructor(Internal\ReflectionClassFactory $refl) |
||
487 | { |
||
488 | return $refl->newInstanceWithoutConstructor(); |
||
489 | } |
||
490 | |||
491 | /** |
||
492 | * Get method parameters. |
||
493 | * |
||
494 | * @param \ReflectionClass $refl An reflection class instance. |
||
495 | * @param string $method The method name. |
||
496 | * @return array |
||
497 | */ |
||
498 | protected function getMethodParameters(Internal\ReflectionClassFactory $refl, $method) |
||
499 | { |
||
500 | return ($refl->hasMethod($method) ? $refl->getMethod($method)->getParameters() : null); |
||
501 | } |
||
502 | |||
503 | /** |
||
504 | * Mark resolved class name to true. |
||
505 | * |
||
506 | * @param string $abstract The resolved class name. |
||
507 | * @param object $resolvedInstance The object instance of resolved abstract. |
||
508 | * @param mixed $flag The concrete-resolving behavior. |
||
509 | * @return void |
||
510 | */ |
||
511 | protected function markAsResolved($abstract, $resolvedInstance, $flag = []) |
||
512 | { |
||
513 | if (!is_array($flag)) { |
||
514 | $flag = array_slice(func_get_args(), 2); |
||
515 | } |
||
516 | |||
517 | if ($this->isAbstractExists($abstract)) { |
||
518 | $this->resolved[$abstract] = [ |
||
519 | 'concrete' => $resolvedInstance, |
||
520 | 'resolved' => true, |
||
521 | 'flag' => join('|', $flag) |
||
522 | ]; |
||
523 | } |
||
524 | } |
||
525 | |||
526 | /** |
||
527 | * Register binding into container stack. |
||
528 | * |
||
529 | * @param string $abstract The unresolvable class name. |
||
530 | * @param \Closure|string $concrete Closure or class name being bound to the class name. |
||
531 | */ |
||
532 | public function bind($abstract, $concrete = null, $shared = false) |
||
533 | { |
||
534 | if (is_null($concrete)) { |
||
535 | $concrete = $abstract; |
||
536 | } |
||
537 | |||
538 | if (!($concrete instanceof \Closure)) { |
||
539 | $concrete = $this->turnIntoResolvableClosure($abstract, $concrete); |
||
540 | } |
||
541 | |||
542 | $this->bindings[$abstract] = compact('concrete', 'shared'); |
||
543 | } |
||
544 | |||
545 | /** |
||
546 | * Register shared binding into container stack. |
||
547 | * |
||
548 | * @param string $abstract The unresolvable abstract |
||
549 | * @param \Closure|string|null The concrete form of supplied abstract. |
||
550 | */ |
||
551 | public function singleton($abstract, $concrete = null) |
||
552 | { |
||
553 | $this->bind($abstract, $concrete, true); |
||
554 | } |
||
555 | |||
556 | /** |
||
557 | * Bind service into binding container stack if supplied class name |
||
558 | * not being bound. |
||
559 | * |
||
560 | * @param string $abstract The unresolvable class name. |
||
561 | * @param \Closure|string $concrete Closure or class name begin bound to the class name. |
||
562 | */ |
||
563 | public function bindIf($abstract, $concrete) |
||
564 | { |
||
565 | if (!$this->isBound($abstract)) { |
||
566 | $this->bind($abstract, $concrete); |
||
567 | } |
||
568 | } |
||
569 | |||
570 | /** |
||
571 | * Call defined instance. |
||
572 | * |
||
573 | * @param string $instance The class name to invoke/call. |
||
574 | * @param array $args The class name __invoke method argument. |
||
575 | * @return mixed|void |
||
576 | */ |
||
577 | public function callInstance($instance, $args = []) |
||
578 | { |
||
579 | $args = (is_array($args) ? $args : array_slice(func_get_args(), 1)); |
||
580 | |||
581 | $current = $this->make($instance); |
||
582 | |||
583 | return call_user_func_array($current, $args); |
||
584 | } |
||
585 | |||
586 | /** |
||
587 | * Determine if class name has been bound or not. |
||
588 | * |
||
589 | * @param string $abstract The unresolvable class name. |
||
590 | * @return bool |
||
591 | */ |
||
592 | public function isBound($abstract) |
||
593 | { |
||
594 | return $this->isAbstractExists($abstract); |
||
595 | } |
||
596 | |||
597 | /** |
||
598 | * Determine if a given type is shared. |
||
599 | * |
||
600 | * @param string $abstract |
||
601 | * @return bool |
||
602 | */ |
||
603 | public function isShared($abstract) |
||
604 | { |
||
605 | if (!isset($this->bindings[$abstract])) { |
||
606 | throw Internal\Exception\ReflectionExceptionFactory::invalidArgument( |
||
607 | sprintf("Parameter 1 of %s must be valid keys in binding container stack.", __METHOD__) |
||
608 | ); |
||
609 | } |
||
610 | |||
611 | return ($this->bindings[$abstract]['shared'] ? true : false); |
||
612 | } |
||
613 | |||
614 | /** |
||
615 | * Turn class name into resolvable closure. |
||
616 | * |
||
617 | * @param string $abstract The class name |
||
618 | * @param \Closure|string $concrete Can be instance of \Closure or class name. |
||
619 | * @return \Closure |
||
620 | */ |
||
621 | protected function turnIntoResolvableClosure($abstract, $concrete) |
||
622 | { |
||
623 | return function (Container $container, $parameters = []) use ($abstract, $concrete) { |
||
624 | return ($abstract == $concrete ? $container->resolve($abstract) |
||
625 | : $container->resolve($concrete, $parameters)); |
||
0 ignored issues
–
show
It seems like
$concrete defined by parameter $concrete on line 621 can also be of type object<Closure> ; however, DependencyInjection\Container::resolve() does only seem to accept string , maybe add an additional type check?
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. ![]() |
|||
626 | }; |
||
627 | } |
||
628 | } |
||
629 |