WEBVTT

00:00.110 --> 00:00.500
Okay guys.

00:00.500 --> 00:06.590
So next up we are starting with another let's call it abstract concepts.

00:06.590 --> 00:11.840
So we are still not really building a full fledged blog application.

00:11.840 --> 00:18.650
I'm gonna first introduce a design pattern that's called dependency injection container.

00:18.680 --> 00:27.080
Now whatever programming language you will be using in the future, you will most likely have to work

00:27.080 --> 00:30.290
with some kind of a dependency injection containers.

00:30.290 --> 00:37.310
So I think it's super relevant and it's just important to understand this concept.

00:37.310 --> 00:39.140
So let me quickly explain this.

00:39.140 --> 00:44.000
And after that we're gonna implement a simple Di container.

00:44.150 --> 00:48.020
So dependency injection is a design pattern.

00:48.020 --> 00:56.000
And in this design pattern objects receive their dependencies instead of creating them or fetching them

00:56.000 --> 00:57.050
themselves.

00:57.050 --> 01:00.140
What does it mean in a simpler language.

01:00.380 --> 01:03.620
So let's consider that example that we have right here.

01:03.620 --> 01:05.720
You've got a database class.

01:05.750 --> 01:07.700
It needs to have a config.

01:07.700 --> 01:15.170
So it needs to get the configuration of the database the database name ports whatever information you

01:15.170 --> 01:23.120
might need about the database instead of the database class trying to fetch this information from a

01:23.120 --> 01:27.980
file, this info is just passed to the database.

01:27.980 --> 01:31.700
Typically it's just done through a constructor.

01:31.850 --> 01:36.830
And then there is another class that is called container.

01:36.860 --> 01:40.130
Or it might just be called application.

01:40.130 --> 01:47.690
This is how it would be called in our case an app that is a dependency injection container.

01:49.910 --> 01:57.140
That basically has a map of all those classes that are already created with all their dependencies.

01:57.140 --> 02:05.940
And if you have, let's say a script command line interface script that needs to load the database schema.

02:05.970 --> 02:09.540
That's something we have done previously in the previous project.

02:09.570 --> 02:10.860
Now we will have.

02:11.100 --> 02:18.150
Now we'd like to have a more generic approach to those CLI scripts and will have more of them as well.

02:18.270 --> 02:27.990
And consider we need a database so we don't want to worry about how do we get the database.

02:27.990 --> 02:33.240
Where do we get the configuration for the database from instead?

02:33.300 --> 02:42.420
All we do is we tell the Di container that we need a database, and the container already has the database

02:42.450 --> 02:47.670
object created with the proper configuration passed to it.

02:47.670 --> 02:50.010
So we just get it right away.

02:50.760 --> 02:52.680
And that's the whole concept.

02:52.710 --> 03:03.410
You simplify your own life by instantiating some of the classes within this dependency injection container,

03:03.410 --> 03:07.490
passing all the dependencies that classes need into them.

03:07.490 --> 03:14.750
Whether this is a config that's an array or some objects, whatever is needed, and then you just get

03:14.750 --> 03:18.680
things you need from this Di container.

03:20.120 --> 03:25.160
So to summarize you just reduce the coupling between components.

03:25.400 --> 03:33.020
So nothing is really tightly coupled because everything is orchestrated by this Di container.

03:33.380 --> 03:41.180
Then the code is better organized and maintainable because classes are smaller and they only do a one

03:41.180 --> 03:42.440
specific thing.

03:42.680 --> 03:47.120
And the code is also better for testability.

03:47.120 --> 03:55.550
So if you need to write any kind of automatic tests, it's easier to create them if the code is separated

03:55.550 --> 03:56.930
this way.

03:57.350 --> 03:58.160
Okay.

03:58.220 --> 04:04.490
So without any more further ado, let's just get started and do those two things.

04:04.490 --> 04:07.790
We want to have a centralized configuration.

04:07.790 --> 04:11.390
And also we want to have this Da container.

04:11.390 --> 04:18.470
And we will only create a let's call it boilerplate of this database class, because that's a topic

04:18.470 --> 04:25.670
for some next videos to actually implement some basic database abstraction that will help us with the

04:25.670 --> 04:28.760
typical tasks that we do with a database.

04:28.790 --> 04:30.260
Let's get started.

04:31.250 --> 04:37.070
So we're going to create this dependency injection container inside the car folder.

04:37.700 --> 04:39.320
Let's call it app.

04:40.130 --> 04:45.440
That's essentially a central repository of things in our app.

04:45.440 --> 04:47.000
We can call it this way.

04:47.660 --> 04:51.110
So the namespace here is core.

04:51.140 --> 04:53.060
Well that's everything just core.

04:53.060 --> 04:56.600
And the class will be called app.

04:56.600 --> 05:02.470
Now Let's define the field inside which we're going to keep all the entries.

05:02.470 --> 05:05.650
And that's just an associative array.

05:06.250 --> 05:07.810
Let's call it container.

05:07.840 --> 05:10.480
Initialize it with an empty array.

05:10.510 --> 05:12.640
This doesn't have any constructor.

05:12.640 --> 05:18.100
But we need a way to bind something to this container.

05:18.220 --> 05:25.150
So if I want to create a database class I need to put it under a specific key.

05:25.180 --> 05:36.190
That's why we need the static function that will be called bind with a key and value.

05:36.220 --> 05:37.330
That can be anything.

05:37.330 --> 05:40.720
That's why we're going to use mixed type for it.

05:42.940 --> 05:46.180
And it's void doesn't return anything.

05:47.260 --> 05:50.320
And we're just going to do static container.

05:50.320 --> 05:55.720
This is how we can refer to static data or static methods.

05:56.140 --> 06:00.180
And just under a given key, we're going to put a value.

06:00.450 --> 06:06.870
So you might also say that that's a simple wrapper around an array.

06:07.200 --> 06:16.020
But also then we need a way to get some specific entry from this container using a key.

06:17.280 --> 06:21.090
And the value can be mixed can be different things.

06:22.920 --> 06:34.080
So it's important to check if an entry exists because if the array key exists, would return false for

06:34.080 --> 06:41.370
the given key inside the static container, which is our array.

06:42.030 --> 06:44.760
Just gonna throw an exception.

06:49.560 --> 06:54.210
And then we can say that no key.

06:57.290 --> 07:00.230
Is bound in the container.

07:02.840 --> 07:04.880
So that's also a good practice to add.

07:04.910 --> 07:09.560
Use statements for exceptions even though they are globally available.

07:10.040 --> 07:14.000
So in other cases where we can find the key we just return it.

07:14.000 --> 07:20.780
This would be static container with a given key.

07:20.810 --> 07:25.670
Now this implementation of a dependency injection container might look simple.

07:25.670 --> 07:26.930
And it is simple.

07:26.930 --> 07:34.490
But generally the concept of a dependency injection container can be vastly expanded and can have some

07:34.490 --> 07:36.230
other features that will help you.

07:36.230 --> 07:36.680
Like.

07:36.680 --> 07:43.370
For example, in Symfony framework, dependency injection container has a feature called Autowiring

07:43.370 --> 07:50.360
where classes are instantiated automatically and also all their dependencies are created and automatically

07:50.360 --> 07:51.140
parsed.

07:51.170 --> 07:54.740
This is super handy with bigger applications.

07:54.770 --> 07:57.940
Okay, let's get back to our thing.

07:58.090 --> 07:58.540
Okay.

07:58.570 --> 08:01.300
At this point, we can close this container file.

08:01.300 --> 08:05.710
And I think that this video is all about organizing our app.

08:05.740 --> 08:09.040
That's why I think we need two more files.

08:09.040 --> 08:17.500
So previously we have created a bootstrap PHP file which of which was kind of initializing the whole

08:17.500 --> 08:18.250
project.

08:18.250 --> 08:20.380
And now we need this as well.

08:20.380 --> 08:27.310
So we can initialize all the command line scripts and also the server the same way.

08:27.340 --> 08:31.420
And another file that we need is config php.

08:31.660 --> 08:37.060
That would be the file that will store all of our app configuration.

08:38.620 --> 08:43.000
So the config for an app of this size can just be an array.

08:43.030 --> 08:47.380
Now I'm returning something from a file which is not a function.

08:47.380 --> 08:48.940
There is no function here.

08:48.940 --> 08:55.600
So later on you're going to see how can we require this config file and get whatever was returned from

08:55.600 --> 08:56.400
this file.

08:56.400 --> 08:59.040
So we are returning the whole app config.

08:59.040 --> 09:01.740
It's going to have two categories the app.

09:01.740 --> 09:05.280
And maybe another one can be database.

09:06.390 --> 09:10.290
So having one simple config array is enough.

09:11.820 --> 09:14.430
So let me add the app title.

09:14.790 --> 09:16.290
That's my blog.

09:16.290 --> 09:20.670
Whether we are in debug mode, let it be true for now.

09:20.700 --> 09:30.630
The driver, let's say we are using SQLite and the path does a path to a file and this would be the

09:30.630 --> 09:35.130
current directory plus the database folder.

09:35.340 --> 09:37.770
Blog SQLite.

09:38.010 --> 09:44.340
Now at this point you should create this database folder inside the root directory.

09:44.370 --> 09:47.340
This is where we're going to keep the database.

09:48.630 --> 09:55.380
So now we need to move some things from the index file into the bootstrap file.

09:55.380 --> 10:02.040
First, let me just copy everything into the bootstrap file and let's remove things that we don't need

10:02.040 --> 10:02.700
in here.

10:02.700 --> 10:11.580
So we definitely don't need routing because this is an index specific thing.

10:11.580 --> 10:19.710
Because index.php file is a so-called front controller, the bootstrap file instead needs to generically

10:19.740 --> 10:21.690
initialize the app.

10:21.900 --> 10:33.090
So for example it should have the config and config we're going to get by doing require ones using current

10:33.120 --> 10:39.150
directory and using the config php file.

10:39.150 --> 10:40.980
So notice how.

10:41.010 --> 10:48.960
So notice how I am requiring the contents of this file into the variable, which should now contain

10:48.960 --> 10:52.200
this array that is inside this config file.

10:52.500 --> 10:52.920
Okay.

10:52.950 --> 10:57.230
So we've got the config and autoloading configured.

10:57.260 --> 11:08.750
Now inside this file we should instead remove this require once and instead require once.

11:11.690 --> 11:13.070
The bootstrap file.

11:13.940 --> 11:19.280
So we need to go up and select the bootstrap file.

11:19.280 --> 11:24.830
So now all the app initialization code is in one place is in a bootstrap file.

11:24.830 --> 11:27.650
Same thing we did in the previous project.

11:27.650 --> 11:33.230
So now we can reuse this bootstrap for command line scripts.

11:34.310 --> 11:36.440
Now at this point I should be able to.

11:36.470 --> 11:41.240
VAR dump config and I should see an array.

11:42.530 --> 11:47.240
So I've got 500 error which means there is a bug to fix.

11:47.270 --> 11:56.260
So in this bootstrap file I need to remove this two dots because we no longer need to go up, as the

11:56.260 --> 11:59.680
vendor folder is at the same level as the bootstrap file.

12:00.280 --> 12:03.640
After saving the changes, this should be fine.

12:03.670 --> 12:11.170
And now we've got this whole config array on the screen, which means nothing else than we were just

12:11.170 --> 12:13.060
successful in loading it.

12:14.050 --> 12:16.960
Okay guys, so I'd like us to take a short break at this point.

12:16.960 --> 12:23.860
And next up, I'd like us to create a database class that will be a database abstraction.

12:23.860 --> 12:31.150
And then we're going to wire everything together using our dependency injection container so that we're

12:31.150 --> 12:34.390
gonna have a config inside database inside.

12:34.390 --> 12:41.650
And then if you would need to access the database, you're gonna always do it through dependency injection

12:41.650 --> 12:44.080
container that we've just created.

12:44.080 --> 12:51.430
That way, all the features that our application offers would be easily accessible everywhere.

12:51.430 --> 12:53.770
But that's for the next video.
