[ Background sounds ] >>This is CS50. And actually this is my Halloween costume. Actually -- [Applause] >>Actually I wasn't quite sure which one to wear. We can raise the house lights now. I also debated between this one here, if anyone's of interest. So I thought at least Rob is here. Rob would you like to come up and be Team Boden today or with Boden fever? Come on awkwardly up. Woo! [ Applause ] >>I have Boden fever. Okay. >>So now -- all right. So I'm the one who has to wear this now all day. So we left off -- recall -- introducing something completely new after we left this. So this was an actual screenshot from one of your classmates that frankly probably kind of summed up how you've been feeling the last week or so. Actually happened. And he was clever enough to screen shot it before it was too late. So now all of that is behind us. And we move on to things like CS50 Finance, which is going to be the first of two web-base programming projects that we'll do this semester. And you'll find that the skeleton code that we give you for these problem sets is really meant to empower you for final projects to have a starting point. To realize now that what a lot of students do for final projects is they take their CS50 Finance or their Problem Set 8, they kind of throw out code that's irrelevant to their project, but then use the basics for their own final project. So realize we're tried to provide you not just with this framework for implementing this tool, but really web projects in general. Toward that end, know that -- actually I screenshotted this as well. So this was a screenshot of a penny stock that we used last year for Problem Set 7. It's only 40 cents there, according to the screenshot here. And I knew about this stock because I'd gotten this email from a guy named Tim in my spam folder. We usually change this every year because this is 2010. In 2011, the A5 Labs are not doing so well, all thanks perhaps to a bit of excessive trading. But the stock is still traded. And you'll see that this is the one that's used in the Problem Set's examples. So dinner this week -- for those of you who have not been able to make the past lunches -- we thought we would do something on Wednesday at six pm. If of interest, go ahead to CS50 dot net slash TV. And then a word on seminars. So this is the most seminars we've ever offered historically. All of these will be filmed. And if you'd like to register for any of these, go to that URL there. In particular, let me draw your attention to two particularly novel ones involving mobile programming. So some of our friends at Microsoft are going to be offering, probably tomorrow night, this appLab phone for Windows programming. More details can be found at the URL there. They've offered to present some fabulous prizes for those of you if you choose to elect to do some Windows phone-based project. And also, too, know that we'll have a Blackberry programming seminar in a week or so. And for this RIM has kindly donated some Blackberry Bold phones. So if you would like to go the route of developing for Blackberry, drop me a note and we can see if we can hook you up with some actual hardware for that. All right. So PHP. So PHP is fundamentally different from C in that it's not compiled. It's interpreted. And an interpreted language is something that you still write in the same way with source code, but you don't actually run it through a compiler and then run the resulting executable. Rather, you write your source code. Then you run and executable and you pass to that executable the PHP source code at its input -- as its command line argument, really. So in the world of PHP, the interpreter is generally a program called PHP dot exe, on Windows at least, or PHP dot app on Mac or PHP on a Linux system. So what's nice about interpreted languages is that they actually lend themselves to much faster programming. You don't have to jump through as many hoops to actually get your code working. And there tend to be much higher level in the sense that you don't need to worry henceforth about pointers and locations in memory. You don't need to worry about memory management anymore. Rather, the interpreter -- in this case PHP -- is going to handle a lot of that minutiae -- interesting details, but tedious details as you advance further in your understanding and savvy with programming. So just to give you a sense of PHP, here is perhaps wonderfully recommended resource that just talks about the language. Here is a loop. Here is a condition and so forth so that rapid fire you can acclimate to the syntax. And you will find PHP syntax very similar to C, which is one of the reasons we use it at this point in the course. In terms of functions, though, one of the nice things is that we also don't need to adhere to this convention of having a main function anymore. Rather, if you want to write a program in PHP, you open up a text editor, you create a new file, and you just start writing PHP code. You don't have to have a main function per se, but you can have and will have other functions that you write or that you use. So conditions look just like this. And this is the exact same slide we showed in week one when we started talking about C. The general format for conditions in PHP is going to be the same. In the case of Boolean expressions, these are going to look the same, both with or's and with and's. Switches are going to be the same. In fact, switches are a little more generous in PHP in that you don't need to just compare integers or chars. You can actually do string comparisons using these cases. So that's actually a little more friendly and versatile as well. Loops are actually going to look the same. You're going to have for loops. You're going to have while loops. You're going to have do while loops. And so this ultimately is to say that we're going to see lot of familiar syntax. We also have arrays in PHP. But the nice thing about PHP's arrays is that one, you don't have to declare their size in advance. If you want an array, you effectively just say, 'Give me and array.' And then PHP figures out what size it should be. And if you keep adding and adding and adding to it, PHP will take care of resizing it for you. You don't have to worry about malloc and realloc and all of these lower level details anymore. The language is, again, much higher level. You also have variables. But variables, syntactically, you'll find are a little different. For better or for worse, every variable in PHP is prefixed with a dollar sign. The upside of this is that it really is obvious what is a variable. The downside that you have dollar signs all over the place. But this is just a convention that these folks chose. So in this snippet of sample code here, I am declaring a variable called S. I'm setting it equal to a value of 'hello, world'. And then notice what I'm omitting. I'm not specifying the word 'string'. I'm not specifying the word 'char star'. In fact, when you declare variables in PHP, you're no longer going to specify the type of a variable. Rather, PHP is going to figure it out from context. And indeed the context here is pretty obvious. The double quotes obviously suggest this is a string. So there is no need for us, the programmer, anymore to say 'string s' or 'char star s'. Same in the case of floats, in integers, and even Booleans. So we relax that constraint. PHP is loosely typed whereas C is a strongly typed language. And so this has both upsides and downs. But for now it means that a lot of the syntax that you might have struggled with for some time will start to slip away. So loops, too, have some nice new features. It's a very common paradigm in PHP to want to iterate over an array because PHP is very often used in web programming. Web programming often involves databases. Databases often involve lots of data. And so it makes sense that you might want to iterate over a whole bunch of data like your list of friends or you stock portfolio and print out, print out, print out the same kind of information again and again in a loop. So PHP is this very nice for-each construct that C did not have. And the syntax is generally as follows. For each and then in a parenthesis, you specify the name of an array that's stored in a variable. In this case I arbitrarily called the thing array -- dollar sign array. For each array as element -- as is just this new keyword -- dollar sign element is also arbitrarily named, but ultimately inside these curly braces I can now do this again and again with dollar sign element. On each iteration of the loop PHP is going to automatically change what value is an element by taking the next element from array successively. I don't need to do plus plus. I don't need to do that sort of manual manipulation anymore. But perhaps most powerful about PHP and a lot of these higher level languages -- Ruby and Python and the like -- is that they support something called associative arrays, which is just a new word for what we spent past week on, namely hash tables. Those of you with Java backgrounds might have called these things hash maps back in the day. But an associative array is simply an array whose indices no longer need to be numbers. Up until now, anytime we've had an array, you index into an array by way of bracket zero, or one or two or three. And that's a little limiting. Because in Problem Set 6, you wanted to answer questions of the form , not where is this word, but is this word in my hash table or in my tr1. And so in the case of hash tables, the input to your check function was typically the word that had been pulled from the Austin Powers script for instance, and so you wanted to say, is this word 'foo' in the dictionary. And you wanted to use 'foo' as your key and get back a value of true or false. Well PHP makes this so incredibly easy that you can re-implement the entirety of Problem Set 6 in just a couple of minutes. And so in fact, let's see how we might do this. I'm going to over to my -- sorry. I should have told you last week. So let me go over to my appliance. I opened up GEdit. I created a new file called dictionary dot php. And I'll go ahead and start typing this. So the one distinction with PHP that you have to remember is that you can't quite just start typing code. You actually have to tell the interpreter that you're about to start writing PHP code. And so the convention the world adopted is that if you're writing a PHP program, the top of your text file should have open bracket, question mark, PHP. And then at the bottom of your text file should be essentially the opposite but without the word, so question mark angle bracket. So most web servers, though, actually allow you to shorten this to just this. There's a good amount of religious debate on the web as to which is better. Frankly I think this is much simpler and more elegant. And so you'll see, at least in a lecture, examples in the Problem Sets that we use what are called short tags. We don't bother writing PHP all over the place. But what these tags means -- and these are not HTML tags. These are for better or for worse PHP tags. This means here comes some PHP code. And so I can start implementing Problem Set 6 by thinking ahead as to what I need. Well ultimately I'm going to want, for instance, a variable. And I'll call this size. That's going to represent the size of my dictionary. I also want to have an actual dictionary. And so, a dictionary, I like the approach of hash table. Just conceptually it's easy in that you insert a word and want to get back true or false. So that begs an associative array. And to declare and array in PHP one of the ways is literally call function called array, open prn and close prn. And that gives you now an array of size zero. But recall that arrays in PHP will resize themselves and their indices -- the thing in square brackets no longer have to be numbers. And so that allows me to do things like this. Let me now scroll down. And let me start implementing something like the load function. And I'll call D the name of the file that's being loaded -- so large or small as in the case of Problem Set 6. And I have to so something a little annoying in PHP. I actually have to say global size and global dictionary only because when I'm inside of a function, unlike C, I need to say explicitly if I'm trying to use a global variable. With that said, global variables are not all that common. I've simply gone this route because it's nice and simple to get started here. So let me do something error-checking oriented. So if it is not the case that this dictionary file -- dollar sign D -- exists, I'm going to go ahead and say -- if not exists, I'm going to ahead and say, 'return false'. So if D does not exist return false. And also, just for good measure, if not is readable D, go ahead and also return false. So you didn't focus on these lines so much in your own implementation since we wrote a lot of the error checking code in speller dot c. But these are now PHP functions that just come with the language and are a lot easier than some of the techniques we had to deal with in C. But believe it or not, the load function is almost done. I'm going to go ahead now and use this new construct for each -- let me say -- let's call this -- let's do this. Words gets file of D. It turns out that file is a function that loads in a text file and for each of its lines puts each of those lines in a different element in an array. So at this point in the story, 'words' is an array containing every word from the dictionary. So now what I want to do is a little something like this. For each of those words as, let's call it word. So this is the construct that's like a for loop, but it's going to do all of the auto-incrementation for me. So fore each of those words in the array as a word, I'm going to go ahead and do this. Dictionary, word gets true, size plus plus. Done with my load function. All right. How is this actually working? So dictionary is an associative array. An associative array is just an array whose keys no longer need to be numbers. They can be actual words. And just like an array with numbers associates key with value -- number with value -- an associative array can certainly associate word with value or in this case word with Boolean. So now I have this amazing data structure that took me one line of code to implement that I can just say dollar sign dictionary bracket word close bracket gets true. And what's that going to do for me? Well PHP is going to figure out where in this data structure called an associative array to put that word. And it's going to store the value of true. Yes, one, whatever the implementation may be in that data structure. And size plus plus is just like C. Now I need to actually do one little thing just for good measure here. I should probably do this. And I should probably. Actually the one little thing I do have to do -- I have to say a word gets chop word, in case you're playing along at home, only because the file function is not quite smart enough to get rid of the new lines at the end of each line. So if I want to get rid of those new lines, chop is one way of eliminating the white space at the end of that word. But I don't have to deal with lower case or anything like that because recall that the dictionary we allowed you to assume would be lowercase. So return true. That's it for the load function. And really the magic is in here. The rest is just error checking and syntax. So what about -- how about size? Well size was pretty easy for all of us, but let's just do that one for good measure. So function size -- now I can say global size, return size, silly though that may seem here. But it's also certainly pretty simple. And now let's do check. Check was kind of the interesting one because that's the one that was called again and again and again. So let me scroll up to the top of my file. Do function check. This time I'm going to be checking a word. Let's arbitrarily call it W. And in here I need access to the dictionary. So I have to deal with that little syntax. But now I can just do this. First, let me force the word to lower. So stir to lower is a function in PHP that changes a string to its lowercase form. And so now I can just do this. If in the dictionary array at location W equals equals true, well return true else return false. Or if you really want to be fancy, you can just say return that bam. Problem Set 6. So why the hell did we just implement Problem Set 6 in C? Well the reason that these associative arrays and languages like PHP and Ruby and Python exist is because of languages like C. And the fact that this is pretty darn easy to write is because we've stood on the shoulders of these previous languages. In fact, the PHP interpreter -- the program that we're about to use to run this program itself -- could be written in C, and the same thing for interpreters for other languages. Because C, as we will see in a moment, is actually very high performing. And so actually in the real world when you really care about the performance of your code as we did for Problem Set 6, you might want to sacrifice some rapidity of developer time. Put more time, put daresay a week or 20 plus hours, into that implementation so that you really squeeze out all possible performance. So let's see what actually happens here. I'm going to go ahead and go into my terminal window here. And in here I have two files at the moment, dictionary dot php and speller. And just to show you what speller is, let me go ahead and open speller. Speller is also implemented in PHP. And we won't spend time going through this, but pretty much I sat down one night with the C code open, with a blank file open, and I just started translating in my own head the C code to PHP, trying for every line to call the nearest equivalent PHP function. So as an at home exercise, definitely look through this speller file or if you have a printout here today. But just realize that it's almost a direct translation from C to PHP. So as such, it's a nice way of understanding how to go from one to the other. And let me point out one little thing here. You will see in a lot of interpreted languages, even though they're just written as text files with simple text editors, at the very top they have this silly thing called a shebang -- a sharp bang slash user slash bin slash something. So this simply means when this is file is executed at a command prompt, run this interpreter and pass that interpreter all of the lines below it. So it's a way of naming your files very simply like speller as is the case here in my terminal window. But I don't have to specify a file extension and therefore tie myself to a specific language. I can literally just run speller as we could in C. And thanks to that first line in the speller file, the operating system will know what to execute. So let's go ahead and run speller in the PHP version on CS50 slash PSet6 slash texts and then Austin Powers for instance. So let me go ahead and run this. All right. So we've got that. Looks like there were 644 words misspelled. Words in dictionary seems to check out. And it just took about half a second, so point 53 seconds. Well now let me go into another terminal window. In this window I have implemented PSet6 using C. So this is my C code from PSet6. I've already compiled speller. So let me do the same thing. Speller on CS50, PSet6 slash text slash Austin Powers enter. Okay. So I'll zoom in. This is -- whoops. Oh, I ran it the same way. This is before. Sorry, this is after -- point 03 seconds. And now if we go back to our misspellings for just a second and run this again here, it feels slower, right. If we can do this really explicitly, speller. Okay, it even got faster that time. Before, after. Before, after. For those who can't see in front, same story. Before, after. Before, after. So this is the price you pay. And it's not clear perhaps at first glance if this is now a positive. It feels like we're about to introduce you to a really crappy language, right. Because now you write much less code. But my God, look at the price you pay. It's an order of magnitude different. But this is a little misleading as such. So on the one hand I'm actually doing things a little less efficiently in PHP as I could be here because I'm just trying to make it map as closely as possible to Problem Set 6's C code. But also realize this. We are paying a fundamental penalty, not the result so much of PHP, but the result of PHP being an interpreted language. Whereas C is compiled by GCC into zeros and ones that the underlying CPU understands, well PHP is not compiled into anything. Rather, we are running a program -- php dot exe -- we're passing it all of those lines of codes we just plus speller and saying please figure out how to execute these. And an interpreter pretty much goes top to bottom, left to right, and converts as best it can each line into the equivalent zeros and ones, but on the fly. And if I run my speller again, the interpreter has to reinterpret it. If I run my interpreter a third time, it has to reinterpret it. So one of the disadvantages then of an interpreted language is you might be doing all of this work right in the very front to interpret your program, but then you're throwing those results away because the program is not saved. It's because it's not compiled. Now let's fast forward to the context of the web. So the reality in the world of the web is that computers are not the slowest part. We have the whole internet between us and someone else across the country if we're trying to have two computers communicate. And so there's a lot of other delays that actually might mean that you know what, it's okay if it doesn't take a split second, but two split seconds. All right. So we might be able to tolerate that performance penalty. And also in web servers, which we're about to go back to, you can actually cache PHP. So you can enable a feature whereby once a PHP file is interpreted once, the computer -- the web server -- will actually remember how to do that again so as to save time. And so you will find that as super majority of start ups these days of websites on the web actually do use these high level languages like PHP and Python and Ruby and Perl and even others because C is the wrong language with which to implement most websites. Once you're at the point of Facebook scale, Google scale, and even a little smaller than that, certainly there are small problems that you might want to solve at the very low level with C, doing database queries or searching graphs of social networks and the like. But for implementing something that just spits out html and spits out a stock portfolio and even prints out your list of friends, by all means is and interpreted language like PHP a better choice than C. Case and point, it took just a few seconds to implement the entirety of a week's work. So just realize these tradeoffs. So let's transition then to actually running PHP code on a web server. Right now I ran it at the command line, which is absolutely possible with one of these interpreted languages. But if I instead move my PHP files into my public underscore html directory or somewhere like that, I can actually have the web server execute my PHP code so that I the human no longer need to manually type commands. And this is perfect because when a user visits CS50 dot net, obviously we don't want a human having to run a program saying, 'respond to this user'. It's all automated by the web server. So let's then transition back to where we left off last week on something like implementing the freshman intramural site. So let me go into my jharvard directory, public html, and one of the files I have in here today -- it's all on the CS50 dot net slash lectures -- is froshims0 dot php. And this is a simple version of where we left off last week. So notice we have some familiar stuff. Now doc type just means, here comes a webpage written in html5. The html tag is the root element which says to the browser more explicitly, here comes the actual webpage. The head of the page comes next, then the body, and the real interesting stuff typically happens in the body of a webpage. Now we haven't seen all of this html in detail yet, but frankly it's pretty easy to pick up as you go, certainly just by Googling things you don't understand. Div is this invisible division of the page. Style allows you to specify some CSS, cascading style sheets. And this one kind of says it all, text align colon center means everything on this page should be centered and so forth. So today and henceforth we won't focus so much on html but rather how this is functioning as a dynamic website. And the most interesting tag toward that end is this guy here. So we saw forms last week. And a form has an action which is the URL to which the form should be submitted or partial URL if it's on the same server. And then there's two methods. And we've seen get and we've seen post. And for now the simple distinction is GET requests end up where? Where do the parameters end up? In the URL, in the address bar. And so GET is generally to be avoided for anything sensitive. You don't want passwords, credit card numbers, anything personal going into the address bar with a GET request if only because it's unnecessary. Two, it then lends itself to prying eyes, roommates and such sitting down and looking at your browser history. It's just bad practice. So POST is generally preferred for anything sensitive, as in the case of personal information. So what does this thing look like? Well let's go over to a browser. I am in, recall, local host, which refers to the appliance, slash tilde jharvard. And I'm going to go into my froshims directory, froshim0 dot php. And this should look familiar from last week. So register fro froshims. The fact that I'm using a table is just because I wanted this to kind of line up nicely with rows and columns. But let's see what happens when I register. This form, when I click register, is going to get submitted to register0 dot php. So let's take a look at what we should expect there. Let me open register0. And this is actually a very simple file. So the stuff at the top, realize, is just comments. And the only reason I put my comments inside of PHP braces is just so that the user doesn't actually see the results. Realize that anytime PHP or the web server in this case, sees open bracket question mark, those lines are going to get interpreted and the output is going to get sent to the browser. Well these are just comments. So there is, by definition, no output, per se. They're not function calls. It's not printf or print or echo. So nothing ends up going. That gets stripped from the resulting webpage. But the result is really just some html. Most of this is html5 except for this line, which is a new function, a very helpful function PHP at least for diagnostic purposes called print r. The R is recursive. So what I'm saying here is go ahead when you receive a request from a user. Create this very, very basic webpage with a head and a body. And go ahead and print recursively the contents of a special variable called dollar sign underscore post. And notice that this is indeed PHP because I have flanked it with the open bracket question mark on both sides here. And this is a new tag too for most of you. The pretag just means use preformatted text. Use monospaced font so that it actually looks like programming code and not like Times New Roman or something like that. So this is not a useful webpage yet. This is not a freshman intramural registration system. It's really just to see what's going on underneath the hood. So let me go back to my browser. And let me go ahead and type in, for instance, David, captain, male, Matthews. Click register. And what that webpage is doing for us is simply this. It's showing us that dollar sign underscore post is apparently in array. And inside of it are a bunch of key value pairs. Those key value pairs are name equals David, captain on, gender M, dorm Matthews. So here's what's really powerful about languages like PHP. I didn't have to do a thing. I simply called the function that printed out the contents of a default variable that was automatically populated for me by the web server and by PHP so that now I can focus just on getting the job done that I care about, registering this user. By contrast, in a language like C, you would actually have to parse all of those http headers. You would then have to figure out that oh the question mark means a parameter. The ampersand means multiple parameters. You would have to do all of that crazy string manipulation yourself when now all I care about is getting real work done. And that's what these languages tend to facilitate. So interesting, too, is there was no mention of the word 'on' in the html, but this is actually the convention. When you check a checkbox, the value that's sent from a browser apparently is literally the word 'on'. So what are these super globals? Well we're actually going to see a few of them. So we've seen POST. And we'll continue using that. There's an analogue for GET requests, dollar sign underscore get. There's going to be another one for something called cookies, which we'll talk briefly about this week and we'll see in more detail probably next. There's dollar sign underscore server, which actually stores some boring information, but some interesting information too like the user's IP address and the browser that they're using. So if you actually want to get a sense of who your users are or verify that they're in Harvard dot edu's IP address range, you can use tricks like that. And then the most magical one, I daresay is dollar sign underscore session. Recall that when you visit a webpage on the internet, even something simple like this -- actually let's go to CS50 dot net slash lectures. And I hit enter. And it proceeds very slowly to connect. There we go. Come on. [inaudible] network. This is the trick. If you guys have experienced this too where you network connection kind of dies, so do service network restart. There we go. So notice -- this is actually perfect. Notice how long it's taking, right. And notice that there's the spinning icon in the top of the page there. And in just a moment we'll see the results. But let's simulate the results. And then at some point the spinning thing stops, right. So this is actually an important visual detail. When that progress bar stops, the end result is of course that the webpage has finished loading. So let's pick apparently more reliable websites. And that's just -- oh, maybe it's in here. All right. We will -- let's pretend Google dot come just came up and the spinning thing stopped. So the takeaway here and the only message I'm trying to communicate is that http is what we'll call stateless. As soon as a webpage finishes loading, that means that all the html -- all of the gifs and jpegs, all of the audio, all of the flash files, whatever composes the page -- has finished downloading so the little spinning wheel in whatever your browser is stops. And the browser at that point has stopped talking to the server. This is in contrast to things like an instant messaging program like GChat which obviously maintains a constant connection somehow so that you keep getting instant messages again and again. And even Facebook is very laden with something called JavaScript and AJAX. So that even when your little spinning icon stops on Facebook dot com, it turns out behind the scenes more and more http requests are being made so that you can get these little flashes on your screen like someone likes your photo or someone has commented. But in traditional webpages such as the ones we're writing thus far, once that spinning icon stops, that's it. You're no longer talking to the server. So that begs the question, how do you possibly implement something like say a shopping cart on Amazon dot com whereby I might go to a page of book. I might click submit to add something to my cart. And then that's it. It's as though I've disconnected from the server on Amazon because my little icon stopped spinning. And yet I can somehow click to another page and another page and keep adding things to my shopping cart even though I don't have this persistent connection to the server. So the means by which that can be implemented in PHP is by storing inside of this special variable called dollar sign underscore session anything that you want to persist even across page loads. So in short, you can think of dollar sign underscore session as a shopping cart. And we might not actually store products in it, but for Problem Set 7, we're going to store at least one thing -- the ID of the user who's logged in. So that you don't have to on every page the user visits -- for CS50 Finance you don't have to ask him or her, 'Are you logged in?' 'Are you logged in?' 'Are you logged in?' You can answer that question yourself by storing those answers in this shopping cart of sorts. And that's implemented by way of something called cookies. But we'll see how we get there with these next examples. So let's open up a little something more sophisticated, froshims1 dot php. The form is identical except for this here. This one's going to submit to register1 dot php. So let's see what register1 does that register0 did not. Well this is what we did see on Wednesday. So we have these conditions at the top. And notice all this stuff. Even though most of this is comments, notice we've got open bracket question mark. So that means here comes some php code. These are just comments. So that's as though they're not even there. This is a comment too. So that doesn't really do anything. But these several lines of an if condition do work some magic. So if the empty function returns true when passed the name field in the POST associative array then I'm going to apparently execute the code inside of these curly braces which have what affect? Well this is the way in web programming to send the user to another page. You've probably seen this before. You go to some website, but it redirects you to some other page either because the page has moved or they want you to log in. That is because you can make the browser say, hunh-unh. There's nothing here. Instead go to this location, specifically this URL. So this one-liner is just my way of saying, you know what, if the user didn't give me a name or their gender or their dorm, forget it. Redirect them back to froshims1 dot php so that they can presumably fill in those blanks. And there's multiple ways to do this, but realize the empty function is a pretty neat and simple way of checking the value inside of one of these associative arrays, in this case name, then gender, then dorm. And now down here, notice that this html is only displayed to the user. It's only sent to the browser in what circumstances apparently? [Pause] >>Logically when is that highlight html actually sent to the user? >>[inaudible]. >>Sorry. >>[inaudible]. >>Exactly. If all those initial things are false, in other words the user has given me their name and has given me their gender and has given me their dorm, then obviously just logically this if condition is not going to have its lines executed. So we keep going, keep going. PHP gets here and says, 'Oh that's it for PHP.' And even though we're comingling PHP and html, what webservers will do is as soon as it sees raw html, it's just going to send it to the browser as though this were a dot html file. So we're obviously not doing anything of interest now with this data, let's at least provide the user with some more feedback. So let's go into froshims2. This too is identical except for this one change. So froshims2 is going to submit to register2. So let's go ahead and focus on register2 and we now see this, a little more dynamism. Notice that I don't have to have my PHP code all the way at the top of the file. Rather, I can comingle it here, especially for something so simple. So notice here, no matter what this time, I'm going to spit out this html doc type and the html element and head and title and close the head and open the body and then I'm going to comingle, again some html and PHP. So this puts me into php mode. And I'm asking the question, if the name is empty or gender is empty or dorm is empty, then notice the colon. C did not have this syntax, but PHP does. The colon means even though this question mark closed brace is there, go ahead and execute anything below this line because this condition was apparently just true. So in this case, I'm apparently literally going to send the string to the user. You must provide your name, gender, and dorm. Go back. And now notice I'm using the anchor tag so that this time I'm not sort of presumptuously redirecting them. I'm instead giving them an error message and then giving them a link with which to go back to the previous screen to fix this problem. Before, didn't even explain it. Else, if that's not the case, notice the other colon here. I just tell the user, 'You are registered.' Well not really. Not really because I'm clearly not doing anything with their form submission just yet. And then notice this new syntax endif. It is indeed one word. C did not have this, but PHP did. So let's see what the end result here is. Let me go into froshims2 on local host in John Harvard's account. And this is froshims2. Let me go ahead and I'll just give you my name. That's all you need. Register. Oh, I broke it. Okay, line 20. So here's an example of how to debug PHP code. Much like GCC spits out error messages, this is actually a little more clear. There's some kind of syntax error. It expected a colon on line 20. So let's see where I screwed up. This is line 20 here. And I left off a closed parenthesis there. So let me go back to the browser, reload. All right. So there we have. I'm at register2 dot php according to the URL. And I indeed got yelled at. So I can click 'go back' and now I'm back at froshims2. So this is better, but it's definitely the best interface. Because the user now has been advised what's wrong, but they still have to hit back. Hopefully we can do a little better than this. So let me go back this time to let's say froshims3, which will give us a little form like this that submits to register3. So let's continue that story in register3. And now this one's getting a little -- oh actually we did tease you with this one here. Let's actually do something with the results. So in this case here, notice that I again have some PHP code. And if the name's not empty and gender's not empty and dorm is not empty, here was our trick for actually sending mail. So most of these fields are kind of self explanatory especially now that we know this is just a variable. This is just a variable. This is just a variable. What's the role of all these dots? Did we say? >>[inaudible]. >>What's that? >>Put the strings together... >>Yeah, put the strings together. This is the so called concatenation operator. So this means put this string, then this string, then this string and make one big string out of them. I could have just written the whole thing on one line, but a lot of people would argue stylistically this is a little more readable. And so I've done that here. Notice, too, in PHP, it is necessary to use double quotes around things like backslash end just as we necessary in C. Here I'm using a firm address of malan at CS50 dot net. Here I'm calling the mail function. And so ideally the result of filling out this form correctly should be an email sent to me at that address. Otherwise, we're going to go ahead and just readdress the user. But let's step up a little further from here. Let's go to froshims4 and now we can make this a little more interesting. So notice here that froshims4 actually submits to itself. So this actually is going to lend itself to a more elegant solution. There's sort of a bad user interface decision I made in the previous examples in that I fill out the form. I submit the form. I go to a new page -- register1, register2, register3 dot php. And if there's any error, yes I can redirect the user back, but there was no explanation as to why they ended up back at the original page. And also I'm telling them the error message in the more recent versions and then they have to hit back. Right? That's just a bad design. Why not just provide the user with immediate feedback on the same screen so that they can then proceed to fix whatever problem they created. Right. You might remember websites, they still exists today, where not only do they make you see the error message then click back. What sometimes happens when you do hit the back button? The whole form has been emptied. That's just horrible design. And this is somewhat browser dependent, somewhat language dependent. Let's at least try to avoid these ridiculous designs. So as a result of this more friendly user interface my file is going to be a little more complex. So let's actually see what's going on here. So in the top of froshims4, I again have some comments. And now I'm going to have a special check here. So it turns out you can check -- you can ask a question, 'Was this field even submitted?' Was it set, so to speak by some html form? And dollar sign underscore post 'action' means I must have defined an html form element whose name is action. This is arbitrary. We could do this in different ways, but I chose to go as follows. If you scroll down and scroll down and scroll down, notice that this time even though my input button is of type submit, notice I also gave it a name. What's the result here? Well when I click that button, because it has a name, it's going to get submitted to the server. So now even if the user does not fill out any of the fields, they did at least submit the form by clicking it or by hitting enter. So no matter what in this scenario, at least one parameter is going to be sent to the server, in this case called arbitrarily 'action'. So I now, the programmer, can at least check was the form actually submitted or did the user just pull up the URL without filling out a form. In other words, I want to distinguish between a POST submission and a simple GET. Where a GET is just the result of opening up this URL on a page. In other words, if I go to my browser and I go to froshims4 and just click it and open this up here. Let me -- let me cheat really fast. Don't pay attention to what I'm doing here. We disabled this in PSet7 for this reason. And notice. Stand by. [ Pause ] >>Dammit. Okay. One second. This is getting awkward. Alrighty. Error reporting. All right, let's do the -- oh, typo. You need to know this. All right, do this. Oh, dammit. All right. David is doing something stupid. All right, mm-hm. Error reporting e-all, e- notice... [Laughter] >>Fixed, okay. So, thank you. [Applause] >>So PHP is really easy though, really. So as an aside, let me explain this so that it's not completely lost on us. So PHP, long story short, has different levels of errors. There's something called an error. There's something called a warning. There's something called a notice. And those are in descending order of severity. In C, we made any possible mistake you made just called an error. And that's why you couldn't even compile your code in C sometimes if you had an error. PHP has even more layers of severity. And so what we typically do in the appliance is we disable notices because notices aren't really errors, but they aren't necessarily perfect lines of code. So in this case I cut a corner which meant, you really shouldn't do that, but the web server yelled at me as a result. I've just told the web server, 'Don't yell at me and I will fix this properly later.' PSet7 you will see in the file called common dot php -- you will see that we did exactly the same disabling there. All right. So what's going to happen in this version? I'm going to go ahead to register as David, as captain, male from Matthews and click -- actually let's leave one of these unfilled. Register. Ah, so now still very simple webpage of course, but at least now this is a little more dynamic. It's still kind of sucky in that I haven't repopulated the form fields but at least I've given some immediate feedback. So how did this happen? Well apparently this form, as we saw in the source code, submits not to register something but rather to itself. So the same PHP file submits to itself. So this is why we need to distinguish between was this a GET request or was this a POST request. In other words, did the user just type this URL manually and end up here in which case there is no error because they literally just got here. Or did they click the submit button in which case they got here by way of a form submission in which case we should yell at them. So now everything is self contained, hence the need for this condition up top. So if we now go to froshims4 dot php -- you can ignore this notice line up here -- let's see what's actually going on. So if the form was submitted -- so if post action was submitted -- and if name is empty or gender is empty or dorm is empty, notice that I'm doing this. I'm setting a variable called dollar sign error equal to true. And just for good measure, I'm going to go ahead and do this. I'm going to go ahead and say error by default is false. So we do have the notion of Booleans and PHP even though we don't say the keyword Bool. But if the user screws up in this way, then I'm going to ahead and say error gets true. So now let's scroll down here. And here is where that red text is coming from. So the rest of this form is as it's always been. But at the very top of my file, I've decided to say quickly in PHP, if error is true, then -- thanks to this colon -- go ahead and output something called a div, whose text color is going to be red according to the CSS property here. And then just yell at the user, 'You must fill out the form.' And then open bracket slash div. But notice down here that none of these elements as the moment have any kind of default value. The reason that this form has not been refilled out for me is because I literally have not said give this field a value, give that field a value, give something else a value. So we might actually need to fix this ourselves. So let me go ahead this time and open up froshims5. And this one is going to do a little something different. Let me go ahead and just paste this in so that we can ignore one of those errors for a moment. And let me scroll down here. Notice that this form also submits to froshims5, so to itself. Notice that I'm yelling at the user if error is true. So that story is identical. But now notice what I'm dong that's a little bit different. And the font's going to wrap a little bit. So let me zoom out. Notice now my input tag is almost the same. Name is name, coincidentally. Type is text. But this time I've added an attribute value. And notice this little PHP trick here. So this is PHP code. Inside of this html attribute's value is a bit of PHP code which very quickly says to the web server, 'interpret this.' Well what is being interpreted? Well html special chars is a special escape function so that whatever the user has typed, you're going to escape. Just as in the way we've escaped certain characters in C, html special chars is a function that says if the user typed in something crazy, make sure it displays literally as what they typed and doesn't mess with the webpage. And we'll see what not doing that would create in a moment. So what am I printing out? Well go ahead and print out the result of whatever the user typed into the name field. Close quote. So in other words, when the user types in their name, but maybe skips the dorm or gender and clicks submit, we can at least when the form is reloaded, prepopulate this value this time as follows. So let me go ahead and zoom out. Let me go ahead and fill in for froshims5 dot php. Let me go ahead and fill out name. But I'm going to skip all the other fills and click register. And notice I got yelled at, but notice this time the form did get filled out for me. Let's go ahead and right click or control click on the browser. And if I scroll down, notice here, to be clear, the browser never sees PHP. PHP is executed server side, not client side. So all of this is the output of PHP or the raw html that I wrote. Here's that div. And notice it's kind of weirdly indented because even though my PHP code was nice and pretty, that white space is also sent to the browser. So it's kind of throwing things off. But that's fine. We don't care about pretty printing or html, just your actual PHP code. Let's scroll down here and here's the difference. Now this is time there's a value field that has spit out 'David' because I had that additional line of PHP code. And notice here if I scroll down these guys are not yet prepopulated because I didn't fill them out. So let's see what the opposite of this is. So I actually did use best practice there whereby I did use this function html special chars. But let's see if I can do something a little hackish. Let me get rid of this and let me just say, 'put inside of these quotes whatever the user typed into the name field'. And now notice one new piece of syntax. Notice this trick here. This means, because the equal sign is right next to the dollar sign, put this value here. This is equivalent to saying something like this or even saying like this with parenthesis and so forth. So this is just nice sort of shorthand notation. So let me go back to the original. And just this says, put my name here. Let me zoom out. And now let's see if a malicious user can maybe break my website. So I am now the user who's just trying to be difficult. I'm some bad guy trying to compromise this website. And if I kind of suspect that the person who implemented this site was not very good and not security conscious, what if I can trick this page into outputting html that wasn't intended. Well typing in David still works. It still populates that field. But notice what we could do here. If I view the page source again and I scroll to the David part, notice that I've just been cooperative as the user. I typed in D-A-V-I-D. But I feel like I could type some crazy stuff here too. What if I instead typed into this form, quote close, V, ha ha ha. Register. Interesting. The only one I'm sort of damaging here is myself, right. Because I'm not actually attacking the website. But this was not intended. And in fact, this is representative of a sort of attack that's possible. Long story short, there's this other language called JavaScript which is executed client side. And so what a lot of bad guys typically do, especially in phishing emails, is if they've realized some website, even something silly like a froshim site has not escaped user's input properly, what they'll do is try to trick you into sending some JavaScript code to this form so as to steal your cookie -- some cookie from the website. And we'll see in awhile that stealing cookies means that your shopping cart -- your dollar sign underscore session variable -- can be compromised. And anything that you've put in there can be taken over by someone else including, for instance, your Facebook account. Now if we go back here and I change this back to the right way, where I'm actually escaping these inputs with this annoying long function name, but still nonetheless useful, html special chars, and now I resubmit this form as I did before. Let's start over. So I'm going to go ahead and type close quotes, close bracket, ha ha ha ha ha. Register. Now I literally see that again in the form. Because what the server has done for me -- what PHP has done for me -- is this. Notice that there are things with ampersands and semicolons now. So it turns out that html has these things called entities. And these are entities in that they represent special characters that normally would break html. And it's a little cryptic, some of them, but ampersand GT semicolon means the greater than sign. Ampersand LT semicolon is the less than sign. Ampersand QUOT semicolon is the quotation mark. So there are a few of these well known entities that PHP can spit out so that even if the user is being difficult, you can at least protect the site against being tricked into executing something that wasn't intended. And even though the source code looks like this, obviously as we just saw those entities are converted back to their original characters before being shown to the user. Now the one thing we haven't yet done here and really has made this site useful -- we have no capability thus far to actually remember that users are stored or have registered. For that we're going to need a database. But before that, we're going to need a break. So why don't we resume here in five. [Pause] >>All right. So we are back. And I thought it would be a disappointment if we didn't actually demonstrate how you can send programmatically emails with this third example that we glanced at last Wednesday. And today this recall is froshims3 dot php. And recall that this was the implementation that underneath the hood had these lines of code using the mail function which has a bunch of parameters to subject, body, and headers, which ideally would send an email to say the proctor who's running froshims or in this jharvard at CS50 dot net. So that when we check that guy's email account, John Harvard should have some registration information waiting for him. So if I go over here to my browser again, I go ahead and fill this out with complete fields so that it actually does like my input, click register and then turn my attention to my Gmail accounts here. This is -- we're actually going to get a second one because I was just testing. In my Gmail inbox is a very simple email like this. So it was sent from malan at cs50 dot net. I logged into our email server as jharvard at cs50 dot net. And this is of course not all that interesting as it's written here. But I do know that this person's name is David. The checkbox was on, male, and Matthews. And if we wanted, we could certainly format these emails a little more cleanly. Of course this doesn't scale very well. And even if we implemented the froshims website for the proctor by sending him or her emails, then this person has to start organizing these emails into folders and figuring out who's registered. It would be much nicer if we could somehow create a database for all of these registrants or create an Excel file even so that the proctor could manage the volume of registrants a little more cleanly. So for this we actually need to introduce a little something called MySQL. So MySQL is a free database server. A database server is something that allows you to store your data in tables or more specifically a relational database server is something that allows you to store data in tables. And what do we mean by tables? Well think again to Excel spreadsheets. These things have rows and columns. That is a sort of a very simple database where you can have columns that mean something like name and email address and phone number and every row represents an entry in that database or in that Excel spreadsheet. So this is a screenshot of a tool that we are about to see and use called phpMyAdmin. The fact that this tool is called PHP something is a coincidence. The tool happens to be written in PHP, but we're using it because it's a useful with which to manage tables on a server. MySQL is that server. It's, again, free software. It's very high performing. And to this day, much of Facebook is implemented with MySQL underneath the hood. This is -- it can be scaled up to many, many, many possible servers. We, in the case of the appliance, of course are just using one server -- our own. So this is a screenshot specifically of a table that you're getting or have gotten with Problem Set 7 that we precreated for you. And we give you a little text file with which to create this structure in your own appliance. And even though there's a bunch of icons on the left, this table is actually even simpler. There's only three columns, an ID column, a username column, and a hash column. And this table collectively will be called the user's table. And the idea here is that when you download PSet7 for the first time, what you have is a slightly functional product. You have a product that looks a little something like this. If I go to the staff's own implementation as CS50 dot net slash finance, you'll see a user interface a little like this, but you won't have the big yellow banner there saying that this is the staff solution. But what you do have by default is a bunch of temporary users -- a jharvard user, a [inaudible] user, a Malan or a boden, a max account and others -- so that you at least have some sample data with which to work. And so the format of that table is as follows. We apparently have an integer representing their ID. Their username is whatever they chose upon registering. And the hash over there is supposed to be their password, but it's not really. So if you think way back to Problem Set 2 when we talked about photography, some of you might have bit off the hacker edition of the crypto PSet, which actually had you crack passwords that weren't quite encrypted like this, but were in some similar fashion. Why, apparently, are we proposing in our database to not remember users' passwords, but instead remember their hashes thereof, whatever that is? What was a hash of a password or a hash in general? This also relates actually to PSet6. Yeah. >>To make it more [inaudible]. >>Okay, perfect. So the point of hash is generally -- is to make it harder for a bad guy who steals, for instance, this database or breaks into my web server and somehow gains access to all of my user data. It's a really bad situation if they not only get my user data but also get my users' passwords. Right? Because there is probably a nontrivial number of you in this room who are using the same password for your email, for your pin account, frankly for your fake CS50 Finance account most likely. And if that data is not encrypted or not hashed, what that means is that all these websites you've been logging into for the past couple of years, if you're using the same password and the people who implemented those sites are not particularly security conscious or savvy, you might be telling half the world who runs these servers what your favorite password is. Because if you don't actually encrypt it or again hash it, much like we created a hash function in PSet6 -- if you don't somehow scramble the input and then save that input, the alternative is the worse, which is just storing the actual password. So long story short, you will see in PSet7's distribution code, the use of a special function called crypt which is essentially a hash function that given a password like 12345 will create nonsense that looks like this. But the key feature of this crypt function is that if you call it again in the future and give it again 12345, it will return exactly the same cryptic value. So the idea is when you check passwords, you don't check what the user typed in against what's in the database. You check what the user typed in after it's been passed to the crypt function again, against what's in your database. And statistically it should be very, very hard to convert these cryptic hashes back to the original inputs. And for the curious and for those struggling to actually log into CS50 Finance, these were the answers to the hacker edition of Problem Set 2. And all of the passwords that we gave to the hackers in the class ranged from the simplest for [inaudible]. Rob's was noob. Matt's was [inaudible]. And mine I daresay was the hardest, which I think this year no one got, but these are the same passwords that we've given you just as sample users for Problem Set 7. So how do we actually use MySQL and use these tables? Well know first that SQL is the language we're now about to start using. So SQL -- structured query language -- is not so much a programming language as it is a database language -- a query language, per its name, that allows you to select data from a database, insert data into a database, delete from it, update it. So in short, all these things we take for granted when using Excel like double clicking on a row and typing and deleting a column and so forth, those can be summed up as deletions and inserts and updates and select. Where select is one of the most useful, that's the search, like give me something from this spreadsheet; give me something from this table. So we're about to start constructing queries that allow us to grab data in this fashion. And we'll use phpMyAdmin as a specific tool with which to actually configure those things so that we can implement a little something like this. So let me go back to the appliance. And I'm going to go ahead and open up Firefox. And I'm going to go not just to local host this time, which recall is my actual web server. I'm actually going to go to slash phpMyAdmin. And when you go here, you'll be prompted to login with jharvard and crimson. So to be clear, phpMyAdmin is an administrative tool on the web server, aka the appliance. You should not be trying to login to phpMyAdmin as [inaudible] or as Matt or as Rob, but rather as you, John Harvard. Because John Harvard in this case, aka you, is the webmaster. So when you login to phpMyAdmin, frankly its UI is kind of a train wreck. There's way too much going onto be compelling. But there are some very handy features that are much more user friendly than the alternative which would be a command line. So notice the top left tier that I've followed some instruction in Problem Set 7 that said, 'Import this database'. How do you do that? We literally give you a big text file. It's called PSet7 dot sql. You essentially highlight it and copy its contents into this big SQL window here. Click run and voila, you know have a database. So for now you're seeing the end result of that process that the spec will walk you through. When I click users, now we see the webpage that I took a screenshot of a moment ago. And again, I have an ID field, a username field and a hash field for their password. But let's start this from scratch with regard to froshims. Let me go ahead and do the following. I'm going to go over to the homepage again. I'm going to click databases. And I'm going to create a new database. Let's call it jharvard Week 9. As an aside, John Harvard has the privileges to create any database so long as its name starts with jharvard underscore. This is a typical MySQL convention. I'm going to click create. And now notice it executed this. So this is what phpMyAdmin does. It simply simplifies the execution of slightly more arcane commands. Again, I could type in a blinking prompt. For instance, to create a database, you could literally type at the right command prompt, 'Create database jharvard underscore Week9'. This gooey based tool just makes it a little easier to do so. Now if I scroll down here, it's telling me, 'No tables found in database.' So you can think of a table like and Excel worksheet specifically and an Excel file as a database that can have multiple worksheets or multiple tables. In this case, I want to go ahead, for froshims, and create like a registrant's table -- the kids who have registered for some froshims4. And how many columns? Well I've got four, right? Name, gender, captain, or dorm -- so four fields in that case. So let me go ahead and hit enter. And now I'm going to get this form here. Again, this is not the most user friendly design in that you have to scroll all the way to the right, but let's at least tease apart what these fields are. So first in column, I'm going to name these fields. Name, captain, this is going to be gender, this is going to be dorm. And now what types do I want to give these? Well notice that MySQL is different from C. It's different from PHP. It comes with a whole bunch of data types, frankly almost all of which are self explanatory, especially like float and double and int because we've seen those before. Int we used for an ID, but for name I need something like a string. And here's the string related ones. And the two that are more interesting now are char and varchar. Long story short, if I choose char, that's actually more than a single char because I can say everyone's name in this database is going to be no more than say 64 characters. And by typing 64 in that box means MySQL's going to create a column that's just wide enough for 64 character strings. Now the downside of this is that like in C if I allocate 64 characters, every name is going to take up 64 bytes, which is probably excessive for a lot of our names. So there's instead a data type called varchar -- variable char -- where you can say 64 is the maximum length, but be smart about this. Only use as many bytes as are necessary to store the D-A-V-I-D space M-A-L-A-N. Right. That's only 11 -- maybe a [inaudible] character -- so 11 or 12. That's much more efficient than using a char itself. So quick sort of thought question. Even though we know nothing really about MySQL or how databases are implemented, what price are we probably paying if I'm not using a char but instead using a varchar which seems like a win? I'm using less space because I'm only using as much as I need. But what's the hidden cost probably as has been a theme in the class? >>Performance. >>Yeah, the performance, right. So it turns out -- so speed, performance. Whenever we talk about these tradeoffs it's almost always time or space. In this case we win on space. We lose on time. Now this is not worrisome for small databases. But again, for large websites with hundreds or thousands or tens of thousands of users, there's an advantage to having every username 64 characters even if most of those are just blank characters. Why? Because just like an array, you can go from here to here to here by just doing plus 64, plus 64, plus 64. If you instead use variable length strings how do you find someone's name? Well you kind of have to scan the whole list in the worst case because you can't jump from name to name because they're not all in the same boundary. In other words, you have ragged edges in your column. They're not straight like this in Excel. They're kind of different lengths all around. So that does not lend itself to performance. So that's something to keep in mind. So for now, varchar is almost always fine unless you're really, really worried about performance. 64 might even be -- 64 is pretty generous, but we can even make this 128 since we're using variable chars. But you do have to decide. Captain is going to be something like a yes or a no. So I'm actually going to use the Boolean field. So that can just be a zero or a one. Gender I actually have a few options. I could do something binary with Boolean. I could use a string. I could use a number. So we could actually go a few ways here. For simplicity, I'm going to go ahead and choose let's say a char. Let's say -- where'd it go? Let's do char because my form is hardcoded right now as M or F. So if I'm only going to restrict to those two choices, let's just use one single char and not worry about Booleans and such. And then lastly, dorm, this could be a char or a varchar. No dorm name is greater than like -- 128 is -- whoops. Sorry. This we made char. I'm not even sure what that would mean. Okay, varchar, all right 1, gender 1. Okay, there we go. Captain, oh I'm all over the place. All right. Varchar, let's say 128. Why? Just because. It's the same. You have to make a decision. So you might as well pick something consistent in this case. So there's a bunch of other fields we can choose here. And let me just point them out, but they'll be more germane to Problem Set 7. So notice we could specify default value. So this is handy because if you don't want to deal with inserting default values you can actually have your database do that for you. We can also scroll down over here to attributes. And none of these are actually valid just yet. But notice in PSet7 we actually will take advantage of unsigned integers so that we don't waste bits using negative numbers for ID's. We can also scroll over here and specify indices. And this is a fundamental database concept. When you have users in a database or data in a database, you very often want to search that date. For instance, you might want to search by username or search by ID, search by stock ticker symbol, search by friend ID or the like. So to do that by default just as in Excel if you want to search something, well you can use linear search, right? Because your database isn't necessarily going to be sorted if you have people registering or signing up for your website in some random order because they're on the internet. But you can tell your database, 'You know what? I know that I'm going to be doing a lot of searches called selects on this particular field, like name or ID or username.' So you know what, you can tell the database, assume that you should index this field. To index a database fields means to use data structures from last week and two weeks ago in CS50 -- use some treelike structure underneath the hood so that in the future when I ask you a question, 'Has David registered,' you can answer like this instead of much more slowly in linear time by searching the whole database table. So we'll see more of those on Problem Set 7. And null just allows me to specify, you know what this field can be null. Captain could be null for instance is it weren't a Boolean. But for now we'll just leave that thing unchecked. And if I now go over here all the way to the bottom and left or right and click save, what I will see is this. And this again is what this tool simplifies. So what I've highlighted there just a moment ago is a whole bunch of SQL code -- create table and name and captain and gender and dorm. And all of that I could have typed manually at a blinking prompt but instead this tool has created this table for me. So that now if I go back to the left, notice that under my jharvard Week9 database, I have this table. Notice that under this table I have a little reminder of what I actually did. Not to fear, the collation here is all somehow related to Swedish. That's just because the people who implemented MySQL originally were Swedish. But thankfully Swedish characters overlap with English characters. So that simply is the default. And what we have here now is a four field database. Let me see who's in this database. Browse. Okay, no one's in this database at this point in time because I haven't inserted anyone. So let's do just that. Let me go back to my code here and let me open up say register8 dot php. So assume that this is the file of that same form we've been playing with today submits to. Notice I have a few sanity checks at the top. If you didn't give me a name, if you didn't me a gender, if you didn't give me a dorm, go away. Go back to this other URL. Other wise, connect to the database. So this is a new PHP function. PHP plays very nicely with MySQL. It has a lot of built-in support for it. This line of code here says connect to the local host -- that is my server, my appliance -- using this username and this password. We have precreated a jharvard and crimson account for your database in the appliance by default. What database do I want to use? Well I want to select the database called jharvard Week9. That's the one I just created. And now I have to do a couple things for security's sake. We'll talk more about this before long. But for now know that there's this idiotically named MySQL-Real-Escape-String function -- so do as we say not as other people do -- whose purpose in life similar to html special chars is to somehow scrub the user's input. What do we mean by that? If they typed in anything crazy like apostrophes or backslashes or worse -- keywords like delete or update or insert that we might otherwise risk accidentally passing to our database directly -- calling this crazy long function, MySQL-Real-Escape-String, ensures that even if they type something crazy dangerous like delete, I am not going to treat that as a command. I'm going to treat that as a string from the user. So notice I'm declaring a variable called dollar sign name. I'm storing it at the return value of this function that's taking as input literally what the user typed. And now notice -- recall that captain is either the word on or it's just not even present at all. So in this case I have to create a variable called captain that's either the number one for true or zero for false. Then I'm going to similarly scrub gender and dorm with that same MySQL Real Escape function. And now notice how you actually insert into a database. MySQL is running on the same server -- on the same local host. So if I want to insert data into it, I essentially need to speak its language. PHP is not its language. HTML is not its language. SQL is its language. So all I have to do in PHP is create a string using double quotes that matches the server's expectations for how to insert data. And it turns out to insert data into a database, you can say, insert into the name of the table. Then in parentheses you specify a comma separated list of the fields that you want to insert values into. Then, it's on the new line but this could all be one line, you literally say values. And then another set of open parentheses. And then inside of this second set of parentheses, you put another comma separated list, this time of course with the values. And notice one key important detail here. I'm using single quotes around each of these variables' names because they are strings. They themselves have to be quoted. I can't use double quotes really because I've already used them. So the simplest approach is to use single quotes there. And now this is one thing we could not do in C. In C we had to do things like printf and sprintf. With PHP, if you want to insert a variable here in a string, you literally just write that variable's name. It will be interpolated inside of the double quotes. This last line here, MySQL query, dollar sign SQL, will actually execute that query for us so that if I go to froshims8 dot PHP and if I type in David and captain and male and Matthews and click register, it says I'm registered, which it's been saying frankly all week. But if I now go to my database and click browse, oh my God, it actually worked. I have now registered for froshims. Happy Halloween. We will see you on Wednesday. [ Applause ]