1 | <?php |
||
15 | class Container implements ContainerContract { |
||
16 | /** |
||
17 | * ServiceProvider names to register with the container. |
||
18 | * |
||
19 | * Can be overwritten to include predefined providers. |
||
20 | * |
||
21 | * @var string[] |
||
22 | */ |
||
23 | protected $providers = array(); |
||
24 | |||
25 | /** |
||
26 | * Registered definitions. |
||
27 | * |
||
28 | * @var mixed[] |
||
29 | */ |
||
30 | private $definitions = array(); |
||
31 | |||
32 | /** |
||
33 | * Aliases to share between fetches. |
||
34 | * |
||
35 | * @var <string, true>[] |
||
36 | */ |
||
37 | private $shared = array(); |
||
38 | |||
39 | /** |
||
40 | * Aliases of all the registered services. |
||
41 | * |
||
42 | * @var <string, true>[] |
||
43 | */ |
||
44 | private $aliases = array(); |
||
45 | |||
46 | /** |
||
47 | * Array of classes registered on the container. |
||
48 | * |
||
49 | * @var <string, true>[] |
||
50 | */ |
||
51 | private $classes = array(); |
||
52 | |||
53 | /** |
||
54 | * Current position in the loop. |
||
55 | * |
||
56 | * @var int |
||
57 | */ |
||
58 | private $position; |
||
59 | |||
60 | /** |
||
61 | * 0-indexed array of aliases for looping. |
||
62 | * |
||
63 | * @var string[] |
||
64 | */ |
||
65 | private $keys = array(); |
||
66 | |||
67 | /** |
||
68 | * Create a new container with the given providers. |
||
69 | * |
||
70 | * Providers can be instances or the class of the provider as a string. |
||
71 | * |
||
72 | * @param ServiceProvider[]|string[] $providers |
||
73 | */ |
||
74 | 69 | public function __construct( array $providers = array() ) { |
|
88 | |||
89 | |||
90 | /** |
||
91 | * {@inheritdoc} |
||
92 | * |
||
93 | * @param string|array $alias |
||
94 | * @param mixed $definition |
||
95 | * |
||
96 | * @throws DefinedAliasException |
||
97 | * |
||
98 | * @return $this |
||
99 | */ |
||
100 | 63 | public function define( $alias, $definition ) { |
|
125 | |||
126 | /** |
||
127 | * {@inheritdoc} |
||
128 | * |
||
129 | * @param string|array $alias |
||
130 | * @param mixed $definition |
||
131 | * |
||
132 | * @throws DefinedAliasException |
||
133 | * |
||
134 | * @return $this |
||
135 | */ |
||
136 | 33 | public function share( $alias, $definition ) { |
|
147 | |||
148 | /** |
||
149 | * {@inheritdoc} |
||
150 | * |
||
151 | * @param string $alias |
||
152 | * |
||
153 | * @throws UndefinedAliasException |
||
154 | * |
||
155 | * @return mixed |
||
156 | */ |
||
157 | 39 | public function fetch( $alias ) { |
|
188 | |||
189 | /** |
||
190 | * {@inheritdoc} |
||
191 | * |
||
192 | * @param string $alias |
||
193 | * |
||
194 | * @return bool |
||
195 | */ |
||
196 | 18 | public function has( $alias ) { |
|
199 | |||
200 | /** |
||
201 | * {@inheritDoc} |
||
202 | * |
||
203 | * @param string $alias |
||
204 | * |
||
205 | * @return $this |
||
206 | */ |
||
207 | 21 | public function remove( $alias ) { |
|
228 | |||
229 | /** |
||
230 | * {@inheritDoc} |
||
231 | * |
||
232 | * @param ServiceProvider $provider |
||
233 | * |
||
234 | * @return $this |
||
235 | */ |
||
236 | 3 | public function register( ServiceProvider $provider ) { |
|
242 | |||
243 | /** |
||
244 | * Set a value into the container. |
||
245 | * |
||
246 | * @param string $id |
||
247 | * @param mixed $value |
||
248 | * |
||
249 | * @see define |
||
250 | */ |
||
251 | 6 | public function offsetSet( $id, $value ) { |
|
254 | |||
255 | /** |
||
256 | * Get an value from the container. |
||
257 | * |
||
258 | * @param string $id |
||
259 | * |
||
260 | * @return object |
||
261 | * @throws UndefinedAliasException |
||
262 | * |
||
263 | * @see fetch |
||
264 | */ |
||
265 | 6 | public function offsetGet( $id ) { |
|
268 | |||
269 | /** |
||
270 | * Checks if a key is set on the container. |
||
271 | * |
||
272 | * @param string $id |
||
273 | * |
||
274 | * @return bool |
||
275 | * |
||
276 | * @see has |
||
277 | */ |
||
278 | 6 | public function offsetExists( $id ) { |
|
281 | |||
282 | /** |
||
283 | * Remove a key from the container. |
||
284 | * |
||
285 | * @param string $id |
||
286 | * |
||
287 | * @see remove |
||
288 | */ |
||
289 | 3 | public function offsetUnset( $id ) { |
|
292 | |||
293 | /** |
||
294 | * Sets the object properties to prepare for the loop. |
||
295 | */ |
||
296 | 12 | public function rewind() { |
|
300 | |||
301 | /** |
||
302 | * Retrieves the service object for the current step in the loop. |
||
303 | * |
||
304 | * @return object |
||
305 | */ |
||
306 | 12 | public function current() { |
|
309 | |||
310 | /** |
||
311 | * Retrieves the key for the current step in the loop. |
||
312 | * |
||
313 | * @return string |
||
314 | */ |
||
315 | 12 | public function key() { |
|
318 | |||
319 | /** |
||
320 | * Increments to the next step in the loop. |
||
321 | */ |
||
322 | 12 | public function next() { |
|
325 | |||
326 | /** |
||
327 | * Checks if the next step in the loop in valid. |
||
328 | * |
||
329 | * @return bool |
||
330 | */ |
||
331 | 12 | public function valid() { |
|
334 | } |
||
335 |
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_function
expects aPost
object, and outputs the author of the post. The base classPost
returns a simple string and outputting a simple string will work just fine. However, the child classBlogPost
which is a sub-type ofPost
instead decided to return anobject
, and is therefore violating the SOLID principles. If aBlogPost
were passed tomy_function
, PHP would not complain, but ultimately fail when executing thestrtoupper
call in its body.