DAVID MALAN: All right. This is CS50, and this is the end of week nine. It's been a whirlwind over the past few days. And problem set seven, if you're knee deep into it, realize there's quite a bit new that's in there. But let's see if we can't piece everything together here briefly before then veering off in yet another direction and seeing where else we can go. So thus far, we've talked about HTML. We've talked about CSS. We've talked about PHP. You've started to experience SQL. Today, we'll talk a bit about JavaScript. But how do all of these disparate languages fit together? So we talked last week about the notion of having a server. So let's just draw this rectangle as a web server here. And a web server serves surely files. And some of those files can be HTML files. So one of the things that a web server can spit out might be a file that we'll just draw like this containing some HTML. So in layman's terms, what does HTML let you do? AUDIENCE: Page look nice. DAVID MALAN: OK, make a page look nice, although I think I've proven that otherwise. So HTML does let you lay out pages structurally, and it allows you to sort of aesthetically mark up a page, mark up static content, so that you can then view it with a web browser. But that's the key. It's static content. You write it, you save it, and then you ship it. And the web server then serves it up to your visitors. But we stylize things using a different language altogether. We started to use a style attribute on certain tags. And the style attribute let us set things like font size and color. And you've probably started to discover, or you soon will for final projects potentially, yet other properties that you can use in CSS. And so in layman's terms, what really then does CSS do? Those are just examples thereof. What does it let you do that HTML doesn't seem to from what we've seen thus far? AUDIENCE: Define styles by yourself. DAVID MALAN: Define styles by yourself. So define things like classes as you may have encountered, or uniquely identify nodes in a document so that you can stylize them. But more specifically, I'd say that CSS really lets you take things the last mile and allows you to specify much more precisely the aesthetics, whereas HTML for the most part lets you structure your pages. And even though there are some defaults, like we saw the tag for a heading tag, which roughly speaking made things big and bold. That's a pretty generic definition of the tag-- big and bold. What font size is that? What color is that? How bold is that? And CSS lets you more finely tune things like that. As well as layout, as some of you have seen. And frankly, CSS is a bit of a messy language. It's very powerful in that you can make literally any website that you've seen on the web today with it, but it's kind of a pain in the neck. And some of you have banged your head against the walls already just to do something stupid like center a menu on problem set seven if you've gotten to that point already. But realize, those things get easier over time. You start to notice patterns. And again, Google will be your friend for the various ways in which you can solve these kinds of problems. And I dare say with CSS, and HTML more generally, you can solve problems in many more ways, all of which might very well be correct, than you could in something like C, even now PHP, or JavaScript. There are just many different ways to lay things out. But this started to get messy, we said. Just kind of commingling your HTML and your CSS with the style attribute was a little sloppy. And so we instead said, sort of abstractly speaking, that you should at least start to factor out your CSS probably. Not your style attributes, but at least use the style tag inside what part of the web page? AUDIENCE: Head. DAVID MALAN: In the head. Up until now, we only had the title up there, but you can also add a style tag, and you can put your CSS roughly speaking toward the top of the page. But then we took things one step further and we factored that out more into a separate file. And so these two files were somehow now linked. And indeed it was the tag that did that. And what was one of the overarching motivations for factoring out our CSS all the more? AUDIENCE: Reusability. DAVID MALAN: Reusability. Right? You may have seen in p-set seven already that a lot of the pages, the buying page, the selling page, the portfolio page, are probably structured somewhat similarly. There's a CS50 finance logo at the top unless you've decided to change it. There's a footer at the bottom of pages. And CSS allows you then to factor it out it into a separate file so that if you want to change something globally across your whole site, you can really just change it in one place. But there is a price you pay potentially by having factored out the CSS from my HTML file into a separate file referencing it with the tag, which we saw on Monday. What might the downside be of this? Thinking back a week ago to when we're talking about HTTP and TCP/IP and how the internet works. Something over here? AUDIENCE: It takes more time. DAVID MALAN: It takes more time. Why? AUDIENCE: [INAUDIBLE]. DAVID MALAN: Yeah. So it arguably takes a bit more time. Because one, the CSS is obviously not in the same file. So now you have to make not one, but two requests. And each of those requests as we saw in Chrome in the so-called Inspector, and we looked at the network tab, each of those files requires one HTTP request, which we saw takes some amount of time. Now, maybe it's not a lot. Maybe it's only 20 milliseconds. Maybe it's 200 milliseconds. But think about a page like Facebook, or CNN, or Google, which are much larger than the examples we've looked at thus far. Those pages might have dozens of files, each of which might require a download of a file. So things can potentially start to slow down. And especially these days when we all have mobile phones in our pockets and slower internet connections, having to wait a few more milliseconds, a few more milliseconds for additional files can actually be slow. Latency is the word that describes the kind of waiting that you have that you experience when waiting for some piece of information. But there is an upside. So it's not all sort of a-- it actually is a bit of a seesaw here. Downside now, but what browsers can do if they're smart in order to avoid having to request the same styles.css file again can be to do what? Cache it. So caching-- C-A-C-H-E-- generally means here just to save the file you requested the first time, and then check your cache for it. Check you're sort of storage container, and if you already have a copy of styles.css, even if some other page in the p-set, or any website, requests it again, just to give the user that same cached copy. Don't bother requesting it. Downside there, though, as some of you have tripped over in the p-set. If you make a change on the server and you go back to the browser and you reload, sometimes the browser does you a favor and doesn't bother re-downloading your styles.css file because, come on, what are the odds that these styles that Facebook uses are going to change hour to hour or day to day? It's pretty low. They might change over time, but not by the minute or by the hour. So a trick, just FYI when doing web development, is often hold down the shift key for instance and then click reload in your browser, and that will typically tell the browser reload everything, even if you already have it in the cache. So again, upsides and downsides, but all of them ultimately design decisions. So now, we didn't just end the story here. If I now go back and back and back and back, we started to introduce not just HTML, but PHP. So in layman's terms, what does PHP let us do? AUDIENCE: [INAUDIBLE]. DAVID MALAN: What's that? AUDIENCE: Introduce logic into the code. DAVID MALAN: Yeah, introduce logic into your code. So it's a true programming language with loops, and variables, and functions, and conditions, and all of the things we've been using way back when since scratch. And PHP, we've seen, can be used either at the command line-- it doesn't have to have anything to do with the web, even though that's really its origins and what it tends to be good at and conducive to-- but you can use PHP merely by nature of the fact that it has a print() function, and a printf() function, or an echo() function. There's bunches of ways you can print text with PHP. Therefore, you can use this programming language to output exactly what we were talking about before. You can dynamically generate your HTML. Maybe not all of it. Maybe you hard code things, like the header, and the footer, and the logo, and your style sheets, and all of that. But for something like p-set seven, where you're manipulating stocks and showing the user's portfolio, which is going to dynamically change, you could surely use PHP and the logic it gives you as a programming language to output dynamically subsets of the page. So when you talk about dynamic websites, or web programming, that's what you're really talking about. Using a language like PHP, or things called Python, or Ruby, or Java, or yet other languages, to query a database often, or another server, and then dynamically spit out HTML. Now the end result, as an aside, is that the HTML of most websites, including your p-set seven, is probably going to be a huge mess if you look at the source code in a browser. That's not a big deal. At this point, when we care about style, we care about the stuff that you write. We won't care about the stuff that what your code outputs. So don't worry about indentation here if it's PHP that's actually outputting stuff. After all, the browser won't care, and a human won't be looking at the source anyway. We the staff, for instance, would be looking at your PHP. So let me give a quick example now of why else this might be useful. So frankly, I can't remember the last time I used C to solve a problem in the real world. It was probably in graduate school when I needed to use a language that was fairly low level and gave me the opportunity to do something very high performing to really save as many CPU cycles as I could, in large part because I was using huge data sets, and every CPU cycle counted. And frankly, even in things like phones these days and other devices where you don't quite have as much memory and you don't quite have as much CPU, using faster languages is still appealing. But in the real world, when you just want to throw some program together to analyze some data, or you've collected a whole bunch of registrations for some student group and you want to very quickly automate sending emails one by one to every one of those registrants, you're going to reach for a higher level language than C so to speak. Something like PHP or Python, or Ruby, or a half a dozen others that exist these days. But those three are probably the most trendy right now. And what this means is that you can open up a text editor like gedit or most anything else and then just start writing code without having to worry about compiling, without having to really worry about memory management, keeping in mind though that a little sloppiness will eventually come back to bite you if the data set gets larger or the problem gets big. But what this means for us is the following. Let me go ahead and run speller from problem set six. So this is my trie-based implementation that I used on the big board where I performed not so well. We'll come back in a week's time and revisit those who did end up atop the big board at our last lecture. But for now, let me go ahead and just run my solution in text, and we'll do the King James Bible, and here we go. So those are all of the supposedly misspelled words out of the King James Bible. And my implementation took half a second in total. So not too bad on this particular computer. But think of how much code I had to write. Think how much code you had to write. Think how many hours you spent in the D-hall or your dorm or wherever actually coding up that solution. Well, if I actually have a higher level language like PHP, take note of what I can do here. First, suppose that this is instead your distribution code. This is a file called speller. It's available as part of today's distribution code. And I'm going to wave my hand at most of the details, but this is actually an interesting example of how you might port a language like C over to PHP. I literally opened two text windows, one with my C version of speller.c, and I just started translating it in my head to PHP and typing it out using the closest equivalent functions. So some of these things are different. We saw last time that PHP doesn't use include in quite the same way. It uses require typically, though include does exist. Define is a little different from #define in C, but that's how we make a constant. $argc it turns out exists in PHP, so we've seen that before. These are just variables, all of which start with dollar signs. Recall these are just a bunch of floating points. So long story short, you're welcome to flip through this if curious, this is almost a line-for-line conversion of the C version of speller.c into PHP. And you could do this again for half a dozen other languages. But what's interesting is this. Or what's frankly disheartening is this. Let me go ahead and type about dictionary.php, and claim that I'm going to go ahead and re-implement problem set six here. So let's propose first that in this file, which will be implemented in PHP, so let me open my tags like that. Let me give myself a global variable, $size gets zero. And I'm going to give myself a hash table. I'll use a hash table for this thing. How do I declare a hash table in PHP? Done. OK. So open bracket close bracket represents what in PHP, as we've seen? An array, but an array that could be an associative array. An associative array is a data structure that associates keys with values. Now in the simplest numerically indexed array, those keys are what? Zero, one, two, three, right? Old school stuff back from C. But it can also be strings like foo, and bar, or maxwell, or any such string. So I can leverage that in just a moment. Let me go ahead and declare a function like-- let's do load() first. So function load(). And PHP is a little different in that you literally type function, but you don't type a return type. I'm going to go ahead and say that the load() function should take in argument $dictionary, just like C version did. I'm doing that from memory. And I propose that I'm going to do this. I'm simply going to do foreach. I'm going to call a function called file(), passing in the name of that file, which is the variable $dictionary as $word. And then inside of my for loop here, I'm going to go ahead and store in my $table that $word gets true. Done. Oh, wait. Done. OK. That is the load() function say in PHP. Now, why does that work? And I'm kind of cheating here. So, one, foreach we saw briefly last time. It just means that you can iterate over an array without bothering with i and n and plus plus, and all of that. Dictionary is of course the file name, something like large or small, the two dictionaries we used last time. File is a function that opens up text file, reads it in line by line, and hands you back a huge array, each of whose elements is a line from that file. So that's the combination of fopen, and fread, and while loop, and fclose, and all of that. Finally, as word just means that's the variable I'm going to have access to on every iteration in this loop. So in short, this one liner here means open up the file whose name is in dictionary, the variable, iterate over it line by line, and each time you get a line, store in a variable called word, and then do something with word. What do I want to do? I want to put word into my hash table. Well, I can put something in my hash table just like in C using square brackets. This is the name for my hash table. I'm going to index into that hash table at this location. So not bracket zero, not bracket one. Bracket quote unquote something, whatever that word is. And just like you might have in your hash table work trie, you just store effectively a Boolean, implicitly or explicitly. Done. I'm storing the value true. Now there's a couple of things I'm cutting corners on here. Technically, there's going to be an annoying new line, /n, at the end of each of these words. So I should probably call a PHP function called chop(), which will quite literally chop that off. And I actually need to do one other thing. I should probably increment size on each iteration, so I'm keeping track globally of what it is. And frankly, and this is one of the stupider aspects of PHP, if you're using a global variable, you need to explicitly say that you are. So I'm going to actually type in global $size, global $table, and now my function is complete. So not quite as simple as before, but probably took less time than the C version, maybe? OK. So now let's do the check() function. Let's see if this at least took the hours on end that it took us in C. So let me go ahead and declare check as a function. Takes in argument word, which is going to come from speller. And I'm just going to check if the following variable isset, table bracket strtolower of word-- let's balance all of my parentheses-- then return true. Else-- that was really the hard part of this program. Else, return false. Done. That's check(). Now, why does this work? Well, one I passed in a word, which is a string. Two, I'm checking inside of the hash table, who's called $table. I'm forcing it to lowercase by calling a function quite similar tolower() in C, but this does the whole word, not a single character. And if that is set, in other words there is a value set, in other words, if it's true, then yes, this is a word. Because I put it there with load(). And if not, I'm going to return false. Now the others are easy. Function size(), how do I do this? I essentially do return $size. But I technically need to do this annoying thing. And actually up hear, I was cutting one corner too many. I really need to do global $table. But that being said, unload). Unload() is amazing. Function unload(). How do I want to implement unload()? Done. OK. So unload(), memory management is completely taken care of for you in something like PHP and a lot of higher-level languages. So this is amazing. Like why the hell did we spent the past eight plus weeks on C writing apparently really slow, really time consuming problems with tens of hours of work under our belts? Well, for one thing, this may work fine for small programs. It certainly sped up my development time. But let's see what happens in the real world. Let me go into this directory in a terminal window. There's speller. And notice as an aside, and you might have encountered this in problem set six or problem set seven. You don't strictly have to end PHP files with .php. If you put a line like that first one at the very top, that's a special line of syntax that essentially means find the program called PHP and use it to interpret this file. So now no one really knows that I'm running a PHP program. I can run it just as though it were something compiled in C. But here's the thing. Actually, let's do this again. Dropbox/pset6/. There's speller. OK, 0.44 seconds. It got faster this time. Now let's go into the PHP version. Nice touch. But just think how much time I saved at office hours. OK. So 3.59 seconds, which actually doesn't sound accurate either. But that's because long story short, when you're printing out a huge amount of stuff to the screen, that itself slows things down. What it really took the CPU in the appliance was 3.59 seconds, in contrast to C, which took 0.44 seconds most recently. That's truly an order of magnitude different. So where is that price coming from? Why is it so much slower? Why does PHP perform so poorly? Danielle? AUDIENCE: You didn't really use a hash table. DAVID MALAN: I didn't really use a hash table. So I kind of did. So it's an associative array. Most likely if the people at PHP are really smart, they used underneath the hood an actual hash table implemented in something like C or C++. But. Yeah. AUDIENCE: [INAUDIBLE]. DAVID MALAN: Yeah. So each of the functions I wrote now-- actually, can you say that once more a little louder? AUDIENCE: Each of the functions that you included has a lot more full capacity than-- DAVID MALAN: So that's very true. There's a lot more overhead that we're not really seeing by focusing only on dictionary.php, which I just wrote. By contrast, there's a whole interpreter going in the background. Indeed, when I ran this program, it wasn't running compiled zeros and ones designed for my Intel CPU. Rather, it was running line by line PHP code that looks exactly like we typed it. And so whenever you use an interpreted language, you actually do pay this price. It's going to take some time to read your file top to bottom, left to right, and then execute each line again and again. Now in reality, especially on the web, you can actually expedite this process by caching the results of the PHP code being interpreted. And that makes sense on the web, because if you have not one user like me here, but 1,000 or 10,000 users, then maybe the first time the file is accessed it's slow, but thereafter it's much faster. But this too, again, is a trade off. And for something like a research data set, or even something large like this, your users will eventually start to feel that slowdown. So in short, interpreted languages are very much in vogue, very popular, and frankly are probably the languages you should reach for when solving problems subsequent to CS50. But realize how much you're really taking for granted underneath the hood really those past several weeks in hash tables, and trees, and tries, which are used ultimately to actually implement things like open bracket, square bracket, which we can now gratefully take for granted. So let's take a look now in this web context. And I mentioned last time that there's a bunch of superglobals in PHP that aren't really relevant at the command line. They're more relevant in the context of using PHP in a web context. So running PHP on a web server in order to generate stuff like HTML. And we glanced at $_GET and $_POST, and that's where automatically users' input ends up simply if you submit a form to a file ending in .php on a web server like the appliance. But let's look briefly at $_COOKIE and $_SESSION. In layman's terms, what is a cookie as you understand it in the context of using the web? AUDIENCE: File on the computer. DAVID MALAN: Yeah. It's a file on the user's computer planted by whatever website you happen to visit. So when you go to Facebook, when you go to bankofamerica.com, when you go to google.com, when you go to almost any website in the world these days, including cs50.net, a cookie is planted on your computer, which is either a value stored in RAM in your computer in your browser's memory, or sometimes indeed a file stored on your hard drive. And what's typically stored in that file is not your user name, not your password, typically not something sensitive unless the website is not so good with their security, but rather it is a big unique identifier among other things. It's a big random number planted on your computer but you can think of as sort of a virtual hand stamp like from a club or some amusement park that allows the staff, the owners of that service, to remember who you are. So if the big random number is like 12345678, although that's obviously not too random, think of that as the hand stamp that when you visit facebook.com for the first time, they stamp that number on your hand. And then because you speak HTTP, you being a browser, and because Facebook obviously speaks the same as a web server, the protocol HTTP says that anytime you subsequently visit facebook.com, whether it's a second later, an hour later, even the next day, so long as you haven't explicitly logged out, which effectively is like washing your hands. HTTP says you should present your hand stamp every time you return to that website. What Facebook then does is they look at that hand stamp and they say, oh, 123456789. I don't know at first glance that this is David Malan in Cambridge, Massachusetts, but they can check their database and say, oh, the person on whose computer we planted 123456789 is David Malan from Cambridge, Massachusetts. Let's show that user then his profile page or his News Feed. But there's a problem here if this is how the web indeed works. Let's take a look at a quick example. Let's actually go to say facebook.com. But before we could go there, let me go ahead and open up Chrome's Inspector down here. Let me look at the network tab. And now let's go ahead and type in https://facebook.com. And I'm doing that so that we don't see all of those redirects and waste time looking through those. Let me hit enter. All right. We see a whole bunch of requests. There comes Facebook. There's a whole bunch of files. And here, per my mention of latency last time, that's a lot of HTTP requests. But the first one is probably the most interesting. So let's scroll down here, and I'll zoom in in a second. This is going to be kind of a mess, but let's see. Facebook is sending us a whole bunch of stuff. But whoa, interesting. They're planting not one, but four hand stamps onto my hand here. Set-cookie, Set-cookie, set-cookie, set-cookie. And there are a few features here. All of them mention some kind of expiration. And it looks like Facebook is hoping to remember me until 2015. So that's presumably the time by which I must log out or they'll just automatically assume I'm not coming back. So that's actually a decent amount of time. And there are some other things going on here. This cookie appears to be forcibly deleted by saying it expired in 1970 before cookies existed. So the browser is just going to assume OK, that's like washing the hands stamp. But now when my browser makes a subsequent request-- let me go ahead and do this again and reload. Now let me scroll back to the top request and go down here, request headers. Notice this. So now I'm under not response headers, but notice it says request headers. And notice that my browser as part of its request after hitting reload has sent at least the following information. Not set-cookie, but cookie. So this is the line, the HTTP header so to speak, where my browser is sort of without my knowing it presenting my hand for Facebook's inspection. So these cookies can be used then for what? To remember who you are, or remember how many times you've been there, or really anything. So here is counter.php. And let me zoom in on the font. And each time I reload this page, notice it's remembering how many times I've been there. Well, that's not all that impressive. Let's just close that tab, and now let's go back to http://localhost/counter.php. Oh, that's interesting. It still remembered, even though I closed the tab. And frankly, if I close the browser, if implemented in the right way, I could still remember that this user is who he or she was the first time, and only once I go into Chrome's menu, which over here is here, and go to History, and click Clear Browsing Data, as some of you may have in the past, only then will your cookies actually be deleted during web development. So, if we go-- let's close up gedit here. And if we go now to this file. Let me go into our vhosts/localhost/public, and let me do counter.php. Notice that this is a pretty simple program. It's a pretty simple website. So the top of the file is just comments. But here's a new line that you may have seen already in p-set seven, session_start(). This is a line of PHP code that essentially tells the web server, make sure to stamp hands and make sure to check hand stamps. That's all that line does, and it does all of that process for us. Then notice I've just got two branches here. If the counter key inside of this special global variable called $_SESSION is set-- in other words, if there's some value there-- let's get it and store it in a local variable called $counter. Else, let's assign $counter the default value of 0. Now here's one aspect of PHP that's both a blessing and a curse. PHP is a little sloppy. So whereas in C, what would the scope of counter have been either here or here? It would have been confined to those curly braces. Guess what? In PHP, it exists even outside of those curly braces, here, and here, and here, and here, and even down below. So I say this is a blessing in the sense that you don't have to think as hard as we did weeks ago. But it's also a bit of a curse in that no matter where you use a variable in PHP, at least in a program like this, it's globally accessible for better or for worse. So you have to keep in mind now that your variables may not be undefined. You might have defined them elsewhere. But what am I going to do ultimately? I'm going to store inside of that global variable as a value of the counter key the result of doing counter plus 1. So this is just the arithmetic that does the incrementation of that counter. And the fact that I'm storing that value back in here is means to essentially update the database to remember that user 123456789 has been here two times. And when I do it again the next time I reload the page, it's going to check my hand stamp and say, oh, user 123456789 has now been here three times. And so what PHP and similar languages are doing for us is they are figuring out how and where and for how long to store values in this special superglobal. And this superglobal the next time I visit the page is sort of magically pre-populated, filled with values that were there the last time you visited, whether that was a second ago, a week ago, or in 2013 and we're now talking about 2015. PHP and the web server take care of all of that for you. AUDIENCE: [INAUDIBLE]. DAVID MALAN: Variables in PHP are essentially always global unless you declare them inside of a function, and then they are local to the function only. But because I've not written any functions, they are now effectively global throughout my whole file here. AUDIENCE: Is there a way to make them local? DAVID MALAN: Is there any way to make them local? Only by wrapping them into functions. Which in the latest version of PHP, you can do this with an anonymous function. But more on that in the context of JavaScript. But the short answer is no. A longer answer is yes. Nice. Good quiz question. All right. So lastly, the page itself is actually pretty simple. Notice that once I exit PHP mode, recall that all of this stuff down below is just going to get spit out raw to the browser. Which is fine, because I do want to send the user some HTML, but I do want to dynamically update that HTML. And one way I can do this is to sort of very quickly drop back into PHP mode, use open bracket question mark equal sign, and then output the value of counter. Or if this looks a little cryptic, this equal sign is actually just some syntactic sugar for this printf($counter). But frankly, that's just a little ugly and a little annoying to type. So PHP very nicely offers this feature where you can just say it more succinctly in the same way. So what's going on underneath the hood? Let's quickly look at the network tab here for counter.php. And let me go ahead and first let's clear your cookies. Let's clear browsing data since the beginning of time. Now let's go back over here. Now let's reload the page. And I'm back at zero. Because my hand stamp has been washed, I now get a new cookie. Indeed if I look at the network tab and look at response headers, notice that the appliance is sending me a cookie whose name is somewhat arbitrarily, but kind of reasonably, PHPSESSID. And it's sending me this really big random number. It's not quite a number. It's not quite hexadecimal. It's some kind of alphanumeric string, but presumably it's random. And that is the hand stamp so to speak that I'm referring to. Meanwhile if I click reload and then look at this second line for my second request, notice now that my request headers include PHPSESSID equals this, not set-cookie, but just cookie. And that's my browser's presentation of my hand stamp. So now as a teaser, and we'll talk more about this in a week or so, but in what way does this make you vulnerable, your Facebook account vulnerable, and other such accounts vulnerable? AUDIENCE: If somebody has your cookie. DAVID MALAN: Yeah, if someone has your cookie. I mean truly, much like some of you might have tried at like a club or an amusement park, if you try something like this to copy the stamp, albeit backwards onto another person's hand, and then he or she presents it as their own, if it actually does look identical, 123456789, then the web server is apparently just going to trust that that user is you. And this is indeed a fundamental threat any time you use cookies because if someone just spoofs so to speak your cookie, figures out what it is, either by truly copying it by looking at your computer and being like, OK. David's cookie is JJ3JIK and so forth, and then they're smart enough to know how to sort of manually send that cookie from a browser or from a program they write, they could totally log into a website as you. It is not that hard to pretend to be someone else unless we revisit p-set two, which introduced what? AUDIENCE: Cryptography. DAVID MALAN: A little bit of cryptography. Simple cryptography, at least in the standard edition, but crypto nonetheless. less. So it turns out if you encrypt all of these headers using something that you might now know more familiarly as SSL, secure socket layer, or https:// URLs, then all of these things we've been glancing at are actually encrypted, which means that it's like you can't read the hand stamp. Only facebook.com can, or google.com, or in this case, the appliance can read that hand stamp. Tragically though, and again, this is all too appropriate with the NSA stuff of late, even SSL is breakable. And it's actually not that hard to even crack that encryption. Not so much by cracking the encryption, but by tricking the browser into decrypting the data prematurely. But again, we'll tease you with that before long. For now, just be afraid. It's tragically kind of true. All right. So, where does this now leave us? Well, let's do this. Let's go ahead and take a quick teaser before we take a break. And I think we'll linger a bit longer today, but we're going to dive into something brand new and sexy, which will whet your appetite for even more. So that's the teaser. So SQL, we started talking about ever so briefly last time. You'll really get your hands dirty with some of it in p-set seven. And in layman's terms, what does SQL-- S-Q-L-- do for you? What is it? Yeah. AUDIENCE: Let's you access data. DAVID MALAN: Yeah. It let's you access data in a database. Structured Query Language. And this is essentially a programming language. There are features of it that we won't even use in class. But you can effectively define functions. They're called stored procedures in SQL. But we'll keep it fairly simple and just use it for some basic operations like selecting data, inserting data, updating data, and deleting data. And you can really think of a database, like a SQL database, as just being Microsoft Excel. Because SQL refers to a relational database, where relation just means tables. Rows and columns. So anything you can put in a spreadsheet like this or Google Docs, you could put into a SQL database by declaring a table. Now, how do you actually access that information? Well, with commands or queries like this. SELECT, INSERT, UPDATE, and DELETE. And for the most part, those are the four only ingredients you'll need to do something quite powerfully in problem set seven. Now back in the day, you would actually interact with a database in a black and white terminal window at a blinking prompt like this. And the database we're running on the appliance is called MySQL, which is free and open source database engine. If you Google and read the Wikipedia article, you'll know that the name is a bit of transition for some versions of Linux. Maria database is actually a fork so to speak of MySQL. Long story short, Oracle bought MySQL. Oracle's a big company. People have been worried that it would no longer remain quite as open source, so this is just a copy of MySQL that's still free, still open source, and installed in Fedora Linux by default. But this is kind of a pain in the neck to get acquainted with a database this way. So we include in the CS50 appliance a free open source tool called phpMyAdmin. Just a coincidence that it's written in PHP. There's no fundamental need for PHP here. But this is just a web-based tool that we downloaded for free, installed in the appliance, that allows us to have a graphical user interface with which to explore the p-set seven database with which to create new databases, say for your own final project if you'd like, and ultimately create dynamic websites like CS50 Finance that allow you to query data and update data dynamically. You're not going to have to use just a simple text file or CSV. You can actually use a smart database program so that you can execute more sophisticated queries than just reading through everything linearly. So for instance, this is what we give you out of the box for p-set seven. This is a table with apparently at least three columns, one of which is username, one of which is hash, and the other of which is ID. But the interesting thing, and just to tease out one thought here, username is presumably already unique, right? I mean, most any website, if you have a username, there can't be two caesars. There can't be two malans. There can't be two jharvards. Its unique. Otherwise, they don't know which jharvard it actually is. So what might be the motivation for also having a third column on the left there called ID, which looks like a number that's similarly unique? It feels a little redundant to me at first glance. Why might it be compelling to have not only unique usernames, but also unique numbers? AUDIENCE: They could have the same password. DAVID MALAN: People might have the same password, sure. That could absolutely happen. But if they have this unique username, I would argue that that doesn't really matter, because if they type in their username, I only need to check their password, their hash thereof. Why else? AUDIENCE: Faster searching. DAVID MALAN: Faster searching. Why? AUDIENCE: ID is just one. DAVID MALAN: ID is just one character, or to be more precise, it's a number, so it's probably 32 bits or something like that. Whereas the username, apparently Jason Hirschhorn's up there is sort of ridiculously long, and it's going to take me a lot more time to string compare H-I-R-S-C-H-H-O-R-N, and maybe a /0 or something like that, in order to look up Jason, as opposed to just saying give me user number two. That's 32 bits. It's a single INT that you have to compare. And indeed, that's exactly why databases tend to assign unique IDs to rows in them. Now what other data types are there besides INT and apparently strings like this? Well, to be more proper, SQL databases, like MySQL, have CHAR fields. And CHAR a little misleadingly is not a single CHAR. A CHAR field in a MySQL database is one or more characters, but it's a fixed number of characters. So for instance, if I go over to phpMyAdmin as you may have already, or soon will a problem set seven, and I go to my database, and just for fun, let's create a new table called test with just two columns. I'll then click Go. And this will become fairly familiar, especially as you tinker around on your own. Here I might type ID to create a new table of type INT. But here I might type username to recreate that earlier table. And notice I have a whole bunch of types to choose from. And this too is why phpMyAdmin is kind of nice. It's kind of self-teaching in that you can just kind of point, and click, and look at dropdown menus, and infer from that what powers SQL gives you. And indeed, if I choose CHAR, I then have to specify the length, or how many values, how many CHARs. So very common values are things like 255, but that's a little long. Commonly is eight for a username. But that's a little small these days. So this is a design decision. Is it 8 characters max, 32, 255, 1,000? It's really up to you. But a CHAR field is a fixed number. So choose too few and you're kind of screwed if you want a longer username. Choose too many and what's the downside? AUDIENCE: [INAUDIBLE]. DAVID MALAN: It's wasteful. Just like in C, if you have a bigger chunk of memory than you need, you're just wasting time and wasting space. So as an alternative, there exists VARCHAR, which solves this problem by treating length not as a fixed length, but as a maximum length, and using a variable number of CHARs, which then tends to use only as many CHARs as you actually need. That sounds perfect. Why don't we get rid of the CHAR data type then? What might be the downside of using VARCHARs, which sounds like it's a nice win? Yeah? AUDIENCE: [INAUDIBLE]. DAVID MALAN: OK, good. So if all of your data is the same length, what's the concern? AUDIENCE: Because you're wasting data by telling them all. DAVID MALAN: So if all of your data is the same length, though, I would argue that specifying a maximum length on VARCHAR is no different from specifying a fixed length on CHAR if you know that number in advance. But there is indeed, and I'll sort of extract from that answer the reality that there's still a max, which could be annoying, especially if you encounter a person's name that's unusually long that you didn't anticipate. And it's also a little less efficient to actually search on VARCHARs as opposed to searching CHARs, especially for long tables that have lots and lots of data. So here too, thematic is again no obvious choice. So just to give you a sense of other data types that might be of interest either for p-set seven or in the future, there's INT. There's BIGINT, which is like long long. It tends to be 64 bits. There's DECIMAL, which you'll see in the problem set, which is a much cleaner answer to the problems we encountered with float and floating point imprecision. And then there's DATETIME. There's literally a data type that has to look like a year, a month, a day, and an hour, minute, and second. But SQL databases also have things we'll call indexes. And an index is something that you specify when creating the table to make searches and other operations more efficient. Specifically, there's something called the PRIMARY index that you could declare as follows. We did this for you with the users table we give you. But notice if I were manually recreating the users table here giving it a name of users. I already specified ID. I specified INT. I specified username with maximum 32 characters. But if we keep scrolling in this fairly wide window, notice there's a bunch of other things I can specify. One, I can specify attributes like, you know what, this INT should be UNSIGNED. I don't want negative numbers, so let's make it UNSIGNED. Null is not relevant here because I do want every user to have a unique number. I don't want it to be null. But this is interesting. I can specify that ID is either the primary key of this database, or it's unique, or it's indexed, or full text. So for today's purposes, long story short, PRIMARY means that this shall be both conceptually and technically the field that we use to uniquely identify users. So when we look up users, this is sort of a promise to look them up mostly by that unique identifier. And the database will ensure that if you have a user number 3, you cannot physically insert another user with that same number 3. The database will just refuse to save your changes. Which is a good thing, because you can protect yourself from yourself. self Alternatively, for username. So the second row, recall, is the username field. So the second row here is username, as we did on the far left there. So what else might I want to specify? I'm not allowed, according to SQL, to specify two primary keys. you can specify a joint key where you look at both fields, but they can't individually be primary keys. So that's out of the question. So which might I want to choose? Well, UNIQUE is similar in spirit to a primary key where you specify this field shall be unique, but it's not going to be the one I use all the time. And we're not going to use this one all the time for what reason again? It's slower potentially if it's a long username. It's just a waste of time. INDEX, meanwhile, specifies that it's not going to be unique, but I'd like you to work your magic underneath the hood to make it faster for me to search on this field. So this probably isn't relevant here. For username, I'd argue that UNIQUE is a good answer. But suppose that we made users more interesting than just usernames, hashes, and ID numbers. What if we gave people full names? What if we gave them addresses and other data about them? Well, if you specify that a column in a database is indexed, that means that MySQL, or Oracle, or whatever database you're using, should work its magic and use some kind of fancy data structure like a tree, or a trie, or a hash table, or something to guarantee that when you search for data using select on that particular field-- like show me everyone that lives on Oxford Street. A query like that. If you have specified in advance that you want an index on that field, the searches will be much, much faster. If you don't specify an index, the best you can do is a linear search if it's not sorted. But if you specify INDEX, the smart people who made the database-- people like you who now know trees and tries and hash tables-- will automatically build such a data structure in RAM to make sure that those searches are much faster. FULLTEXT meanwhile is similar in spirit, but allows you to do wildcard searches, like show me everyone that lives at streets that begin with the letter O for whatever reason. You can do wildcard searches like that. Or, more compelling things like show me everyone who has the word-- show me everyone whose name starts with a particular letter. You can search for keywords in this way. All right. So, design opportunities there potentially. There are others that I'll wave my hands at. It turns out that you can have different storage engines. And this is more arcane than we need certainly for problem set seven. By default, you guys are using something called InnoDB. You'll see mention of this somewhere in phpMyAdmin's interface most likely. But know that there are other design decisions that are of potential interest come final projects if you do something web-based. But let's do this. Let's go ahead and put this on the screen as a teaser for a story involving you, a roommate, and a glass of milk. Let's take a two minute or so break here. And if you can stick around, let's come back, look a bit more at SQL, and then a bit of JavaScript with p-set eight in mind. All right. So, let's get you thinking about a corner case that can very easily arise in the context of using a database, or frankly, even using real world things like ATMs to get money. So here's a refrigerator. Suppose you've got one too in your dorm or your house. And you've got one roommate, and both of you really like milk for instance. So you come home from class one day. He or she's not yet back. You open the fridge. You really want a big glass of milk. There's no milk. So what do you do? You close the fridge. You grab your keys. You go out to the square. And you get in line at CVS at those self checkout things, which always take longer than actually having cashiers. Anyhow. So then, meanwhile, dot dot dot, your roommate comes home and he or she similarly has a hankering for some milk. So he or she opens the fridge, looks inside, and oh, damn. No milk. So he or she heads out, happens to go to the other CVS, which was only a block away for some reason, and he or she gets in line to buy some milk. Meanwhile, you come home, he or she comes home, and what do you ultimately have? Twice as much milk. But you don't really like milk that much. So now you have so much milk that now one of them is just going to go sour eventually. So this is a really bad problem. Right? So what has happened? So fundamentally, this is kind of a ridiculous example. But underneath the hood, what we've had happen here is both of you checked the state of some piece of memory, the refrigerator. Both of you checked the state of some variable. You both drew a conclusion that you then acted on. But unfortunately, while your roommate was at the store, the state of that variable changed, he or she came back and now wants to change the state, but it's already been changed on him or her. And of course, he or she would not have gone to the store if they knew that you were already en route. So in the real world, how could you avoid this problem, assuming you have a fridge, you have a roommate, and you actually like milk? AUDIENCE: Communicating. DAVID MALAN: Communicating. OK. But how might you communicate? AUDIENCE: Leave a note. DAVID MALAN: Leave a note, right? Always leave a note, for fans of the show. All right, so always leave a note, or put truly like a padlock or something on the refrigerator that keeps your roommate from inspecting the state of that variable. Now, why might this be germane to problem set seven, or to ATMs. Well, imagine a world in an ATM where you might be able to go up to an ATM machine here, and another ATM here. And this happens quite often. And suppose you had two ATM cards, which is possible to obtain. And you log into both machines effectively simultaneously, hopefully while no one's looking. And then you type in your PIN roughly simultaneously. And then you do a balance query to see how much cash you have. And let's say you have $100 left in your account. So essentially simultaneously, you say one, zero, zero, enter. And you hopefully get back some money. But how much money might you get back? Now computers at the end of the day, especially if they're talking to servers, don't necessarily do things in the order that's expected. So suppose what happens, because of whatever network speed issues there are, or CPU issues there are, or anything like that, suppose that the first ATM checks your balance and sees, oh, this person has $100. But then gets distracted because maybe a backup is happening and so it's slowing down. Or maybe while checking, the network connection got a little slower because this just happens. They're physical devices. So meanwhile, the second ATM is asking the same question. How much money does David have? $100 is the answer. But because the first ATM hasn't yet sent the message subtract $100, both ATMs have inspected the bank's vault, seeing there's $100 there, and now both machines potentially are going to spit out an answer. Now, this is great for you in some sense if what the bank does ultimately is change the amount to minus 100 by setting the variable equal to your bank account equal to 0, as opposed to doing minus 100. Now in the worst case for the bank-- or in the best for the bank, meanwhile, they give you $200, and your bank account now shows negative $100, which really doesn't benefit you at all. But the point is that this race condition for two roommates getting milk, or for two ATMs trying to get cash and change the state of a vault at the same time exists any time you have a database. Now in problem set seven, this issue arises in the sense that if you buy a share of Facebook stock, and then for instance you buy a second share of Facebook stock, you need to make a decision as the programmer. In order to decide how to update the database, odds are you're going to have one row for that stock, and this is one way to implement it. And you're going to have one share of FB, which is their stock ticker symbol for this username, or this user ID, the unique identifier. But the same story can happen here. If you do a SELECT in SQL, as you'll see in problem set seven when you see, oh, David has one share of Facebook stock. Let me now change this to be two shares, because he wants to buy a second share. But suppose David actually had two browser windows open, or suppose that it's a joint account with two spouses, and both of them are trying to perform the same operation, there, too, the potential exists for a decision to be made based on the previous state of the world-- the account has one share-- and both people, or both servers, now try to say increment it to two shares. But in this case, you might have charged me money for both shares, but incremented just that one time. So in short, the fundamental problem here, as with the joke about leaving a note, or putting a padlock on it, is if two people, or two threads-- think back to scratch-- can inspect the state of some variable and then try to change that variable, but those two things don't happen at the same time but can get interrupted by other things happening, data can get into a very weird state. And you can benefit or you can suffer in the sense of the money example. So in problem set seven, we give you this one line of code, which long story short, solves this problem in MySQL. This very long instruction that doesn't even fit onto one line on the screen here ensures that your operation is what's called atomic. It all happens at once, or it doesn't happen at all. This very long phrase cannot get interrupted partially. And what it does is literally what it says. Insert into some table the following three fields those specific values, but on duplicate key, don't do an insert. Do an update. So this is like doing a SELECT and an INSERT so to speak at the same time. And what is the key that's probably being referred to here? It turns out, and you'll see this in problem set seven's spec, because we've declared there to be a unique key on this particular table such that you can't have multiple rows for the same user with the same penny stock symbol-- in this example here, DVN.V is a silly penny stock that we refer to in the spec. Because we've declared it to be unique, what this means is that if you try to insert a duplicate row, you're instead going to update it without anyone else having a chance to change the state of the world either. So in short, this ensures things are atomic. More generally though, databases like MySQL-- and you don't need this feature for p-set seven, but keep it in mind for the future-- support what are called transactions, where you can say START TRANSACTION literally. You can then execute two SQL statements. And a SQL statement, as you'll see in p-set seven, looks a little something like this. Update a table called account. Set the balance column equal to whatever the balance column currently is minus 1,000 where the number, the account number, like the user ID, equals 2, and then update account dot dot dot. So in layman's terms, what do these two queries seem to be doing in the real world sense of banking? AUDIENCE: Transferring to savings. DAVID MALAN: Exactly. Transferring funds from one account to the other. And this is another example where you really want these two things to happen or not happen. You don't want something to get in the middle of them and potentially mess up the math, or mess up how much money you have, or how much money the bank has. So what's really nice about transactions in MySQL is that, and databases more generally, is that they and smart people who've implemented these features figure out how to make sure that both of those things happen or not at all. And if you are truly aspiring to make a website that's used by people on campus, people in the real world, doing something in the startup sense, these are the kinds of design decisions that become ever so important. Otherwise, you start to lose data, lose users, or in the worst case as we've seen here, potentially lose money. So again, more on that in problem set seven, as well as perhaps for some of you in final projects. So let's change that picture we had a moment ago just in one more way. So let me actually see if I can-- nope, that's gone. There it is. So this is where we left last time. And it turns out we're going to toss one more thing into the mix here-- a language called JavaScript. So JavaScript actually fits into this piece-- and I didn't quite leave enough room, so this is not now to scale. OK, this is really pathetic. OK, so that's JavaScript. All right. I'm really doing it a disservice. All right. So JavaScript is another programming language, and our last, If that helps reassure that there's not much more of the fire hydrants here. So JavaScript is also an interpreted language, which means you don't compile it into zeros and ones. You just run it. But what's fundamentally different with JavaScript usually is that you don't run it on your web server. It doesn't get run in the appliance per se. Rather, it gets downloaded by a user via HTTP into their browser-- Chrome, Safari, Internet Explorer, Firefox, whatever-- and it's the browser that executes this particular programming language. So to be clear, PHP thus far has been executed either at the command line in our black and white window, on a server like the appliance, a computer like the appliance, or it's been executed by a web server running on a computer. But the theme here is that PHP thus far has been executed server-side, so the user and the user's browser never sees a line of PHP code. In fact, if you ever open a browser for your website or another and you actually see PHP code in your window, someone has screwed up. Because it's not meant to be sent to a browser directly. It's supposed to be executed and turned into something like HTML. But JavaScript is essentially the opposite. It's meant to be run typically inside of a user's browser window. And what kinds of websites use JavaScript then these days? Like literally every popular website. Every website that you guys probably use daily use JavaScript for the simplest and even the sexiest features. So something like Facebook Chat if you use that. How does that actually work? Well thus far, all of the stuff we've done with HTML and PHP assumes that you pull up a URL, and you hit Enter, and you see some HTML content. And you click the link, that changes the URL, changes the page, and reloads some new content. Click another URL or submit a form, you get whisked to another page and you see some new content. But using something like Facebook Chat, or Gchat, or Google Maps, rarely does the whole page refresh such that you see a white screen momentarily and then new content. Rather, web pages today are dynamically getting updated again and again and again all sort of behind the scenes. And it turns out that when you do go to something like Facebook, or Gchat, or Gmail, and the page updates automatically without reloading the whole screen, what's happened is that your browser has made sort of secretly additional HTTP requests-- not for whole web pages, but just for little chunks of data, like the instant message that your friend just sent you, or the status update that someone just sent you, or the tweet that someone just sent. It's just making little requests for data, and then using JavaScript, this programming language, to change what the web page looks like without the server helping, without the server generating that HTML. So in short, JavaScript can be used then to not only fetch new data from the server without reloading a whole page or submitting a form. It can also be used to change the so-called DOM-- document object model-- which is just the fancy way for saying the tree of HTML that we saw last time. So to reassure, JavaScript is syntactically so similar to C as well. There's no main function. You just start writing the code and it will get executed, or interpreted more properly. Conditions will look like this. No different from C or PHP for that matter. Boolean expressions or-ed together will look like this. Anded together look like this. Switches will look like this. For loops will look like this. While loops will look like this. Do while loops will look like this. This is new. So JavaScript has not a foreach construct per se, but this construct for variable i in array, and i in this case becomes an index value. So it's a little different from that foreach, though new versions of JavaScript are coming out all the time, so even these language features are evolving. And as an aside, JavaScript these days can also be used on a server just like PHP using a framework called Node.js. One of CS50's TFs, Kevin, has led a seminar on Node.js that's available at cs50.net/seminars. So if you're curious, know that you can use this on the server side as well, but that's a fairly recent trend, but a powerful one at that. This is a little different. This is an array in JavaScript. And what strikes you as different versus C or PHP? There are a few quick stories we can tell here. What's missing versus PHP? AUDIENCE: [INAUDIBLE]. DAVID MALAN: Yes? Sorry, say again? AUDIENCE: Not declaring the type of variable. DAVID MALAN: We're not declaring the type of variable. So actually quite like PHP, we're not specifying the types of this variable. Rather, we're more generically saying var for variable. We don't have PHP's nuisance of the dollar sign, which while tedious to type, does make more clear that something's a variable. Whereas here, we're sort of back to C's approach by just calling a variable by the name we want to give it, like numbers. And also like PHP, we have square brackets for the values inside that array. So variables in JavaScript also might look like this. Notice here this is a string called s, but similarly have we not specified that it's a string. Here though is a feature that doesn't exist in exactly the same way in PHP, but a bit similarly. This is an object in JavaScript. And objects are sort of the Swiss Army Knife of a data structure in that you can use them for any number of things. Here, for instance, we're declaring a variable called quote. The type of that variable is an object. You can think of this as a C struct that has keys and values. Symbol is a key. FB is a value, apparently a stock symbol. Comma. Price is another key, and its value is apparently a floating point, or a number more generally in JavaScript, of $49.26. So PHP doesn't have-- we haven't seen in PHP objects quite like this, but we did see an analog, which was what? AUDIENCE: [INAUDIBLE]. DAVID MALAN: Associative arrays. So whereas PHP has associative arrays whose syntax is ever slightly so different-- we saw the square brackets. We saw the weird arrows symbols. JavaScript has objects, but this is mostly a semantic difference and a different synonym for now. However, as an aside, PHP also has objects in a way that Java and other languages have objects in object-oriented programming. But we'll use these just for data types for now. Objects and associative arrays. This one might make it a little more clear. Here's why an object is useful. When you want to declare a student, like Zamyla, we can actually encapsulate so to speak inside of that object using curly brackets just like before a whole bunch of keys and values in here. We have an ID, a house, and a name for Zamyla, followed by a semicolon as usual at the end. Down here too, this is slightly different, but also very powerful these days. Here's an array, and I know that because there's a square bracket up top and a square bracket at the bottom. And this is an array of what data type apparently in JavaScript? This is an array of it looks like three objects. And I know it's an object only because of the curly braces. And notice there's open curly brace, some stuff, close curly brace, comma, then some more, comma, and then some more. So that's three arguments separated by two commas. So this is an array of three objects. And each of those objects appears to be a student or staff member of some sort, each with an ID, house, and name. But I've called this something called JSON-- JavaScript Object Notation. And this is a data format that actually is so very popular and in vogue these days that if you write an application that uses the Facebook API, the Twitter API, really almost any API out there these days, including some of CS50's own, the data you get back is not in old school CSV format. Because recall that CSV is super simple. It is just columns separated by commas. JSON data gives you more metadata. It associates a key with every value so they don't have to just assume that the zeroth column is one value, column one is another, column two is another. Everything in a JSON object here is sort of self-describing, because every one of names in this file has literally name in front of it as a quoted string. So let's take a look at a couple of examples here. Let me go into the appliance. And let me go into our vhost directory into public. And let me go into the JavaScript directory. And let's go ahead and open up dom-0.html, where DOM just means document object model. It's the tree stuff to which I referred to earlier. And let me propose the following. Here's a web page whose body is pretty simple. So down here at the bottom, notice I have a form. We've seen those before. It has two inputs, one of which has an ID of name, one of which has a type of submit, and the first one's type is text. So this actually sounds pretty simple. Let's go here. Let's go back to this page here. Let's go into localhost, and go into our JavaScript directory, and go to dom-0, and here we have this form. So that's apparently all this page does. It has a name field with a Submit button. But I'm not going to use PHP here. I'm going to do everything client side so to speak in JavaScript as follows. Notice that I've indeed given the name field of this input a unique identifier, which will actually save me some time in a moment. And notice I've introduced another tag in the head of my web page, the tag. So it's in this sense that JavaScript is a client-side programming language. In this case, just like CSS, I've put it straight inside of my HTML. But notice I've declared a function that looks a little like PHP syntactically, but this is actually JavaScript, because again, it's client-side in the browser. And take a guess what this is going to do, even though some of the syntax here is new. AUDIENCE: Say hello to whoever. DAVID MALAN: It's going to say hello to whoever visits this page. So how? So notice, it turns out in JavaScript there's an alert() function. This is a very sort of sad function that really just tends to annoy users. It's not one you should really use typically, but it's a quick and dirty way of sort of printing something to a graphical user interface, like a browser. Notice here that I've got a string in single quotes. It turns out that unlike C, JavaScript can actually have you use single quotes, and frankly it's just kind of the stylistic convention among JavaScript programmers to use single quotes. PHP, they actually have slightly different meaning. But for now, just know that that's the only reason. The convention in JavaScript is often to use single quotes, but we could use double quotes in both places as well. So this is interesting. Recall last time that we had that picture on the screen that drew a tree where you had the HTML node, and the head node, and the body node, and then some text. But there was one special node at the very top that I called the document. Well, it turns out in JavaScript, any time you write a program in JavaScript in a browser, you have access to a special global variable. Similar in spirit to PHP's superglobals, this one is called in all lowercase document. It's like a struct, but this struct also has functions inside of it. So a C struct just has data typically. But a JavaScript object as this technically is also has functions, otherwise known as methods, inside of it. And you can call a function inside of this object quite literally doing its name, dot, and then the name of the function, or again method. It's just a synonym, really. And what does this function do? You can kind of guess from its name. Get element by ID. So this is going to search the web page, search that tree, looking for whatever node, AKA element, has a unique ID of quote unquote name. And then what am I going to do? I'm going to get the value inside of that node in the tree, and I'm going to somehow say hello to that name. So take a guess, even though we've not seen this yet, what do the plus symbols mean here and here probably? AUDIENCE: Concatenate. DAVID MALAN: Concatenate. Right, and these are just sort of design decisions people made years ago. In PHP, you concatenate things with dots. In C, you jump through several hoops and call functions like strcopy() or strcat() or other such functions. But in JavaScript, you use pluses. So this is just concatenating three strings-- hello, a name, and then an exclamation point. So when and why is this function called though? Well, take a guess from the HTML at the bottom. Why is greet() called, or when? Apparently, as best I can tell, on submit, when this form is submitted, I'm going to do whatever is inside of these quotes. And specifically, I'm going to call greet() and then return false. Well, let's see what the net effect here is first. So let me go ahead and type in, say, Loren, Submit. Hello Loren. Let's see if maybe this was just a lucky implementation. Nope. So it's typing out whatever name I actually put there. But notice what's not changing. The URL is still dom-0.html. There's no register.php. There's no second file. There's no action attribute. So what is this return false presumably doing? Why am I calling greet() and then returning false probably? What normally happens when you click Submit on a form that even we have seen in the past week? AUDIENCE: [INAUDIBLE]. DAVID MALAN: It goes somewhere, right? It goes to some destination URL. But I don't want that to happen here. I want my web page to be completely dynamic like Gmail, where once you're there, you stay there. The URL doesn't change in a way that indicates the whole page is reloading. Rather, I just want to change something like printing out something here on the screen. Well let me clean this up a little bit. Let me open up not dom-0, but let me open up dom-2. Just so you've seen some syntax here. It turns out that what we just did is using raw JavaScript. So this is truly the language JavaScript. Some of you might know of a library called jQuery. So jQuery is not the same thing as JavaScript. It's just a library that a really smart guy wrote and popularized such that almost everyone in the world now uses jQuery when using JavaScript. And at first glance, honestly, it looks a little more cryptic. But you'll find, especially if you go there for your final project with web development, you'll find that this cleans things up and saves you quite a few lines of code. So let's just glance at how this form is working. Notice what did I remove apparently from my HTML? There's no on submit handler so to speak. There's no attribute. Because you know, what I didn't really like? I felt like we were falling into old habits there. Just like it was starting to feel sloppy to intermingle both CSS with HTML, because you're kind of throwing different languages all over the place, similarly did this start to feel like a bad road to go down where I'm putting JavaScript code inside of my HTML rather than factoring it out. So that's the lesson here. In dom-2.html, I'm factoring it out. And I'm doing things slightly differently. For now, I'm going to wave my hands at what this really does underneath the hood. But just for now assume that that first line of code in this library called jQuery just means when the document is ready, do the following. Because web pages can take some time to load. You might be on a slow internet connection, and it might be spinning and spinning, and finally it's loaded. That line of code just says wait until the whole page is ready, the document is ready, before executing this code. And now notice, this is probably the most useful first take away from jQuery. This line here is very similar in spirit to this much longer line here. Whereas in raw JavaScript code, there exists a document global object that has a function called getElementById(), the people who wrote jQuery simplified that to just say dollar sign, and then inside of parentheses put two quotes, and then put a hash symbol followed by the unique ID you want to grab. So this is equivalent to document.getElementById. Meanwhile, .submit just means on submission of whatever form you're referring to on the left, go ahead and execute this. But this is now the curiosity too. What's weird about what I've highlighted here? Not only is it kind of syntactically new, there's also something missing. AUDIENCE: It's just called function? It's not called alert? DAVID MALAN: Yeah. Well, so alert() is down here, to be fair. But there is no mention of a name, like you know, foo or something up here. And indeed, this is one of the features of JavaScript that's quite powerful, but also quite new. And PHP actually has this as well. Let me go ahead and do something real quick. Let me go ahead and put this out here. Let me do this. Function. Let's call this handler(). A handler function so to speak. Something that handles some operation. Let me clean up my indentation. And put this here. And put that here. Yep. OK. So now I have a function called handler() that I don't really know what it does yet. It just still has that stuff. Whoops. Took too much. Let's do this. All right. Sorry. All right. Let me do this. OK. That looks nice and straight forward now. Let me do this. Do this. And OK. So now, let's put this over here. No more programming on the fly. OK. So now, let's go back to where the story began. Previously, I said that this line here means when the document is ready, go ahead and do this. What do I want to do? Well specifically, I want to go ahead and do the following. Execute this line of code, and then what I want you to do is call this function when the form is submitted. Now this is what's interesting. This is not itself a function. Notice I am not putting parentheses here in the normal way. I'm literally passing a function called handler() to another function called submit() as an argument as though it's like a variable. And this is one of the features of JavaScript, is functions themselves are really just objects. In fact, they're really just variables of some sort. And if the name of the function is handler(), there is no reason I can't pass it in as an argument here. And this means when the form with the ID of demo is submitted, call this function. But now if I undo all of this, why then did I perhaps do this a moment ago? Well, this is an anonymous function. Because frankly, I realized why am I bothering to waste time declaring a function called handler() only to call it in one and only one place? If I don't need the name, and I don't need to call it more than one place, let's just implement the function right where I need it. And so JavaScript and PHP support what are called anonymous functions that allow me to do exactly that here. But we're just scratching the surface. Let's tease with just a couple final examples here. If I go into quote.php. Notice that this is actually a PHP function, a PHP program, that I wrote that expects an HTTP parameter called symbol, and I can pass in a value like FB. And if we actually look at the source code, this is querying a free website called Yahoo Finance, just like p-set seven, and it's returning to me something in apparently the format known is JSON-- JavaScript Object Notation. It's just an object. Notice the curly braces, the quotes, the colon, and the commas. Now meanwhile, this is pretty cool. Because I can probably use a programming language to generate URLs that look like this dynamically, right? I can change this to Google and get back Google's stock price of $1,017.55. So let's see if we can't use this now. Let me go to ajax-0 here, which looks like the following. It's just a website that has a form with a button. Let me here go ahead and type in YHOO for Yahoo's stock symbol, click Get Quote, and now notice I've gotten an alert with 32.86. Let me actually go to a fancier version of this page, version two, and type in let's say Microsoft, MSFT. Get Quote. And now notice, no alert. Notice where it says price to be determined? There is the simplest of examples that hints at what Gchat, and Facebook Chat, and Gmail, and other such websites are doing by actually changing the web page. Notice this. Let me reload the page. Let me open up Chrome's Inspector. Let me go to the elements tab down here. Now notice if I zoom in down here and open this up, notice that this is my HTML DOM-- my document object model. This is my HTML. But now notice, even though it's going to be a little hard to see it in both places at once, if I type in FB up here, watch the bottom of the screen only. It's actually changing my HTML on the fly. And it's doing this quite simply by doing something like this. If I open up ajax-2, notice implementing something as sexy as that, even though it's pretty ugly, but as sophisticated as that functionally, it has some HTML at the bottom. But notice I used to tag. We've not used this before, but this is like a , but it doesn't force everything onto a new line. It just makes a rectangular region on the same line essentially. Notice that I gave it an ID of price. And it turns out by using the same JavaScript library, I have a function called quote() that's called whenever the form is submitted. And what I'm doing is this. I'm declaring a variable in JavaScript called url, saving the value quote.php?symbol=. In other words, I myself am beginning to prepare an HTTP request, and then I'm concatenating onto that with a plus whatever the element with the ID of symbol is, which notice is that text field right down here. So just like we had forms in the past. And then it turns out in jQuery, if you call .val(), that calls of a val function, a value function, that gets whatever the user has typed in. And then all of the network traffic that happens is this. $.getJSON. And as an aside, dollar sign is just a shorthand notation. It's really jQuery.getJSON. Get me to JSON from this URL, and when the request comes back, call this function and pass in as the argument whatever came back from the server. So in other words, if I go back to the browser, and I go back to quote.php, what my browser is doing is getting this chunk of data. And when I go to this web page here, notice if we instead go to the network tab and clear it, and then type in something like GOOG for Google and Get Quote, notice the page didn't change. But an HTTP request was made, and what came back here if we look at the response is a whole bunch of JSON that we accessed finally with this simple line here. Data is what was gotten from the server. Price is the name of the key I care about. So data.price gives me that. Now meanwhile, and this is the last example. You can do yet more with the page. One actually, well two. We can bring back the tag, if you remember this. That's JavaScript. We can do that. Very exciting. We'll leave that as a cliffhanger. But more excitingly, you can do things like this. If I go to geolocation-1, it turns out that Chrome knows that we are at latitude longitude 42.37 .-71.10. So there's even more there at your disposal. But more on that next week. See you Monday.