Completed
Push — master ( ab2421...ac78a3 )
by Matthieu
02:21
created

CompiledContainer::setDefinition()   A

Complexity

Conditions 1
Paths 1

Duplication

Lines 0
Ratio 0 %

Size

Total Lines 6
Code Lines 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace DI;
4
5
use DI\Definition\Definition;
6
7
/**
8
 * Compiled version of the dependency injection container.
9
 *
10
 * @author Matthieu Napoli <[email protected]>
11
 */
12
abstract class CompiledContainer extends Container
13
{
14
    /**
15
     * {@inheritdoc}
16
     */
17
    public function get($name)
18
    {
19
        // Try to find the entry in the singleton map
20 View Code Duplication
        if (isset($this->resolvedEntries[$name]) || array_key_exists($name, $this->resolvedEntries)) {
21
            return $this->resolvedEntries[$name];
22
        }
23
24
        $method = static::METHOD_MAPPING[$name] ?? null;
25
26
        // If it's a compiled entry, then there is a method in this class
27
        if ($method !== null) {
28
            // Check if we are already getting this entry -> circular dependency
29
            if (isset($this->entriesBeingResolved[$name])) {
30
                throw new DependencyException("Circular dependency detected while trying to resolve entry '$name'");
31
            }
32
            $this->entriesBeingResolved[$name] = true;
33
34
            try {
35
                $value = $this->$method();
36
            } finally {
37
                unset($this->entriesBeingResolved[$name]);
38
            }
39
40
            // Store the entry to always return it without recomputing it
41
            $this->resolvedEntries[$name] = $value;
42
43
            return $value;
44
        }
45
46
        return parent::get($name);
47
    }
48
49
    /**
50
     * {@inheritdoc}
51
     */
52
    public function has($name)
53
    {
54 View Code Duplication
        if (! is_string($name)) {
55
            throw new \InvalidArgumentException(sprintf(
56
                'The name parameter must be of type string, %s given',
57
                is_object($name) ? get_class($name) : gettype($name)
58
            ));
59
        }
60
61
        // The parent method is overridden to check in our array, it avoids resolving definitions
62
        if (isset(static::METHOD_MAPPING[$name])) {
63
            return true;
64
        }
65
66
        return parent::has($name);
67
    }
68
69
    protected function setDefinition(string $name, Definition $definition)
70
    {
71
        // It needs to be forbidden because that would mean get() must go through the definitions
72
        // every time, which kinds of defeats the performance gains of the compiled container
73
        throw new \LogicException('You cannot set a definition at runtime on a compiled container. You can either put your definitions in a file, disable compilation or ->set() a raw value directly (PHP object, string, int, ...) instead of a PHP-DI definition.');
74
    }
75
}
76