WEBVTT

00:00.290 --> 00:06.950
So we need to do all the steps from this list that I have created here inside our router PHP file.

00:06.950 --> 00:10.640
Let's begin by normalizing the URI.

00:10.640 --> 00:16.190
And as I write this function, I'm going to explain what does it exactly means and what needs to be

00:16.190 --> 00:16.700
done.

00:16.700 --> 00:22.160
So let's create a function that we're gonna call normalize URI.

00:22.190 --> 00:28.670
It accepts the URI as a parameter and it returns a string.

00:28.670 --> 00:31.910
So the URI let's make some changes to it.

00:31.910 --> 00:37.250
First I'd like to make it lowercase as our files our route handlers.

00:37.250 --> 00:38.840
They're also going to be lowercase.

00:38.840 --> 00:44.060
So to be able to find a file we need to care about the character case.

00:44.060 --> 00:50.030
Because on Unix systems the character case in file names matter.

00:50.270 --> 00:57.710
Next up I'd like to use trim to remove all the white spaces from the URI and also remove some additional

00:57.710 --> 01:00.140
characters, which would be slashes.

01:00.140 --> 01:03.400
We want to get rid of those completely.

01:03.460 --> 01:08.770
Next up, we've got this URI and we're going to return a value.

01:08.770 --> 01:12.550
But there is one special case that we need to think of.

01:12.580 --> 01:17.050
If the URI is empty, this means we are on the main page.

01:17.050 --> 01:21.940
That's why we need to look for a route handler that will be called index.

01:21.970 --> 01:25.630
Otherwise we just return the URI.

01:25.660 --> 01:28.960
Now it's time to see this in action.

01:29.200 --> 01:31.360
So let's move to the dispatch function.

01:31.360 --> 01:34.420
And we are implementing the first step.

01:34.420 --> 01:44.080
So the URI is the result of calling the normalize URI function we've just defined on the URI that is

01:44.080 --> 01:45.910
passed to this function.

01:45.910 --> 01:50.260
Now at this point it would be useful to see what that actually is.

01:50.260 --> 01:54.490
For that I'm going to just do var dump with uri and die.

01:54.520 --> 01:58.540
So we stop this function and we see what is the effect.

01:58.570 --> 02:04.910
Now this dispatch function it needs to be called inside the index, the front controller.

02:04.940 --> 02:06.800
So let's call dispatch.

02:06.800 --> 02:09.050
And what do we pass in here.

02:09.080 --> 02:14.900
Well we can get something from our server super global that we already know.

02:14.900 --> 02:19.250
And this is simply the request URI.

02:19.280 --> 02:21.440
That would be our URI.

02:21.440 --> 02:25.280
And the method we also get from the node server.

02:25.280 --> 02:28.280
But server super global.

02:28.280 --> 02:32.600
And that is on the other hand called request method.

02:32.630 --> 02:35.240
That's everything that we need to do in here.

02:35.240 --> 02:37.730
The next thing to do is to start the server.

02:37.730 --> 02:43.970
So let's make sure that we jump into the public folder and we start the server from there.

02:44.600 --> 02:56.270
So I run php dash s localhost 8000 and the file name is index php.

02:56.360 --> 02:58.430
Now we should have the server running.

02:58.430 --> 03:03.060
And let's now head to localhost 8000 to see what's the output.

03:03.090 --> 03:10.440
So now I have magically moved into the browser, and when I just type localhost 8000, the result is

03:10.440 --> 03:11.100
index.

03:11.100 --> 03:14.010
Let me try with slash contact.

03:14.160 --> 03:18.150
So you see that this works fine for the guestbook.

03:18.150 --> 03:20.130
It should also work fine.

03:20.130 --> 03:26.220
So we are getting the route handler name without the method attached.

03:26.250 --> 03:32.700
We're going to be working on this a little bit later, but we can see that our edge case is also working

03:32.700 --> 03:33.480
fine.

03:34.080 --> 03:40.560
By the way, you might have probably noticed that I have the documentation for the stream function open,

03:40.560 --> 03:42.570
and I'm not ashamed of that.

03:42.570 --> 03:47.400
I don't remember the names and order of every function parameters.

03:47.400 --> 03:55.680
That's why I make sure that I have the documentation open on every single project, language, or framework

03:55.680 --> 03:58.950
that I work with, and I suggest you do the same.

03:59.010 --> 04:04.190
Okay, so let's enlarge the working space, the code editor again and then jump to router.

04:04.370 --> 04:05.150
PHP file.

04:05.150 --> 04:07.940
So we've got this first step handled.

04:07.940 --> 04:09.680
I can comment out this line.

04:09.680 --> 04:16.010
By the way, this combination of VAR dumping and dying is a common practice in PHP.

04:16.040 --> 04:18.530
I use it for debugging all the time.

04:18.530 --> 04:21.110
We might as well extract it to a function.

04:21.110 --> 04:22.430
That's for later.

04:22.460 --> 04:25.070
Now we need to handle the second point.

04:25.070 --> 04:30.470
The only allowed HTTP methods that we allow is get or post.

04:31.580 --> 04:41.090
So another good practice that I'd like to introduce is to not hide the magic values inside functions.

04:41.150 --> 04:45.920
So we've got two examples right now this get and post method.

04:45.950 --> 04:48.170
Those are the ones that we handle.

04:48.170 --> 04:55.730
We should not hide this detail inside the dispatch function, because this might be an interesting knowledge

04:55.730 --> 04:59.000
that might be used across the whole project.

04:59.000 --> 05:02.150
That's why we should go with a constant.

05:02.360 --> 05:08.800
So we should define that the allowed methods is get and post.

05:08.830 --> 05:12.730
Now this can be accessed in different places.

05:12.760 --> 05:20.140
Another thing that we should be extracting into constants is maybe the index URI.

05:20.170 --> 05:22.300
This is an empty string.

05:22.300 --> 05:27.040
This might look trivial, but believe me, this is really a good practice.

05:27.070 --> 05:34.780
Now I'm not comparing that to an empty string, and I can configure the behavior of the project without

05:34.780 --> 05:38.410
changing the implementation of the functions.

05:39.580 --> 05:50.380
I can also do index route to say that if we are looking at this main page without any specific URI,

05:50.410 --> 05:52.570
the route name is index.

05:53.110 --> 05:55.840
I can use this constant right here.

05:55.840 --> 05:57.970
This would be index route.

05:57.970 --> 06:04.690
So now every single time you go back to this file or any other developer on your team.

06:04.690 --> 06:11.860
They don't have to scan the implementation of every single function and try to understand what is happening.

06:11.860 --> 06:20.140
And it might feel a lot safer to just change one of those values, to change the behavior of the app,

06:20.140 --> 06:24.760
instead of changing it directly inside the function.

06:24.760 --> 06:29.350
So this is a very good practice.

06:29.380 --> 06:32.290
Now let's jump to this second step.

06:32.290 --> 06:37.930
Let's make sure that we only handle specific HTTP methods.

06:37.930 --> 06:45.070
So we're going to add an if statement and use an in array function to check if the method that was passed

06:45.070 --> 06:48.940
here is one of the allowed methods.

06:49.450 --> 07:00.130
Now if it's not, we should return a 404 response that can be summarized as a not found response.

07:00.130 --> 07:03.640
Now also, we need to normalize the method.

07:03.810 --> 07:09.210
So the method variable, well let's convert it to uppercase.

07:09.210 --> 07:17.250
On the other hand, because this is how we have defined those methods inside this constant like this.

07:18.390 --> 07:25.260
So let's go back into this if statement and let's call a non-existing Notfound function.

07:25.260 --> 07:31.560
So we need to add this function because this is something that might really be reusable across the whole

07:31.560 --> 07:32.670
application.

07:33.030 --> 07:38.520
So by calling this function it immediately returns the response from PHP.

07:38.550 --> 07:46.920
It stops the execution and it returns an HTTP response code that is specific to this case.

07:46.920 --> 07:50.310
404 means that the page wasn't found.

07:51.420 --> 07:59.730
Next we can echo 404 not found and the exit statement will stop the execution of the script.

08:01.950 --> 08:05.330
So you might be wondering how do I test that?

08:05.330 --> 08:12.470
If we have the allowed methods as get and post and get is the default method of the browser.

08:12.470 --> 08:19.010
When you just go to a website and post is the method that you typically use with forms.

08:19.040 --> 08:24.950
Well, it's easy to test that we can temporarily remove the get from allowed methods.

08:24.950 --> 08:28.640
And now you can see that this was working fine.

08:28.640 --> 08:33.980
And if I now go to the main page we've got 404 not found.

08:34.010 --> 08:39.110
So this was just a temporary measure to try this out to test the functionality.

08:39.140 --> 08:40.190
It worked fine.

08:40.190 --> 08:43.610
Let's bring back the get method from the allowed methods.

08:43.610 --> 08:49.190
And when I refresh the page we don't see anything, which actually is a good sign.

08:49.190 --> 08:55.760
It means that this dispatch function went to the very end and it didn't stop at this point.

08:57.050 --> 09:05.150
So the next step is to figure out what is the actual file name for that, let's define a function that

09:05.150 --> 09:07.730
will be called Getfile path.

09:08.540 --> 09:11.570
Now this function might be super simple.

09:11.570 --> 09:14.060
It depends on our requirements.

09:14.090 --> 09:21.980
Now, if I pass the URI to it and the method, I expect to have a string returned, that would be the

09:21.980 --> 09:26.690
full path to the PHP file that can match the route.

09:26.870 --> 09:32.390
So let's jump to the index file because I think we need another constant.

09:32.390 --> 09:34.700
We've got the includes directory.

09:34.730 --> 09:41.270
Now let's also have the routes directory in a constant that we can use everywhere.

09:41.270 --> 09:45.290
And we're gonna have a new folder called routes.

09:45.320 --> 09:47.540
Let's create this folder now.

09:47.900 --> 09:49.670
So this is routes.

09:49.670 --> 09:52.970
This would contain all the routes that we define.

09:52.970 --> 09:54.830
Let's go back to router.

09:55.610 --> 10:01.010
Now I think that here we can just return a value.

10:01.040 --> 10:13.150
This would be the routes directory If I remember the constant name properly, then a directory separator,

10:13.690 --> 10:22.210
then I think that we can directly translate the URI into the pathname, but we might normalize it first.

10:22.210 --> 10:30.190
So let's do normalize URI to just make sure it's matching the case of the path names.

10:31.180 --> 10:32.560
So this is this.

10:32.590 --> 10:38.140
Next up we should append the method after an underscore.

10:38.140 --> 10:41.770
So first we are we are adding the underscore.

10:41.920 --> 10:49.900
Next up I'm concatenating the method which by the way I might have to lowercase.

10:49.900 --> 10:59.200
So I do str two lower because all of our path names and file names should be in lower case.

10:59.200 --> 11:05.050
And finally I concatenate the extension the PHP.

11:05.160 --> 11:08.580
Now let's just see if this works.

11:08.580 --> 11:14.190
If this is fine, I'm gonna var dump the.

11:14.670 --> 11:15.690
What's the function name?

11:15.690 --> 11:18.480
Get file path okay.

11:18.600 --> 11:20.130
Get file path.

11:20.130 --> 11:28.440
Passing the URI and method that we already have here and calling die to stop the execution.

11:28.680 --> 11:30.750
Let me refresh the page.

11:34.140 --> 11:35.640
Now this looks fine.

11:35.640 --> 11:42.420
I really expect to have this directory and I expect to have this file inside once I create it.

11:42.450 --> 11:43.320
Of course.

11:43.440 --> 11:46.440
And this also works on windows.

11:46.440 --> 11:54.420
If I refresh this script and zoom out a little bit, even though we've got a mixture of slashes and

11:54.420 --> 12:02.070
forward slashes, they both work on windows, so you should be fine on windows as well.

12:03.150 --> 12:11.390
Now the next step should be to create a file and see if it really works, if we can really load a specific

12:11.600 --> 12:12.710
PHP file.

12:14.840 --> 12:18.230
Okay, now let me open the files.

12:18.230 --> 12:23.900
And here let's create the contact get PHP.

12:23.930 --> 12:27.080
One file is more than enough.

12:27.110 --> 12:29.240
It can do echo.

12:29.270 --> 12:33.170
Hello something super simple.

12:33.590 --> 12:36.320
Now let's jump back to the router.

12:36.950 --> 12:41.660
And at this point we should just check if this file exists.

12:41.660 --> 12:52.430
So let me remove the var dump and just leave this fragment and assign it to the file path variable.

12:52.610 --> 12:58.490
And next up we're going to do a check using file exists function from PHP.

12:58.640 --> 13:08.900
We're going to check if this file exists because if it does I'm just going to use include And I'm going

13:08.930 --> 13:14.120
to include this file so it can run and I can return to.

13:14.150 --> 13:20.090
Just make sure we stop at this point because if this file won't be found.

13:20.900 --> 13:26.240
I run the not found which would display a 404 not found page.

13:26.300 --> 13:29.750
Okay, it's time for a final test.

13:30.230 --> 13:35.090
So let me go to this URL and as expected, I see the text.

13:35.120 --> 13:35.960
Hello.

13:36.830 --> 13:39.380
Let's also verify that on windows.

13:40.610 --> 13:44.420
And if I go to main page well this was expected.

13:44.420 --> 13:46.370
The index file is not created.

13:46.370 --> 13:51.710
But if I jump to contact page I see the same text.

13:51.740 --> 13:52.580
Hello.

13:52.940 --> 13:56.780
All right so we've created a working router.

13:57.710 --> 14:03.350
So our next steps should be to start implementing some specific logic.

14:03.350 --> 14:07.040
Some specific pages of this application.
