Dependencies6:01 with Alena Holligan
Let's take a look at how Slim uses a dependency container to prepare, manage, and inject application dependencies.
Dependency Injection Container
If we were packing a lunch and wanted to include an apple, our lunch box could specify an apple. Each time the lunch box is packed it would require an apple. In programming terms, this is call "tightly coupled" because our lunch box must contain an apple and cannot accept any other fruit. If we want to "decouple" the lunch box and the apple, we could instead "loosely couple" our lunch box with a fruit of ANY kind. The fruit available is contained in a refrigerator. This allows the one packing the lunch to add any available fruit to the lunch box. This is called "dependency injection". The fruit is a dependency of our lunch box, but the available fruit and the person packing the lunch control which fruit is injected into the lunch box. The person packaging the lunch is our application. The refrigerator is a dependency container and our fruit and our lunch box are objects working together to provide our lunch.
You can read more about Pimple, the dependency injection container used by Slim.
There are two steps for handling dependencies in an application. 0:00 The first step is dependency management, and we handle that with Composer. 0:04 Composer makes sure we know what and where to get the packages and classes we need. 0:09 Step two involves using those dependencies within our application. 0:15 If we were packing a lunch and one or 0:20 two including apple, our lunchbox could specify an apple. 0:22 Each time the lunchbox is packed, it would require an apple. 0:27 In programming terms, this is called tightly coupled. 0:32 Because our lunchbox must contain an apple and cannot accept any other fruit. 0:36 If we want to decouple the lunchbox and the apple, 0:42 we could instead loosely couple our lunchbox with a fruit of any kind. 0:46 The fruit available is contained in a refrigerator, 0:52 this allows the one packing the lunch to add any available fruit to the lunchbox. 0:55 This is called dependency injection. 1:02 The fruit is a dependency of our lunchbox. 1:04 But the available fruit, and the person packing the lunch, 1:08 control which fruit is injected into the lunchbox. 1:12 The person packing the lunch is our application, 1:16 the refrigerator is a dependency container, and 1:19 our fruit and our lunchbox are objects working together to provide our lunch. 1:22 Let's take a look at how Slim uses a dependency container to prepare, manage, 1:27 and inject application dependencies. 1:32 Our route file, is actually using two dependencies, logger and renderer. 1:35 To see how those are managed, let's open dependencies.php. 1:42 First, we get the container from our app, then we add items to the container. 1:47 The first item is our renderer. 1:54 This is where we create an object that renders our views. 1:56 We use an anonymous function to return the object. 2:00 The function has a parameter which contains the container itself. 2:04 We see on the following line that we're using the container to get the settings. 2:10 This means we must already have those settings in the container. 2:16 Back in the index.php file, we can see 2:20 that our settings are being passed to the app during initialization. 2:24 This creates our initial container with the settings property. 2:30 When we pass an array instead of a dependency container, 2:35 like we're doing here, Slim creates a default container 2:39 using the dependency injection container package, Pimple. 2:44 In the settings file, we can see that this is an inner array of items. 2:48 One of those items is another array with a key of renderer. 2:53 The one item in renderer is a template_path. 2:58 Let's go back to dependencies. 3:03 We are giving our settings with a key of renderer. 3:05 We are then using those settings to pass the template_path. 3:10 This passes the template_path to our PHP renderer object. 3:16 I really don't like the name renderer, I would rather refer to this as our view. 3:21 So let's change the dependency to view. 3:26 We'll call this view. 3:32 We can leave render in the settings or change it as well as long, 3:35 as it matches what's in the settings file. 3:40 If I try to visit the site now, I get an error, 3:43 because renderer is no longer defined. 3:48 I need to go back to my routes file. 3:51 Instead of renderer, I'm going to use view. 3:55 Now we can go back to the browser again. 4:00 And our site is working again. 4:04 One other thing I want to point out about working with dependencies, 4:06 in our dependencies file, we were using 4:11 the get('settings') to explicitly call the settings property. 4:15 Within our routes, file we are implicitly calling the view directly. 4:21 Both of these methods will work, because if the app object itself 4:30 does not have the property you requested, Slim will check its dependency container. 4:36 The second dependency, used implicitly in our route file, is logger. 4:41 Let's go back to the dependencies file. 4:48 We can see here that our logger is setting up a Monolog object. 4:53 Once again, it uses the settings from our settings container, 5:00 but this time it calls logger. 5:04 When we set up Monolog, we pass it a name, And then for 5:09 the pushHandler, we parse in the path and the level. 5:15 If we go into settings, we can see in the logger that our name is slim-app. 5:22 And our path, if our environment is Docker, will go to stdout. 5:28 And if not, it will go into our /../logs/app.log file. 5:33 And finally, our level is MonologLogger::DEBUG. 5:40 If we open up our logs, app.log, 5:44 we can see that our application has in fact been logging our route. 5:47 Now that we can work with dependencies and we know how our views are being rendered, 5:53 let's start adding the additional routes we need. 5:58
You need to sign up for Treehouse in order to download course files.Sign up