Complex classes like Container often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Container, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
13 | class Container implements ContainerInterface |
||
14 | { |
||
15 | /** |
||
16 | * Array of singletons |
||
17 | * @var array |
||
18 | */ |
||
19 | protected $shares = []; |
||
20 | |||
21 | /** |
||
22 | * Array pf definitions, support instance,callable,Definition, class |
||
23 | * @var array |
||
24 | */ |
||
25 | protected $definitions = []; |
||
26 | |||
27 | /** |
||
28 | * Array of interface bindings |
||
29 | * @var array |
||
30 | */ |
||
31 | protected $contextBindings = []; |
||
32 | |||
33 | /** |
||
34 | * Array of parameters |
||
35 | * @var ParameterStore |
||
36 | */ |
||
37 | protected $parameters; |
||
38 | |||
39 | /** |
||
40 | * @var ClassDefinitionResolver |
||
41 | */ |
||
42 | protected $classDefinitionResolver; |
||
43 | |||
44 | public function __construct() |
||
48 | |||
49 | /** |
||
50 | * Add a Definition class |
||
51 | * @param string $name |
||
52 | * @param string $class |
||
53 | * @return ClassDefinition |
||
54 | */ |
||
55 | public function define($name, $class) |
||
61 | |||
62 | /** |
||
63 | * Bind an callable to the container with its name |
||
64 | * @param string $name |
||
65 | * @param mixed $creation A invalid callable |
||
66 | * @throws ConfigException |
||
67 | * @return $this |
||
68 | */ |
||
69 | public function call($name, $creation) |
||
77 | |||
78 | /** |
||
79 | * Bind an instance to the container with its name |
||
80 | * ``` |
||
81 | * $container->instance('user', new User()); |
||
82 | * //Or just give instance |
||
83 | * $container->instance(new User()); |
||
84 | * |
||
85 | * ``` |
||
86 | * @param string $name |
||
87 | * @param object $instance |
||
88 | * @throws ConfigException |
||
89 | * @return $this |
||
90 | */ |
||
91 | public function instance($name, $instance = null) |
||
104 | |||
105 | /** |
||
106 | * Binds an interface or abstract class to its implementation; |
||
107 | * It's also be used to bind a service name to an existing class |
||
108 | * @param string $name |
||
109 | * @param string $implementation |
||
110 | * @param string|array $context the specified context to bind |
||
111 | * @throws ConfigException |
||
112 | * @return $this |
||
113 | */ |
||
114 | public function bind($name, $implementation, $context = null) |
||
133 | |||
134 | /** |
||
135 | * Add a definition to the container |
||
136 | * ``` |
||
137 | * //Add an instance like "instance" method |
||
138 | * $container->set('student', new Student()); |
||
139 | * |
||
140 | * //Add a callable definition |
||
141 | * $container->set('student', 'StudentFactory::create'); |
||
142 | * $container->set('student', function(){ |
||
143 | * return new Student(); |
||
144 | * }); |
||
145 | * |
||
146 | * //Add an instance of "Slince\Di\Definition" |
||
147 | * $container->set('student', new Definition('Foo\Bar\StudentClass', [ |
||
148 | * 'gender' => 'boy', |
||
149 | * 'school' => new Reference('school') |
||
150 | * ], [ |
||
151 | * 'setAge' => [18] |
||
152 | * ], [ |
||
153 | * 'father' => 'James', |
||
154 | * 'mather' => 'Sophie' |
||
155 | * ])); |
||
156 | * |
||
157 | * //Add a class definition |
||
158 | * $container->set('student', Foo\Bar\StudentClass); |
||
159 | * ``` |
||
160 | * @param string $name |
||
161 | * @param mixed $definition |
||
162 | * @throws ConfigException |
||
163 | * @return $this |
||
164 | */ |
||
165 | public function set($name, $definition) |
||
178 | |||
179 | /** |
||
180 | * Share the service by given name |
||
181 | * @param string $name |
||
182 | * @return $this |
||
183 | */ |
||
184 | public function share($name) |
||
189 | |||
190 | /** |
||
191 | * Get a service instance by specified name |
||
192 | * @param string $name |
||
193 | * @param array $arguments |
||
194 | * @return object |
||
195 | */ |
||
196 | public function get($name, $arguments = []) |
||
217 | |||
218 | /** |
||
219 | * {@inheritdoc} |
||
220 | */ |
||
221 | public function has($name) |
||
231 | |||
232 | /** |
||
233 | * Gets all global parameters |
||
234 | * @return array |
||
235 | */ |
||
236 | public function getParameters() |
||
240 | |||
241 | /** |
||
242 | * Sets array of parameters |
||
243 | * @param array $parameterStore |
||
244 | */ |
||
245 | public function setParameters(array $parameterStore) |
||
249 | |||
250 | /** |
||
251 | * Add some parameters |
||
252 | * @param array $parameters |
||
253 | */ |
||
254 | public function addParameters(array $parameters) |
||
258 | |||
259 | /** |
||
260 | * Sets a parameter with its name and value |
||
261 | * @param $name |
||
262 | * @param mixed $value |
||
263 | */ |
||
264 | public function setParameter($name, $value) |
||
268 | |||
269 | /** |
||
270 | * Gets a parameter by given name |
||
271 | * @param $name |
||
272 | * @param mixed $default |
||
273 | * @return mixed |
||
274 | */ |
||
275 | public function getParameter($name, $default = null) |
||
279 | |||
280 | /** |
||
281 | * Resolves all arguments for the function or method. |
||
282 | * @param \ReflectionFunctionAbstract $method |
||
283 | * @param array $arguments |
||
284 | * @param array $contextBindings The context bindings for the function |
||
285 | * @throws DependencyInjectionException |
||
286 | * @return array |
||
287 | */ |
||
288 | public function resolveFunctionArguments(\ReflectionFunctionAbstract $method, array $arguments, array $contextBindings = []) |
||
324 | |||
325 | /** |
||
326 | * Gets all context bindings for the class and method |
||
327 | * [ |
||
328 | * 'User' => [ |
||
329 | * 'original' => 'SchoolInterface' |
||
330 | * 'bind' => 'MagicSchool', |
||
331 | * ] |
||
332 | * ] |
||
333 | * @param string $contextClass |
||
334 | * @param string $contextMethod |
||
335 | * @return array |
||
336 | */ |
||
337 | public function getContextBindings($contextClass, $contextMethod) |
||
349 | |||
350 | protected function createInstanceFromDefinition($definition, array $arguments) |
||
371 | |||
372 | protected function getClassDefinitionResolver() |
||
379 | |||
380 | /** |
||
381 | * Resolves array of parameters |
||
382 | * @param array $parameters |
||
383 | * @return array |
||
384 | */ |
||
385 | protected function resolveParameters($parameters) |
||
398 | |||
399 | /** |
||
400 | * Formats parameter value |
||
401 | * @param $value |
||
402 | * @return mixed |
||
403 | * @throws DependencyInjectionException |
||
404 | */ |
||
405 | protected function formatParameter($value) |
||
424 | } |
||
425 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.