[Section 8] [Less Comfortable]
[Nate Hardison] [Harvard University]
[This is CS50.] [CS50.TV]
>> Welcome to our second to last section.
In this week we're going to talk about PHP, and then next week
we'll do a little review for Quiz 1.
We're going to start on page 3 of the problem sets pack,
and we'll work through the section of questions fairly quickly.
On page 3, we start talking about this difference between C and PHP
in the sense that PHP is a dynamically typed language,
whereas C is statically typed,
and has anybody really quickly done any coding in something like PHP
or Python or Ruby before, JavaScript?
Totally new? Okay.
>> All of these languages that I just mentioned
are very different from languages like C and C++ and Java
in the sense that when you declare a variable you don't have to declare
what kind of variable it is, so in C we were stuck having to always say
this is going to be an int variable, or this is going to be a char * variable,
whereas with PHP, with Python, with Ruby,
with a lot of these more modern languages you don't have to do that at all.
You just declare your variable, and in the case of PHP
you declare that it's a variable by prefixing it with a $ sign,
and then the type of the variable is determined by whatever value it's holding,
which is kind of cool.
To play around with this a little bit, we have sample PHP code right here
in between the start and end tags.
We're using this kind of like HTML in the sense that
we've got these angle brackets here to open and close.
You'll see this with HTML.
You'll see the same sort of syntax with XML too.
>> This indicates the beginning of a PHP block.
This ?php is specific to PHP.
We close everything with a ?> as well.
Let's open up a file in our appliance using whatever you'd like.
In this packet it says to call dynamic.php.
In truth, you can call it whatever you'd like, but the file name will come up
and be important later, so just remember whatever you call it.
I'm going to switch over to the appliance,
and I'm going to make a directory for
section 9 I believe we're at now.
And we'll go into section 9,
and I'm going to use gedit.
Let's see, gedit, and I'm going to call mine dynamic.php.
Boom.
Within dynamic.php, since this is a PHP file
and I want to run this through the PHP interpreter
I need to start everything off with those open tags,
so I'm going to start those right away,
give myself a little space in between the tags,
and then the point of this exercise was to play around with
this function called gettype, so gettype, this function right here.
>> Notice that there's no underscore or space or hyphen or anything like that
separating the 2 words, get and type, just one word altogether.
But what this will do is if I pass in a variable to gettype,
say $var or $x,
this will tell me kind of in a debugging format
what the name of that type is.
We're going to experiment here.
In particular, if you look back at the pset spec
we've got a few different lines of code here.
In the first line of code we initialize this variable, $var,
to be equal to 7, and then we have this printf line
that says hey, printf var is blank.
Printf is one of the many ways we can print things in PHP.
Often you'll see the echo function used instead of printf,
but printf we're all familiar with having been coding in C for a while.
What you can actually do is let's see if copy and paste works.
I'm going to give this a try.
We'll go back over to the appliance.
Okay, and there we go.
And spacing is a little funky, but here we go.
We've got this code in here.
>> [Student] Is it not good style to tab it?
Sorry?
[Student] Is it conventional to tab it?
Right, so Sam asks if it's convention to tab it or not.
Typically yes.
In this case I have chosen not to.
Honestly, you'll see different things among different programmers.
PHP is typically used often in combination with HTML
and other languages, and so sometimes the printing will look a little funky
if you indent within PHP start and end tags.
It really depends.
In this case the copy and paste didn't paste the tabs in for me,
but it definitely does, like you said, make it clearer.
All right, if you save this code in dynamic.php
then what you can do is come down to your terminal window where I am right down here
in gedit, and to do the equivalent of compile
using make and then running your code in C
all you have to do with the PHP file is start up the PHP interpreter,
which is a little program called PHP,
and the argument you give to the interpreter is the file you want to interpret.
In this case, dynamic.php.
Whoops, where did I put it?
Oh, I put it in section 9, and here I am. That's why.
>> Now if I run that again
we see that in my first gettype function call
var is an integer.
In the next one var is a string, and then in the third one var is a boolean.
What's interesting about this is if we scroll back up we see that
these are types similar to the ones that we had in C.
We had ints in C.
We sort of had strings in C,
so strings weren't a totally legit type in the sense that
our CS50 string was really what?
Sorry? Missy?
[Missy] Char *.
Yeah, it was this char * we used.
At the very beginning of the semester we were using the string type,
but it was really a char * under the hood.
We just type defined it, whereas in PHP these strings are an actual type.
There's no more of this char * type stuff.
>> You'll see that we can do many more things with strings
much more easily in PHP than we could in C,
and then finally, we have this boolean type, and the big difference here is that
if we scroll back down we see that the name of these types
are now integer, string, and boolean instead of int and bool,
and as you pick up different programming languages,
assuming that at some point in your lives you will come into contact with
different ones you'll notice little quirks like this
where C calls integers ints.
Some call it integers.
There are other terms that you'll run into.
Big int we saw today in SQL.
There are also number and then bool, boolean,
all sorts of differences there.
>> This isn't terribly interesting but now I'm going to give you a little bit of time—
if we zoom back out—to work through this exercise at the bottom of page 3
where it asks what types correspond to these values here at the bottom.
We have 3.50.
We have this thing right here, which is interesting.
We haven't seen that before, though if you've been following along in lecture
you probably already know what that is.
Then we have this, which this is kind of funky.
You recognize this.
What is this in C?
Sam? What would this give you in C?
It would open a file called dynamic.php and make it readable.
Yeah, and what would be the type of variable that we would assign this to?>>File star.
Exactly, we would assign this to a file star.
This is legitimate PHP too.
Run that. See what happens when you pass that into gettype.
And then also check out what null is, what that might be in PHP.
I'll give you a couple minutes.
You can literally copy and paste these values in,
and then we'll do a little random call on you
and see what you got.
>> [Student] I have a question.<<Yeah.
In one of the lectures David said there's something you can put at the top of your file
so that you don't have to type in PHP every time.
What was that?
He was probably talking about the pound bang, the hash bang.
It's a directive that if you mark your file as executable
then what it does is when you execute the file
it will tell the shell program
to use the PHP interpreter to interpret the contents of the file.
The question being what was this special line
that we could include at the top of our PHP files to not have to include
this PHP line or this PHP command whenever we want to execute the file?
And you can actually do this with a bunch of different files.
I believe it depends on where the PHP binary is stored,
but often usr/bin/php is a good place to start.
You can figure this out exactly by going back down to your appliance
and typing out which php.
The which command figures out when you're executing binary
or a command where the corresponding file is.
This tells me that the PHP is really aliasing this binary file
that's stored in usr/bin, which is where a lot of the system binaries are installed.
For example, if I scroll up to the top, now that I've put this #! line in here
I can scroll down, and I can try to run
dynamic.php, but I get this error about permission being denied,
and what that means is that this file is not currently giving executable permissions.
It's not marked as a file that somebody can run.
>> When you ran Make or Clang and you got an executable from it
the compiler was smart enough to know that hey, I'm building an executable.
You probably want to execute it, so it would automatically configure
the permissions for you.
This isn't the case, though, when you create a normal file from scratch,
the reason being typically you don't want to have any file on your system be executable,
so you actually have to go in and manually do it.
The easiest way to do it is with the chmod command,
and chmod +x says add the executable bit
because there's the read bit, the write bit and the executable bit,
r, w and x,
and saying chmod +x will turn on the executable bit
for then the file that we specify, which in this case will be dynamic.php.
>> [Student] Is that turned on for everyone?
Let's check this out, so how would I check to see the permissions?
Do you know how I'd check to see the permissions of a file?
[inaudible student response]
Sorry?>>[Student] XSD.
XSD gives us the file in hacks.
Listing all the files, -l, will show me all of the files in my directory
kind of in their long, verbose listing, and so here we see that
this dynamic.php file
was last modified November 5th at 4:21 PM.
The owner of this file is jharvard.
That's the user who is logged in.
That's the user I am working as,
and if you're also in the appliance you're also working as user jharvard.
You're in the students group,
and these are things that you'll see often enough.
>> We can go into a lot of detail here,
but for the most part what you want to look at when you're looking to see
whether or not a file is executable is primarily
the user who owns the file, the owner,
so this jharvard, and then we have
the permissions bits over here on the left,
and the way to read this is that the last bit
typically is used for marking whether or not—at least in this case
this last bit will often be set to a d to indicate
that the file is a directory and not just a normal file.
Then the following 3 bits right here
determine the permissions that the owner of the file has,
so in this case jharvard, as the owner of the file, can read and write this file,
but there's a dash saying that jharvard can't execute this file.
The next 3 bits are for the group, so this is the students group,
so if there were multiple users on my appliance,
and we had multiple users as part of the students group,
then they can all read this file, but they can't write it,
and likewise anyone else, the world
can only read this file as well.
There's a good, long writeup about this,
so you can read online.
In the problem set spec we go into this in more detail.
>> [Student] Is the 218 referring to the world?
The 218 is—off the top of my head I'm forgetting,
but no.
Let's see. I am blanking on that right now.
Back to what we were about to do with this chmod +x
where we wanted to give dynamic.php executable permissions,
and the question was whether or not this would give executable permissions to everyone
or to just jharvard, and we can see this by
running the commands and typing ls -l,
and now we see that it's marked as executable.
You see that there was a color change.
Now dynamic.php is listed in green,
and it looks like the answer to the question is what, Charlotte?
[Charlotte] Only jharvard.>>Only jharvard, yeah.
>> If we wanted to turn the executable bit on for everybody
how might we do that?
Any thoughts?>>A + x?
Yeah, exactly.
Charlotte said we can do chmod of a + x of dynamic.php,
and now if we run ls -l we see that the executable bits
are indeed turned on for everyone.
And you can actually do the reverse of this, so you can turn it off for everyone
using minus.
Now it's turned off, and now we can turn it back on for jharvard
so that we can actually run it now,
and now you see when we run the code this special #! line at the top,
#! line, told the shell,
told our terminal hey, when this file is run,
use /usr/bin/php to interpret this file
and then print the output.
[inaudible student question]
Sure, let me scroll back up. Just like this.
You'll see all of these directives start with this pound and then the exclamation point,
sometimes called a shebang, hash bang.
>> [Student] How can we run it with php dynamic.php before we make it executable?
The question was how can we run this using the PHP binary
while dynamic.php is not executable?
This is super important because this is exactly how
it's going to work when you write problem set 7.
Most of the time PHP files are not directly executable.
The way that works is because it's the PHP binary that's executable.
The interpreter is the thing that's being executed,
and so what it's doing is literally slurping in the entire contents
of our dynamic.php file and going line by line
and executing those commands, so it's using our PHP file
as a list of instructions.
It's not directly executing it.
That's where we say that these files are interpreted at run time.
It's a run time language instead of something that's determined at compile time,
not a compiled language like C.
>> Is there a way to get a run time language to act as if it's a compile time language,
like if you have all the running done at the server
rather than—you know what I mean?
Yes, so the question is
is there a way to get run time languages to act more like compile time types of languages?
And there are, I mean, that is an active area of research for a lot of these companies.
I believe Facebook has done a lot of work with PHP
and compiling it down, making it faster, optimizing it
since their site is built on PHP.
If you've been following node.js at all,
which is kind of a JavaScript interpreter
to be able to run JavaScript outside of the browser, outside of your web browser,
because traditionally JavaScript would just run inside of Firefox or Chrome,
and it would be used to make cool animations happen on a web page
and make your web page dynamic.
That's been built on a lot of work that Google has done
to make JavaScript and C++
bind together, so there's a lot of active research to
get these languages to interact and optimize them,
primarily because so many people can code in PHP and JavaScript
because it's a lot easier.
It's a lot nicer. You don't have pointers.
You don't have types floating around.
They wanted to gain the benefits of these compile time languages
with all the type checking and the speed and the lower memory usage and all of that
while still maintaining the flexibility and ease of use of these newer ones.
>> Back to our original plan of attack.
We've got a few of these questions here in our problem set spec.
Let's go through them really quickly, and we'll go around the room.
Charlotte, what type is 3.50?
[Charlotte] That's a double.>>It's a double.
Jimmy, what is this next one?>>An array.
An array, awesome, and Jared, what is the fopen?
[Jared] It's a resource.>>It's a resource.
That's kind of a new one, not a file star, not a file.
It's a resource is the type in PHP,
and I'm sorry, Ella, the last null is what?
Null.
Null, how is it spelled in PHP?>>The same way.
The same way, capitals?>>Yeah.
Yeah, all right.
Here we go, we've got a double, we've got an array,
we've got a resource, and then we've got null.
Let's see now have you seen—
let's see, so now I guess what I also want to do is pull up
this web page right here, this php.net/manual,
so if you guys copy that and open up a web browser.
I'm going to pull up Chrome, put that in.
I want to show you this not just because
we can talk all day about types and all that fun stuff
but rather because this is the PHP manual,
and there are a lot of PHP programmers out there.
There are a lot of PHP websites out there,
and as a result, there is a lot of documentation on PHP,
and the manual, this php.net, is a really good place to go
whenever you're having questions about what's the best way to do X in PHP
or what does a function look like?
Just kind of getting familiar with what this looks like because
you'll be coming here often, a bit for problem set 7.
>> If you end up doing a final project that uses PHP
this will be a place you'll become very well acquainted with.
Often the way people do this is they use Google to search for the site,
and they don't use the search box that's up here in the top right, which is kind of tiny.
If you're Googling around for something to do with PHP and you see
one of the manual links pop up you can typically rely on that
as a fairly good resource.
Awesome, so out of these types, just out of curiosity,
which ones haven't we seen?
Anything we haven't seen here?
[Student] Resource.>>We saw resource with the fopen call.
[Student] Objects.>>Objects we haven't seen for sure.
Callbacks we haven't seen.
There are some of these pseudo-types.
We definitely only saw integer and double.
We didn't see some of the others, so if we click on integers
we can see are there any other integers that they have here?
Are they all—so integer, integer, integer.
Some languages have bigger integer types,
like we saw on MySQL today there was int and then big int.
Cool.
>> So, PHP manual.
Let's go back to our problem set spec, and we'll now scroll down to page 4.
One of the things that happens when you get these languages
that don't have this static typing, so these languages where you have to declare
the type of a variable up front
is you get cases where you might start having variables of different types
interacting with each other,
and PHP does this thing where it tries to do
what it considers to be the most sensible thing to do
when you have 2 different types interact with each other.
For example, if we look at these lines of code right here
you see that we've got what happens when
we try and add the string 1 to the integer 2.
What happens if we try and add a string that is not a numeric value
but rather actual characters, CS to the number 50?
Then we'll see is there anything different that happens where
instead of adding a string to a number we're adding a number to a string,
and so on and so forth to the point where we're getting
some kind of weird stuff right here where we've got 7 + true.
What the heck does that mean?
>> If you guys go ahead and paste some of this code into your appliance.
You can keep it in dynamic.php.
We'll see what happens.
[Student] Just use print, not printf?
Yeah, so you'll find that print is also a valid function for printing in PHP.
There are many different ways of doing it.
We'll see with a couple of the examples later on once we start talking
about the unique problem that we're going to write
and then the concentrations problem that we're going to write
that even though we have fopen and fclose
that's often not the simplest way to read in the contents of a file.
PHP has a lot of these C-like holdovers.
[Student] When I put in all 6 of those things I only get one number as an output.
[Nate H.] When you put in all 6 of these things.
Let's see is it because it's possibly—
one thing is that these print calls are not terminated at the end with new lines.
There's no new line separating each of these print calls,
so maybe you're getting one large number,
and it's really just amalgam of new line characters.
[Student] Okay, how do I make sure—
Well, there are a bunch of different ways.
You could manually put in a print of a new line character,
an echo of a new line character,
print of new line.
[Student] So echo is the same thing as printf?
>> Printf is like C printf
where you're printing a formatted string.
You're supplying it the format string and then all the placeholder variables.
It's often something that isn't used—
let's see, as a disclaimer,
I am less familiar with PHP than I am with other web languages,
and when I have programmed in PHP I typically don't use printf
because I find it faster to use the string interpolation capabilities that it has,
which we'll go into and I'll show you in just a second,
whereas in C we kind of have to do this hacky thing to get it to print out properly.
You can actually put variables directly into strings in PHP.
Printf is kind of overly long for what I usually do. Yes, Ella.
[Ella] Generally if you get parse error does that mean—
like on C it doesn't tell you exactly where the mistake is and what it is,
so does that mean look through your entire code and figure it out?
It's typically more targeted than that.
I think in that case it was a little off,
so I think in that case we were missing a semicolon.
It was trying to make sense of everything,
so like these interpreted languages, the interpreter is going to try
and do its best to make everything work appropriately.
>> You'll see, for example, in JavaScript
you'll often—line statements end with a semicolon just as they do in PHP,
just as they do in C.
In JavaScript some of the JavaScript interpreters
in a lot of the browsers will put in semicolons for you
if you happen to be missing them.
They'll try and accommodate for some sloppiness on your part.
That's where it might be trying and trying and trying to make things work,
and then finally it will get to a point where it says okay,
I can't make things work on bailing, and that's where you'll get a line number
that might seem a little off from the exact place.
Okay, so let's go through this really quickly.
We left off with Ella, so let's go over to Missy,
and Missy, what does print of string 1 plus the number 2 give you?
[Missy] 3.>>3.
Does that make sense? Sort of?
Does it give you a number? Does it give you a string?
[Missy] A number.>>It's a number.
But it's printing it, so it's going to give you some sort of string.
>> One thing we can do to check this out
is if we do $var = 1 + 2
and then we say echo of gettype,
so we're using a third kind of printing here.
Now we can see what happens here.
Here what we've got is we got an integer out of this.
Even though we were adding this string to a number,
we didn't get a string out of it, just like Missy said.
We were getting an integer.
Okay, so let's see, next up, Kevin.
CS + 50?>>[Kevin] 50.
[Nate H.] 50. Does that make sense?
[Kevin] Yeah.
[Nate H.] Why? Why does it make sense to you?
[Kevin] Because it's just having the string, having number value zero.
Yeah, great.
Kind of ambiguous situations, but it's good to know what happens.
Stella, what happens next with number 1 + string 2?
[Stella] 3.>>3 again.
And in this case, do we get a string or a number?
>> Let's give this a try.
Anybody faster than me get the answer? Charlotte?
Oh, I didn't—okay, let's see, we're going to do the same sort of thing
where we've got a number plus a string, and we're going to echo the type,
see what we get.
We also get an integer.
It doesn't matter which one is the string, which one is the number.
We're still going to get an integer.
It's still going to do what we might expect.
All right, so Sam, what about 90 + 9 bottles of beer on the wall?
[Sam] 99.>>99.
No bottles of beer on the wall, though.
It gives us a little more information about what's happening.
[Sam] If you had written 9 in letters
then you would have 90, right?
[Nate H.] Yeah.
The question was if we'd written 9 out as N-I-N-E
would we have gotten 99 or 90?
We'd get 90.
It's literally just looking for digit characters.
It's not smart enough to recognize number words and that stuff. Yes.
>> [Student] Is there such a thing as typecasting in PHP?
There is, and it's exactly the way you would do it in C.
What about 10 / 7, Charlotte?
[Charlotte] 1.4285.
[Nate H.] Yeah, so what might be surprising about this?
What would happen if you did this same sort of thing in C,
if you did 10 / 7 in C?
[Charlotte] It would only give you—depending on how you typecasted I guess
it would give you only a limited number of digits after the decimal.
Yeah, so a limited number of digits after the decimal.
What else might be—would it give you any digits after the decimal?
Often not, so again, depending on how you're typecasting it
it may or may not convert it to a floating point number.
Here it was kind of nice that it did.
Had we shown you this back when we started doing this kind of stuff in C
it probably would have made a little more sense
that it doesn't just go to 1.
And then finally, Jamie, what about 7 + true?
[Jamie] 8.>>8.
What does that mean?
I guess it just gives true the value of 1.
Yeah. What happens if we change that to false?
[Student] 7.
Yeah, so remember where we talk about these binary values,
1 being on, 0 being off?
Now we have true is 1, 0 is false,
and you might not have seen this in the C examples that we've done this past semester,
but historically the bool type in C hasn't been a real type,
so people have used 0 and 1 in the place of true and false.
This is a manifestation of that.
>> Okay, so the one important part about all this
is that we have these different types.
They can interact with each other.
They can often interact with each other in ways that are nice, as we've seen here.
It's nice to be able to have string 1 and the number 2, add them together and get 3.
That makes sense.
However, when you're writing websites, and especially when you're processing
user input, so say you've written a web form
that collects information from the user and then goes to process it
on the back end, on the server side in your PHP code
if you're expecting that value that the user typed in and submitted
to your form to be an integer or to be a floating point number or something like that
you need to explicitly cast it
and then do some type checking.
>> You don't want to just rely on this type juggling system to make things work out,
especially for security reasons and just for the robustness of your website.
Just something to keep in mind that whenever you're handling form data,
anything that comes in the post or the get superglobals
make sure that you always validate it and convert it and typecast it.
And just like we were talking about a moment ago that typecasting
in PHP is exactly the same as in C where you have the parentheses
and then the type.
Keep that in mind.
One function that will come in handy when you're doing this
is we've been using—and this is kind of as an aside—
we've been using this gettype function right here
to figure out the type of a variable,
and while this is handy for debugging and to see what a variable's type is
you don't want to use this, for example, in a condition where
you're checking to see if gettype of $var = integer do something.
This is bad, bad, bad.
Instead there are these functions called is integer, is string,
is array that you want to use instead, so in this case
what I would want to do instead of this guy right here
is use the is integer var.
And they're often referred is is_* in the sense that you could replace the * with integer,
string, et cetera, and just to make sure really quick
is this is int php.
Looks like you can do either is int or is there is integer as well?
Yes, alias, so int integer aliases.
Cool.
>> How are we doing?
Let's pick up the pace a little bit.
Now we're going to talk about arrays, so as you can see
in the next part of the spec we talk about how arrays in PHP
are slightly different than they are in C.
In truth, they're kind of an amalgam of
the arrays that you've come to know and love in C
where everything is of the same type
stored consecutively and contiguously in memory,
and you have these numeric indices.
You have index 0, index 1, index 2,
and you store values at those indices.
You also in C, when you wrote Speller, a lot of you
did the hash table approach, and you saw that there we had
a different kind of storage where we were mapping
a key to a value, so when you tried to store something in hash table
you had to specify that you wanted to store it with a specific key,
and that key determined the location of the value and where it would be stored.
You've kind of got both of those concepts happening at the same time in a PHP array,
and as a result, we often call these associative arrays
where we are associating a key in a value.
In this next part we talk about a simple PHP array
where we have keys a, b, and c,
all strings, mapping to the integers 1, 2, and 3.
And you can have keys of different types.
>> You can have some keys that are strings, some keys that are integers.
You can have values of different types.
You can have a value that's a string, a value that's an integer,
a value that's an object or another array, for example,
all in the same array object, which is kind of weird.
You don't have to have an array that's just got one type of element in it.
You can have many different things going on in there.
The other thing to note is that when you do see something like this in your code,
which is valid PHP to declare an array just like this, 0, 1, 2, 3, 4, 5,
that will declare an initialized $arr to be this array.
But what you're actually getting under the hood is this kind of implicit
generation of keys where we've got 0 to 0, 1 to 1, 2 to 2, 3 to 3.
And it turns out that even if you do have an array like this guy up here
where you have a, b and c as the keys
and then you start using the array push method to start using this array like a stack,
so you can see that this array object, this array is really becoming overloaded.
We can use it as an array. We can use it as a hash table.
We can use it as a stack.
When you start pushing things onto this array
the first thing you push onto this will be index 0 and then index 1 and index 2.
You can get this kind of implicit generation of keys
unless you specify them explicitly.
The way you specify keys explicitly, of course, is by using this bracket notation,
which is similar to arrays except instead of only allowing
integer indices in here, now we allow anything.
If you want your key to be a string, you'd specify it like this.
If you want it to be an int, you specify it with the int you want to use.
>> Questions on that so far?
One of the nice things about this idea
is that you can only ever have one value stored with a particular key.
If we go back over to our appliance—let me delete some of this stuff.
And let's say I initialize an array to be 0, 1, 2, done.
If I now know that, for example, if I echo $arr[0]
I'm going to get the value 0 printed out,
and since there can only ever be one value stored for a particular key
if I store something at $arr[0], say a,
then I know when I echo $arr[0] again
I'm not going to get 0 printed out as before.
I'm only going to get a.
So this is basically saying that I can't have $arr[0] storing 2 different values.
It can't store both 0 and the string a, like this literally replaces
what was at $arr[0] previously.
The reason I bring this up is run it, see what happens.
See here that I got 0 printed out and then a down here.
There's no new line there because I was lazy and didn't put that in.
What's cool about this is we can use this as a way
to capture this idea of a set
where we can't have multiple keys within an array.
We can't have identical keys within an array.
I can't have key 0 and value 1 and key 0 and value a
or key 0 and value true.
The keys are all—there's only 1 key in the array.
Even though you can have the same value stored
multiple times in the array under different keys
it's not possible to have identical keys multiple times in your PHP array.
>> If we look at this next problem, unique.php,
where we want to open up a PHP file
containing a list of strings, one string per line,
and we want to find all of the unique strings in that file
all we have to do is use one of these PHP arrays
and use the strings in the file as the keys to this array
and keep updating our array as we store these new keys.
As we read each line out of the file we can store it in the array,
and at the end we will have as our keys in our array
all of the unique strings within the file.
Does that make sense?
Let's see how this works.
We're going to open up, according to the spec, a new file called unique.php.
Open. Oops, sorry, new file.
We're going to start it off with the same start and end tags.
We're going to save it in section 9, and we're going to call it unique.php.
Okay, now zoom in.
The idea here is open a file,
read in file line by line.
For each line in file
we'll have an array where we have
the line as our key.
And then when we get to the end here
$arr's keys are the unique lines
from the file since we know that if I put line into this array
multiple times it will just keep overriding the old value,
and we can actually put array line in as itself just like that.
>> This is kind of weird.
We're storing the same key value pair over and over and over again,
but since we are guaranteed that there will be only 1 key called line
so if we have a file that says—a file of animal noises and it has woof, woof,
meow, meow, moo, moo, and each time we read an animal noise out
like woof and we store it in our array we get woof, and then the second time
we store woof it will overwrite the first time that we stored it.
In the end we'll only have one entry in the array
for each of the animal noises in our animal noises file.
Do you guys feel confident that you can tackle the opening of a file in PHP?
One way to do it—let's go over this quickly—one way to do it
is with fopen, like we saw earlier.
You can fopen some_file.txt.
You can open it in read mode, just like in C.
That's one perfectly good way to do it.
You also then for reading in the file line by line
have the same functions, many of them, that you did in C.
You have fgets.
You have feof, though we don't like using that
because, remember, that was not great in C.
You can do it the same way,
but here is a really cool thing.
Sorry, I don't want to do $file, but there is a function called file in PHP,
and this function right here is cool because it reads the entire contents
of the file that you specify, so some_file.txt,
reads the entire contents of this file into an array
and then lets you iterate over it, which is pretty nifty.
>> If we go, for example, to our web browser
and we look at Google for PHP file
you can see here that our manual says that file reads entire file into an array,
and we can file_get_contents to return the contents of a file as a string,
but typically just getting it as an array is really nice because what it does
is it breaks it up so that each element
in the array is one line of the file,
so if we look at file 0, that's the first line of the file.
File 1, second line, file 2, third line, and so on and so on.
Wouldn't it be nice if that was all you had to do in C?
Pretty nifty.
David showed this in lecture, and the idiom he showed was
that in addition to our standard for loop—in PHP we had that
for ($i = 0; i < 10; i++),
and you can do this in PHP too, same thing—
we also have this cool construct called foreach.
Foreach is really handy when iterating over arrays or these data structures
because it allows you to pull out each element of the array
without having to manually do the indexing yourself,
without having to manually create an index variable, increment it,
pull out the value in the array at that point, because that's a very common thing to do.
>> You probably have done that tons of times when you were doing C stuff
over the semester, so with this foreach
we can loop over this file array,
and the syntax is that we want to now loop over this array
and specify that the variable we're going to use to store
the element of this array locally, local to the scope of this foreach loop,
is we're going to call it line.
If it's a file of just words and there's one word in a line
we could call it word as well, really just you give this a name,
whatever you want to call it,
and then inside the loop you can do whatever you want with this variable line.
If it's not enough to get the value of the array and you also want to get
the index along with it you can specify a name for the index
as well as the value, and now you have access to 2 variables.
You have $i and line
where $i is the index in the array,
and line is the line that you retrieved from the file.
For example, if we wanted to print out echo line 0 of the file as this,
we could do it just like this, "Line $i of the file is $line,"
and here is something we also haven't seen yet either
where I've just totally skipped over this whole %s %d business
that we had to deal with in C, and instead I've gone straight to
writing the variables in line in my string.
>> This is called variable interpolation, string interpolation
where you're stuffing the variables right in, and the PHP interpreter
is smart enough when it's reading through a string that begins with double quotes—
not single quotes, with single quoted strings you can't do this—
but with double quoted strings as it reads through it's looking for variables.
It's hunting them down, and if it sees variables it will take the value of the variable
and stuff it into the string if it can convert it into a string representation,
which is pretty nifty.
For now, let's comment out the rest of everything,
save this, and what we can do now is we can open up a file
that we can call some_file.txt—let's create a new file—
and we can put in a bunch of nonsense stuff in here just to test everything out,
save it, call it some_file.txt, as I'm doing up here at the top,
and now if I zoom out just to make sure everything is in the same directory—
it looks like I have unique.php and some_file.txt in the same directory.
If I run php unique.php
see how it prints out each line in my file and what the line is?
>> That's pretty powerful, right?
Look, it took 3 lines of code to open up a file.
Well, 4 lines of code. I can't count today, clearly.
But really just 2 interesting lines of code, because the other 2 were the curly braces,
but in this much code we were able to open a file, iterate through it,
pull out the line number and the line itself
and print it out.
Cool stuff. Charlotte.
[Charlotte] I have a question about the syntax.
So foreach deals with every single line of the file that you open,
and then when you want to do things with every single line you just do it as
and then associate the value.
[Nate H.] What you can do right here—the question was
the foreach has to do with the array, so the foreach syntax
is really foreach, and notice that there's no space
or anything between the for and the each.
They have to go right next to each other,
and then it takes in an array,
and then you have this other keyword called as that has to be there,
and then after the as you can either put one variable name,
in which case you're going to be pulling out the values of the array,
not the indices, or if you do it as we've written below
you get the keys and the values.
You have foreach element of the array or pair of the array as keyed to value
or as just value.
Depending on what you need, if you don't need the keys,
then you can go with the value.
If you want the keys you can go with them too.
>> [Charlotte] I also realized we never declared the i or line.
How does it even know what they are?
[Nate H.] What do you mean by declare?
[Charlotte] We never told them what i or line means.
[Nate H.] We never told the computer what i or line means in terms of—
[Charlotte] That they're indexed or that they're—
[Nate H.] We never told it that this is supposed to be the index or the key and the value,
and that's because that's the PHP interpreter.
This serves as the declaration and says okay, the key is going to be
a variable called i stored in a variable called i.
The value is going to be stored in a variable called line,
so this serves as the declaration of these variables
and says $i is a key, and $line is a value.
Yeah, Ella.
[Ella] If the keys aren't done numerically
how does it decide what order it's going to print everything?
Is it just like the order it's entered in?
[Nate H.] Let's give it a try.
Let's create a variable called arr,
and we can do a goes to 7.
Let's say 0 goes to another array with 1, 2, or apple.
Let's say 7 goes to 1, b goes to 2,
and 3 goes to 4.
This is kind of a crazy looking example because we're mixing up
strings and integers all over the place.
There's no real order to this array.
I mean, we could order everything in alphabetical order by the keys.
We could order everything alphabetically by the value.
>> We could try and take into account that some are strings, some are ints,
and we could try and convert them all to the same type and see what happens,
or we could consider them in the value in which we already entered them
where we put this guy in first, this guy in second, this guy in third,
this guy in fourth, et cetera.
Let's see what happens when we run this code.
If we scroll down and do the same sort of thing,
and here it's not printing out the new lines.
When it read things out of the file it was including the new lines in the values,
which was why it printed out nicely, whereas here it didn't,
so that's why everything is smushed together.
Let's add in that new line just to make things nice.
Let's rerun it, and so here
look at what happened.
It printed everything out in the order in which we put it into the array.
It does preserve order in that sense.
>> Going back to this problem of uniques
where we want to be able to iterate over a file,
and we'll give it some_file.txt,
and we're going to iterate over it like this.
We said that we wanted to use an array to make sure that we'd got all of the
unique lines out of there, and we could do that really easily
by just storing in an array that we of course declare outside the scope of a loop,
and we said that if we used the lines in the file as the keys in our array
if we entered a duplicate line we'd be overriding the previous value.
It's not ever possible to have 2 keys that are identical in the same array.
We can do just that.
We'll get rid of this echo statement right here.
Here we're storing the line in the file in our array
using itself as the key.
Nothing to it, and it turns out that we don't even need this key.
We don't need that i variable.
At this point if we were to do another foreach loop
and we were to loop over each arr
and line now if we echo—oops, sorry.
We can't use the comma. We have to use this as keyword.
Now if we echo line we should get all of the unique words in the file.
If we go up to some_file.txt,
and let's say we do apple, banana, apple, apple, banana,
if we're printing out all of the unique words in this file we should only get
apple and banana to print out.
If we save this, now here we'll zoom back in,
php unique.php, and ta-da.
We've successfully uniqued the file.
>> The final part of this problem is asking you to sort this array before you printed it out
because in this simple example that we've just done
we were lucky in the sense that the file—
we did this contrived example with apples and bananas.
It was already sorted.
But using the simple sort function you can sort an array, which is pretty nifty.
The final thing I wanted to talk with you guys about really quickly
is that this kind of PHP is all well and good, and it's super handy
to know how to do if you ever need to do little, quick things programmatically.
For example, if I need to write a program that, say,
puts everybody into sections I'm not going to go and write it in C.
It's going to be long.
It's going to be kind of a pain, especially if there are files involved,
just as you guys have seen.
It's so nice that with just this much code right here
we were able to rip through a file, pull out all the unique values
and print them back out.
>> However, for your assignments, for your projects,
if you're building websites with PHP the power is that
we're running our PHP files through this interpreter,
and the interpreter is processing everything within the PHP tags,
leaving everything else untouched and spitting out the results.
We can do this to build HTML programmatically.
Now, if we go back to the spec, the last problem in the spec
talks about this idea of concentrations
and creating a drop-down menu,
which you may or may not want to do, depending on what your final project is doing,
that allows the user to select from a list of all possible concentrations
their one concentration.
Now, this is kind of a pain to type this out
and have to do all this manually, especially when you're having to make sure
that you have all the angle brackets in the right place and all the quotes in the right place,
so with PHP you can do this programmatically, and you can do this really quickly.
>> Let's see how to do this.
We're going to open up a new file.
We're going to put in our PHP tags.
We're going to call it concentrations.php,
and now when you're doing this, kind of a good thing to think about
when you're trying to mix and match your PHP and your HTML
is figuring out, okay, what is the part that I want to programmatically generate?
What is the part that I can programmatically generate?
It's true that you can do all of your HTML
inside of PHP blocks.
You can echo all of the HTML as strings.
For example, if I want to start doing the select tags inside of PHP
I can say echo, say select name = concentration,
and then down below I could have another echo tag
or another echo called close the select.
This is one way to do it because what this is literally going to do
is print out this string when it's run through the PHP interpreter,
so the result will be HTML.
If I save this file as it is right now
and I run php concentrations.php
look at what I got.
I got this open close select tag.
>> If I were to do this and I were to save this result to a file,
say, concentrations.html—wait, it looks like the l has gone over to the other side—
now if I open up here concentrations.html you see I have a valid HTML file.
Is that kind of weird?
We're using PHP to create HTML, create valid HTML.
The way we're doing it is we're just having the PHP print
the HTML that we want it to print.
This is literally how PHP websites are working.
When you visit a website that sends you to something like
something, something, something dot com slash index.php
the computer is literally calling up index.php,
running it through the PHP interpreter, and whatever junk comes out
it's sending back to the browser and saying hey, browser, interpret this as HTML.
The nice thing is that it can be a pain to constantly write echo, echo, echo, echo
and enclose everything in quotes like this, so if you want to write
the HTML that's going to be static yourself you can do it like this,
put it outside, close it,
and then here you only put inside the PHP tags that which you know
you want to programmatically generate, and in this case it's those option tags
that are a pain to generate.
>> For example, we could generate a thousand option tags
by doing something like this, $i < 1000, i++
and saying echo option value = $—whoops, I can't do that.
Well, let's give it a try and see what happens.
$i and then saying $i</option.
Rather than having to type out that option tag a thousand different times
I'm using PHP code to generate it automatically, programmatically.
Kind of nifty. Yeah.
I remember this being mentioned in either the lecture or the walkthrough,
but what's the difference between the quotation marks,
the normal ones and these single things?
That's actually something that I've done incorrectly here that I was going to show you.
The single quotes don't allow any special characters,
so everything inside a single quoted string is interpreted literally.
If I had a \n inside of single quotes and I save this, for example,
and now I go down here and run it—
oops, where am I going?
Oh, it's because I forgot the $.
>> Now if I open up—actually, here, we'll get rid of the typing it to a file.
We'll just read it.
Here you see that I've got this literal \n in the string, like not an actual new line,
and likewise, instead of actually interpolating the value of this variable
it gave me the $i itself, which is kind of a pain.
The way around this is to use the double quotes,
and then when you use double quotes it will actually
properly interpolate the values of all of these variables in here
and also recognize this \n to be the new line that it is
and not \n.
Using the single ones is nice when you have
characters that might be interpreted as special characters because then you don't have to
escape them constantly.
Things can get messy, and often the way I do it,
just to make things easy, is that if I'm going to have anything
HTML like in my code I'll include edit within single quotes
and then use this concatenation operator
to concatenate the variables in.
This is another way of doing it
where we've got the dot that's going to connect this is a string
with this with this with this,
and now I don't have to escape these double quotes.
I don't have to use this guy to escape.
They'll literally be printed out as double quotes and then this guy right here.
This is another way of mixing everything together.
>> [Student] Also, when you echoed gettype there were no quotation marks at all.
Right, so echo is kind of special in the sense that you don't need parentheses.
You don't need to have the quotation marks necessarily around variables,
like it's valid to say echo $i, and it's going to interpret this as a string.
It's going to do the cast, so we could do this, and that's valid too, but we don't need it.
It's optional.
In this week's problem set look out for a lot of this kind of stuff
where you're mixing and matching HTML with PHP
just like this, and now if we scroll back and we run this
we can see that we have a whole bunch of option values
that just got printed out.
We have all this HTML that got generated really quickly for us.
I'll leave it as an exercise.
It's very similar to the file reading that we did earlier.
>> There is a concentrations.txt file that you can pull down from the CDN,
and you can open it using the same foreach trick that we did earlier,
and foreach you just have to echo an option and plug in
the appropriate values, the appropriate keys and indices,
and then you get a drop down that literally creates
programmatically for you all of the different concentrations at Harvard.
A handy thing to have.
There is a lot of configuration stuff for this assignment.
If you haven't done it already take the next half hour, hour,
some time tonight definitely for sure,
walk through the problem set spec,
see what's going on with setting up the vhosts, the local host, all that stuff.
One thing to point out right now is that
in most problem sets we've been going into your Dropbox folder
and then downloading the problem set zip file and unzipping it.
For this problem set you don't want to.
You want to go into this vhosts directory.
You'll want to go into vhosts and go into the local host directory within it,
and this is where you'll want to pull down the zip file,
unzip it, and get ready to go.
You'll have to follow the steps closely.
>> If you have any questions, send email, post it on Discuss, come to office hours.
Thanks guys. Next week we're going to have a review session for the quiz.
Enjoy your last problem set. I hope it all goes really well.
[CS50.TV]