-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathInteropInvoker.php
66 lines (51 loc) · 1.75 KB
/
InteropInvoker.php
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
<?php
namespace mindplay\walkway;
use Closure;
use Interop\Container\ContainerInterface;
use ReflectionFunction;
/**
* This is an invoker implementation that attempts to resolve parameters directly
* provided first, then attempts to have a dependency injection container resolve
* the argument by type.
*
* This provides integration with a number of DI containers via `container-interop`:
*
* https://github.com/container-interop/container-interop#compatible-projects
*
* To use this, you will need to install the `container-interop/container-interop`
* Composer package.
*/
class InteropInvoker implements InvokerInterface
{
/**
* @var ContainerInterface
*/
protected $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function invoke(Closure $func, array $params)
{
$func_ref = new ReflectionFunction($func);
$param_refs = $func_ref->getParameters();
$args = array();
foreach ($param_refs as $param_ref) {
if (array_key_exists($param_ref->name, $params)) {
$args[] = $params[$param_ref->name];
continue;
}
$argument_type = $param_ref->getClass();
if ($argument_type && $this->container->has($argument_type->name)) {
$args[] = $this->container->get($argument_type->name);
continue;
}
if ($param_ref->isDefaultValueAvailable()) {
$args[] = $param_ref->getDefaultValue();
continue;
}
throw new InvocationException("missing parameter: \${$param_ref->name}", $func);
}
return call_user_func_array($func, $args);
}
}