PhpArrayContainer::createService

protected PhpArrayContainer::createService(array $definition, $id)

Creates a service from a service definition.

Parameters

array $definition: The service definition to create a service from.

string $id: The service identifier, necessary so it can be shared if its public.

Return value

object The service described by the service definition.

Throws

\Symfony\Component\DependencyInjection\Exception\RuntimeException Thrown when the service is a synthetic service.

\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException Thrown when the configurator callable in $definition['configurator'] is not actually a callable.

\ReflectionException Thrown when the service class takes more than 10 parameters to construct, and cannot be instantiated.

Overrides Container::createService

File

core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php, line 49

Class

PhpArrayContainer
Provides a container optimized for Drupal's needs.

Namespace

Drupal\Component\DependencyInjection

Code

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
protected function createService(array $definition, $id) {
  // This method is a verbatim copy of
  // \Drupal\Component\DependencyInjection\Container::createService
  // except for the following difference:
  // - There are no instanceof checks on \stdClass, which are used in the
  //   parent class to avoid resolving services and parameters when it is
  //   known from dumping that there is nothing to resolve.
  if (isset($definition['synthetic']) && $definition['synthetic'] === TRUE) {
    throw new RuntimeException(sprintf('You have requested a synthetic service ("%s"). The service container does not know how to construct this service. The service will need to be set before it is first used.', $id));
  }
 
  $arguments = array();
  if (isset($definition['arguments'])) {
    $arguments = $this->resolveServicesAndParameters($definition['arguments']);
  }
 
  if (isset($definition['file'])) {
    $file = $this->frozen ? $definition['file'] : current($this->resolveServicesAndParameters(array($definition['file'])));
    require_once $file;
  }
 
  if (isset($definition['factory'])) {
    $factory = $definition['factory'];
    if (is_array($factory)) {
      $factory = $this->resolveServicesAndParameters(array($factory[0], $factory[1]));
    }
    elseif (!is_string($factory)) {
      throw new RuntimeException(sprintf('Cannot create service "%s" because of invalid factory', $id));
    }
 
    $service = call_user_func_array($factory, $arguments);
  }
  else {
    $class = $this->frozen ? $definition['class'] : current($this->resolveServicesAndParameters(array($definition['class'])));
    $length = isset($definition['arguments_count']) ? $definition['arguments_count'] : count($arguments);
 
    // Optimize class instantiation for services with up to 10 parameters as
    // reflection is noticeably slow.
    switch ($length) {
      case 0:
        $service = new $class();
        break;
 
      case 1:
        $service = new $class($arguments[0]);
        break;
 
      case 2:
        $service = new $class($arguments[0], $arguments[1]);
        break;
 
      case 3:
        $service = new $class($arguments[0], $arguments[1], $arguments[2]);
        break;
 
      case 4:
        $service = new $class($arguments[0], $arguments[1], $arguments[2], $arguments[3]);
        break;
 
      case 5:
        $service = new $class($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4]);
        break;
 
      case 6:
        $service = new $class($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5]);
        break;
 
      case 7:
        $service = new $class($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6]);
        break;
 
      case 8:
        $service = new $class($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6], $arguments[7]);
        break;
 
      case 9:
        $service = new $class($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6], $arguments[7], $arguments[8]);
        break;
 
      case 10:
        $service = new $class($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6], $arguments[7], $arguments[8], $arguments[9]);
        break;
 
      default:
        $r = new \ReflectionClass($class);
        $service = $r->newInstanceArgs($arguments);
        break;
    }
  }
 
  // Share the service if it is public.
  if (!isset($definition['public']) || $definition['public'] !== FALSE) {
    // Forward compatibility fix for Symfony 2.8 update.
    if (!isset($definition['shared']) || $definition['shared'] !== FALSE) {
      $this->services[$id] = $service;
    }
  }
 
  if (isset($definition['calls'])) {
    foreach ($definition['calls'] as $call) {
      $method = $call[0];
      $arguments = array();
      if (!empty($call[1])) {
        $arguments = $call[1];
        $arguments = $this->resolveServicesAndParameters($arguments);
      }
      call_user_func_array(array($service, $method), $arguments);
    }
  }
 
  if (isset($definition['properties'])) {
    $definition['properties'] = $this->resolveServicesAndParameters($definition['properties']);
    foreach ($definition['properties'] as $key => $value) {
      $service->{$key} = $value;
    }
  }
 
  if (isset($definition['configurator'])) {
    $callable = $definition['configurator'];
    if (is_array($callable)) {
      $callable = $this->resolveServicesAndParameters($callable);
    }
 
    if (!is_callable($callable)) {
      throw new InvalidArgumentException(sprintf('The configurator for class "%s" is not a callable.', get_class($service)));
    }
 
    call_user_func($callable, $service);
  }
 
  return $service;
}
doc_Drupal
2025-01-10 15:47:30
Comments
Leave a Comment

Please login to continue.