WEBVTT

00:00.140 --> 00:03.830
So let's talk about the scopes of variables in PHP.

00:04.460 --> 00:07.280
So at the very top you've got the global scope.

00:07.280 --> 00:14.540
And that's the scope of all the variables that were just declared outside the functions so directly

00:14.540 --> 00:16.160
in PHP files.

00:16.160 --> 00:21.110
And the global scope is shared across every single PHP file.

00:21.110 --> 00:28.820
So if you use includes or you require some PHP files, they will share the same global scope.

00:30.140 --> 00:33.290
The next scope is the local scope in functions.

00:33.290 --> 00:41.600
So whenever you declare any variables inside functions, they are part of the local scope of that function

00:41.600 --> 00:45.800
and this means they are not accessible outside this function.

00:45.890 --> 00:51.830
So can't be accessed in a global scope or in other functions.

00:52.340 --> 00:54.440
Same with function arguments.

00:54.440 --> 01:02.730
So whatever you pass to a function, if that's passed by value, it's the local scope of that function,

01:02.730 --> 01:07.530
and this variable is not accessible outside.

01:07.830 --> 01:13.020
The last special case are the static variables inside functions.

01:13.110 --> 01:20.040
So you can say that static variables are part of the function scope, but yet they are special.

01:20.550 --> 01:29.130
So all the variables that you define in functions, they only exist for the duration of this function.

01:29.130 --> 01:37.290
If the function stops and returns a value, the variables and arguments, they disappear.

01:37.290 --> 01:39.120
They are no longer available.

01:39.120 --> 01:46.620
And when you call the function again, you actually have new variables inside this function scope.

01:46.770 --> 01:55.410
So the difference with the static variables in functions is that they actually preserve their state

01:55.410 --> 01:58.560
between subsequent function calls.

01:59.040 --> 02:03.000
So let's see examples of all of that.

02:03.210 --> 02:07.410
And also let's see, how can we mix those scopes?

02:07.410 --> 02:09.060
How can we access.

02:09.090 --> 02:16.350
Global variables in functions and how the static variables work.

02:18.030 --> 02:19.440
So it's time for examples.

02:19.440 --> 02:25.050
Let's create the scope PHP file and add the starting tag.

02:25.080 --> 02:27.690
Next up, let's add a global variable.

02:27.720 --> 02:30.570
Let's call this superhero.

02:31.320 --> 02:35.190
And this would be maybe Superman.

02:36.600 --> 02:42.750
Next up we're going to create a function called reveal identity.

02:44.190 --> 02:48.900
And here I'd like to say what's the real name of Superman.

02:50.370 --> 03:00.570
So I use the superhero variable and I say real name is Clark Kent.

03:01.080 --> 03:05.560
Let's call this function now and let's see if this would even work.

03:05.830 --> 03:15.430
So we run PHP, scope, PHP, and we've got a warning that we've used undefined variable called superhero.

03:15.430 --> 03:18.940
So that's the separation of scopes.

03:19.060 --> 03:21.070
That's the global scope.

03:21.190 --> 03:29.290
And inside this function between curly braces we've got the local scope of this function.

03:29.290 --> 03:37.330
And we can't access directly at least the variables from the global scope.

03:37.480 --> 03:47.110
So a way around that would be to just pass a parameter where you can just use name variable, or even

03:47.110 --> 03:54.130
define the superhero argument and just pass the variable with the same name.

03:54.130 --> 04:02.110
That's another thing that you can use the same variable names in different scopes.

04:02.770 --> 04:06.140
So this superhero variable here, since we have.

04:06.140 --> 04:12.830
The argument is something different than this one because those are separate scopes.

04:12.830 --> 04:15.830
You can compare that to separate rooms.

04:15.830 --> 04:22.550
You can have Peter in one room and another Peter in another room, and that's not the same Peter.

04:25.430 --> 04:31.340
So that's one way, and I would say the preferred way to just pass arguments to functions.

04:31.340 --> 04:40.580
But in PHP you also have the global statement which lets you, let's say import or just make available

04:40.580 --> 04:43.730
some global variables inside functions.

04:43.730 --> 04:51.140
And now this would work fine because we now access this original global variable.

04:53.540 --> 04:56.240
Now let's mix that with the local scope.

04:56.240 --> 05:03.410
So the variable I'm now creating is in the local scope of this reveal identity function.

05:03.410 --> 05:11.000
And I'm going to move this part of the display displayed text to our local scope variable and just use

05:11.000 --> 05:13.490
it inside the echo statement.

05:13.700 --> 05:23.630
So the code works fine, because this is a variable that exists in the scope of this reveal identity,

05:23.630 --> 05:30.650
and every single time this function is called a new variable with this value will be created.

05:30.680 --> 05:39.830
But if for whatever reason you'd like to echo it again, you'd like to access a message outside the

05:39.830 --> 05:40.760
function.

05:40.790 --> 05:41.960
Here is what you get.

05:41.990 --> 05:44.450
Warning as it's undefined.

05:44.480 --> 05:52.160
Well, and this means it's not defined in the scope you are currently in, and you are currently in

05:52.160 --> 05:53.570
at least in line 11.

05:53.570 --> 05:56.540
Here you are in the global scope.

05:58.100 --> 05:58.550
Okay.

05:58.550 --> 06:02.510
So next up let's see the static variables.

06:02.840 --> 06:05.240
Let me create another function for that.

06:05.240 --> 06:08.880
And we're gonna count visitors.

06:10.020 --> 06:12.000
Let's define the static variable.

06:12.000 --> 06:17.070
You define the static variable by prepending it with the static keyword.

06:18.210 --> 06:24.750
I'm using visitor count and this will equal zero.

06:25.410 --> 06:29.910
Now what I'm doing here is I'm just going to increase this value by one.

06:29.910 --> 06:33.000
So you probably remember this operator.

06:33.030 --> 06:48.780
And we'll simply output something saying visitor and hash visitor count has arrived like that.

06:48.780 --> 06:53.340
And now let's just run this function three times.

06:57.390 --> 07:01.980
So remember how I previously said that the function variables.

07:01.980 --> 07:11.040
So the functions that are defined in the local scope of the function, they only exist up until the

07:11.040 --> 07:15.030
end of the function after the function is called and returns.

07:15.090 --> 07:17.640
The values are destroyed.

07:17.670 --> 07:23.700
They don't exist anymore, and when you call the function again, you've got a new variable inside this

07:23.700 --> 07:24.330
function.

07:24.360 --> 07:27.000
Let's see what happens with the static ones.

07:27.420 --> 07:29.820
Let's rerun this script.

07:30.960 --> 07:33.180
Well, I'm not sure this is clearly visible.

07:33.210 --> 07:38.340
Probably you can read that easily, but let's run it again.

07:39.000 --> 07:45.960
So what we see here instead is that we've got visitor one, visitor two, and visitor three.

07:45.990 --> 07:52.080
Yet you can see we are using the same variable defined in the function local scope.

07:52.110 --> 07:54.390
So this is what static does.

07:54.390 --> 07:59.220
It preserves the state of a variable defined in the function.

08:00.330 --> 08:07.680
So it might be a little bit counterintuitive at the first glance because you clearly see that the visitor

08:07.680 --> 08:10.300
count is initialized with zero.

08:10.330 --> 08:18.280
Yet when you call this function, it seems like this line isn't run on subsequent calls, only on the

08:18.280 --> 08:19.330
first one.

08:19.420 --> 08:21.550
And actually that's the case.

08:21.550 --> 08:27.250
So here the first call just initializes this variable with zero.

08:27.250 --> 08:33.430
And then this variable leaves even when this function stops.

08:34.420 --> 08:42.880
As we've seen the subsequent returns just increase the value of visitor count that we had previously.

08:42.880 --> 08:49.420
So the variable is shared across all calls of this function.

08:49.420 --> 08:52.300
That's why it is a special scope.

08:54.040 --> 08:56.860
So let's go back to this global keyword.

08:56.860 --> 09:05.530
So this way of using variables from the global scope I think it existed in PHP version four or even

09:05.530 --> 09:06.460
earlier.

09:06.550 --> 09:13.640
And I generally don't think it's a good idea to depend on global variables in functions.

09:13.670 --> 09:15.590
Let me give you some reasons.

09:15.770 --> 09:21.020
So functions main use case is for them to be reusable.

09:21.050 --> 09:29.870
If you depend on some global state this is tightly coupled with the global state which makes this function

09:29.870 --> 09:35.870
less predictable and I would say hardly reusable.

09:36.470 --> 09:39.800
Now it's also harder to test code.

09:39.800 --> 09:42.290
That depends on some global state.

09:42.290 --> 09:46.520
And another problem here might be some hidden side effects.

09:46.520 --> 09:51.140
You also need to be aware of the unexpected side effects.

09:51.170 --> 09:58.610
So imagine I am a new developer in a team and someone has created this function.

09:58.700 --> 10:07.400
Maybe this function does not only read the variable of superhero, because this is not really a dangerous

10:07.400 --> 10:08.180
example.

10:08.180 --> 10:10.100
We are just reading some global value.

10:10.100 --> 10:19.370
Maybe that's even fine, but maybe I'm gonna change it to spider man.

10:20.120 --> 10:21.290
And that's possible.

10:21.290 --> 10:22.610
You can do that.

10:22.940 --> 10:31.040
And me, as a developer that have just joined the company, I need to reveal the identity of some superhero.

10:31.070 --> 10:36.320
I'm calling this function and unexpected thing happens.

10:36.710 --> 10:44.300
I actually change the value of global variable to Spider-Man, and I didn't know that.

10:44.300 --> 10:50.030
So let's echo the value of superhero.

10:53.780 --> 10:57.050
So as you see, that's Spider-Man.

10:57.050 --> 11:00.890
So I've actually modified the global variable.

11:01.040 --> 11:04.070
Now it's a made up example.

11:04.100 --> 11:10.700
But I think you can see how this can be dangerous when you rely on some global data.

11:10.730 --> 11:17.640
So in this case I would prefer that you use the function arguments and then you are clear about your

11:17.640 --> 11:18.630
intentions.

11:18.630 --> 11:26.010
And also when you create functions that are then used by other people, they don't know all the details

11:26.010 --> 11:27.510
of those functions.

11:27.510 --> 11:31.080
So the name of the function should be very descriptive.

11:31.080 --> 11:35.880
And always remember not to put any side effects in a function.

11:35.880 --> 11:40.710
The function should do only what its name suggests.

11:40.710 --> 11:47.070
So if the name says reveal identity, don't change the identity, only reveal it.

11:50.040 --> 11:57.900
Now, as with the static variables, well, I think they might have some better use cases.

11:58.410 --> 12:07.710
So you can use that for the so-called memoization or caching, which just helps you keep some data if

12:07.710 --> 12:10.200
the computation is expensive.

12:10.200 --> 12:17.560
Let's imagine you've got an operation which takes a lot of CPU You power and you just want to keep the

12:17.560 --> 12:22.060
results stored someplace between subsequent calls.

12:22.060 --> 12:25.510
So you just save memory, you just save recalculations.

12:25.510 --> 12:31.630
So you save basically the compute and memory, which essentially is saving money.

12:31.630 --> 12:36.010
So maybe that's a sensible use case then.

12:36.010 --> 12:39.460
Well counters like this, maybe that's a good use case.

12:39.460 --> 12:46.900
If you have a specific example like this then there is something like a singleton like behaviour.

12:46.900 --> 12:51.820
Well I would need to talk about design patterns for you to understand singletons.

12:51.820 --> 13:00.010
Essentially, if you have a resource that should only be created once, that is for example a database

13:00.010 --> 13:08.560
connection, you might use a static variable inside a function to keep the reference to this connection.

13:08.560 --> 13:11.950
Then it might be something like this.

13:12.700 --> 13:25.030
You have a function called get db where you declare that static DB is, well, nothing, and if DB is

13:25.030 --> 13:25.570
null.

13:25.570 --> 13:33.100
So if it wasn't initialized then you somehow create the connection.

13:33.490 --> 13:35.710
So I'm just using made up code.

13:35.860 --> 13:42.610
There is no connect function, just showing you the example and then you always return db.

13:42.730 --> 13:49.750
So on all the subsequent calls to this get db function in your code, you are actually using the same

13:49.750 --> 13:56.080
connection that was initialized once and is being kept on all subsequent calls.

13:56.200 --> 14:04.600
This one is actually a very good use case of the static variables, if you would be using functions

14:04.600 --> 14:06.130
for this purpose.

14:06.220 --> 14:10.120
Okay, so let me comment this out because this actually wouldn't work.

14:10.150 --> 14:12.400
That's just an example.

14:12.460 --> 14:16.510
And by wouldn't work I mean there is no connect function.
