Passed
Push — master ( 933815...92c16b )
by K
01:46
created

Container::get()   B

Complexity

Conditions 10
Paths 11

Size

Total Lines 47
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 11.7434

Importance

Changes 0
Metric Value
cc 10
eloc 29
nc 11
nop 1
dl 0
loc 47
ccs 20
cts 27
cp 0.7407
crap 11.7434
rs 7.6666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
3
namespace PerfectApp\Container;
4
5
use Closure;
6
use ReflectionClass;
7
use ReflectionException;
8
9
class Container
10
{
11
    private array $instances = [];
12
    private array $bindings = [];
13
14
    /**
15
     * Binds an abstract to a concrete implementation.
16
     *
17
     * @deprecated Will be removed in Version 2. Use set() instead.
18
     */
19 1
    public function bind(string $abstract, mixed $concrete): void
20
    {
21 1
        $this->bindings[$abstract] = $concrete;
22
    }
23
24
    /**
25
     * Sets an abstract to a concrete implementation (alias for bind).
26
     */
27 1
    public function set(string $abstract, mixed $concrete): void
28
    {
29 1
        $this->bindings[$abstract] = $concrete;
30
    }
31
32 5
    public function get(string $className): mixed
33
    {
34 5
        if (isset($this->bindings[$className])) {
35 2
            $concrete = $this->bindings[$className];
36
37 2
            if ($concrete instanceof Closure) {
38
                return $concrete($this);
39
            }
40
41 2
            $className = $concrete;
42
        }
43
44 5
        if (!isset($this->instances[$className])) {
45
            try {
46 5
                $reflectionClass = new ReflectionClass($className);
47
            } catch (ReflectionException $e) {
48
                error_log("Failed to create ReflectionClass for $className: {$e->getMessage()}");
49
                http_response_code(500);
50
                die('Fatal Error. See Error log for details.');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
51
            }
52
53 5
            $constructor = $reflectionClass->getConstructor();
54
55 5
            if ($constructor) {
56 1
                $params = $constructor->getParameters();
57 1
                $dependencies = [];
58
59 1
                foreach ($params as $param) {
60 1
                    $type = $param->getType();
61 1
                    if ($type && !$type->isBuiltin()) {
62 1
                        $dependency = $type->getName();
0 ignored issues
show
Bug introduced by
The method getName() does not exist on ReflectionType. It seems like you code against a sub-type of ReflectionType such as ReflectionNamedType. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

62
                        /** @scrutinizer ignore-call */ 
63
                        $dependency = $type->getName();
Loading history...
63 1
                        $dependencies[] = $this->get($dependency);
64
                    }
65
                }
66
67
                try {
68 1
                    $this->instances[$className] = $reflectionClass->newInstanceArgs($dependencies);
69
                } catch (ReflectionException $e) {
70
                    error_log("Failed to instantiate $className: {$e->getMessage()}");
71 1
                    die('Fatal Error. See Error log for details.');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
72
                }
73
            } else {
74 5
                $this->instances[$className] = new $className();
75
            }
76
        }
77
78 5
        return $this->instances[$className];
79
    }
80
}
81