Passed
Push — master ( b3ed43...d0a90c )
by K
01:52
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 1
    public function bind(string $abstract, mixed $concrete): void
15
    {
16 1
        $this->bindings[$abstract] = $concrete;
17
    }
18
19 4
    public function get(string $className): object
20
    {
21 4
        if (isset($this->bindings[$className])) {
22 1
            $concrete = $this->bindings[$className];
23
24 1
            if ($concrete instanceof Closure) {
25
                return $concrete($this);
26
            }
27
28 1
            $className = $concrete;
29
        }
30
31 4
        if (!isset($this->instances[$className])) {
32
            try {
33 4
                $reflectionClass = new ReflectionClass($className);
34
            } catch (ReflectionException $e) {
35
                error_log("Failed to create ReflectionClass for $className: {$e->getMessage()}");
36
                http_response_code(500);
37
                die('Fatal Error. See Error log for details.');
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return object. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
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...
38
            }
39
40 4
            $constructor = $reflectionClass->getConstructor();
41
42 4
            if ($constructor) {
43 1
                $params = $constructor->getParameters();
44 1
                $dependencies = [];
45
46 1
                foreach ($params as $param) {
47 1
                    $type = $param->getType();
48 1
                    if ($type && !$type->isBuiltin()) {
49 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

49
                        /** @scrutinizer ignore-call */ 
50
                        $dependency = $type->getName();
Loading history...
50 1
                        $dependencies[] = $this->get($dependency);
51
                    }
52
                }
53
54
                try {
55 1
                    $this->instances[$className] = $reflectionClass->newInstanceArgs($dependencies);
56
                } catch (ReflectionException $e) {
57
                    error_log("Failed to instantiate $className: {$e->getMessage()}");
58 1
                    die('Fatal Error. See Error log for details.');
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return object. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
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...
59
                }
60
            } else {
61 4
                $this->instances[$className] = new $className();
62
            }
63
        }
64
65 4
        return $this->instances[$className];
66
    }
67
}
68