[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.<>[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