1 00:00:00,506 --> 00:00:10,106 [ Silence ] 2 00:00:10,606 --> 00:00:15,496 >> Alright, this is CS50, the start of week 9. 3 00:00:15,496 --> 00:00:18,536 So we've got a great week of stuff in store for you more 4 00:00:18,536 --> 00:00:20,586 on web, more on database, 5 00:00:20,586 --> 00:00:23,116 more on actually looking toward the final project 6 00:00:23,166 --> 00:00:25,196 but first, the blink tag. 7 00:00:25,266 --> 00:00:29,026 So this is a tag in HTML that has been largely deprecated, 8 00:00:29,026 --> 00:00:31,016 which means the world hated it and ripped it 9 00:00:31,016 --> 00:00:32,876 out of more recent versions of HTML. 10 00:00:33,136 --> 00:00:34,946 But this week, well, we teach you by way 11 00:00:34,946 --> 00:00:36,166 of a language called JavaScript 12 00:00:36,166 --> 00:00:38,736 to re-implement this incredibly annoying feature 13 00:00:38,736 --> 00:00:41,016 of websites 1990 style. 14 00:00:41,066 --> 00:00:43,786 But our other teaser for today is this. 15 00:00:43,786 --> 00:00:45,756 So, thanks to our friends at Microsoft, 16 00:00:45,756 --> 00:00:48,756 they have a brilliantly named research and development center 17 00:00:48,756 --> 00:00:50,616 in Kendall Square called NERD 18 00:00:50,726 --> 00:00:52,726 or New England Research and Development. 19 00:00:53,286 --> 00:00:55,436 It's a beautiful space, overlooks the Charles River. 20 00:00:55,436 --> 00:00:57,166 They've got a huge digital screen 21 00:00:57,476 --> 00:01:00,256 and they're gonna have a lot of pizza 22 00:01:00,256 --> 00:01:01,996 and candy waiting for us this Friday. 23 00:01:01,996 --> 00:01:05,406 So the first ever CS50 movie night will be this Friday. 24 00:01:05,406 --> 00:01:08,426 If you would like to RSVP for this and join us, friends 25 00:01:08,426 --> 00:01:10,506 and family and dates and such are welcome. 26 00:01:10,766 --> 00:01:13,016 Just go to cs50.net/movie, 27 00:01:13,016 --> 00:01:15,896 it's where everyone will be this Friday night. 28 00:01:15,896 --> 00:01:19,596 And what we will do is CS50 now operates its own shuttle 29 00:01:19,596 --> 00:01:20,676 services, so thanks 30 00:01:20,676 --> 00:01:23,186 to Shuttleboy shuttle services will be shuttling us 31 00:01:23,186 --> 00:01:25,116 over from Harvard Square to Kendall and back. 32 00:01:25,406 --> 00:01:28,636 Event itself is at 7:30 and the movie that will be 33 00:01:28,636 --> 00:01:32,016 on the screen is this year's course favorite. 34 00:01:32,016 --> 00:01:37,786 So, for those unfamiliar, a little teaser trailer. 35 00:01:38,286 --> 00:01:41,516 [ Pause ] 36 00:01:42,016 --> 00:01:50,000 [ Noise ] 37 00:01:50,016 --> 00:01:50,706 [ Background Noise ] 38 00:01:50,706 --> 00:01:53,216 >> From Mike Judge creator of Beavis and Butt-head 39 00:01:53,216 --> 00:01:56,026 and co-creator of King of the Hill comes a movie 40 00:01:56,026 --> 00:01:57,856 about people who go to work. 41 00:01:58,516 --> 00:02:03,266 [ Noise ] 42 00:02:03,766 --> 00:02:04,866 >> Who are part of a team. 43 00:02:05,166 --> 00:02:07,916 >> And remember next Friday is Hawaiian shirt day. 44 00:02:08,016 --> 00:02:10,836 >> Okay, if it-- I could take the building on fire. 45 00:02:10,836 --> 00:02:12,766 >> Who respect their boss. 46 00:02:13,046 --> 00:02:14,186 >> We need to talk about your flare. 47 00:02:14,466 --> 00:02:16,896 >> Well, I have 15-- 15 pieces on. 48 00:02:17,276 --> 00:02:18,616 >> 15 is the minimum. 49 00:02:18,726 --> 00:02:22,556 Brian for example has 37 pieces of flare out there. 50 00:02:23,016 --> 00:02:23,766 [ Laughter ] 51 00:02:23,766 --> 00:02:24,746 >> And a terrific smile. 52 00:02:25,156 --> 00:02:26,706 >> And need to escape. 53 00:02:26,706 --> 00:02:27,656 >> I don't like my job 54 00:02:27,946 --> 00:02:29,546 and I don't think I'm gonna go any more. 55 00:02:30,536 --> 00:02:33,236 >> One of these days I-- I just kicked this piece of- 56 00:02:34,236 --> 00:02:36,586 >> I'm thinking now it might be more fun to just get fired. 57 00:02:36,806 --> 00:02:40,406 >> And I've always wondered what that would take. 58 00:02:40,406 --> 00:02:41,556 >> Oh here, listen. 59 00:02:42,036 --> 00:02:45,266 >> It looks like you've been missing quite a bit 60 00:02:45,266 --> 00:02:45,596 of work lately. 61 00:02:46,046 --> 00:02:47,646 >> Well, I wouldn't say I've been missing it, Bob. 62 00:02:47,646 --> 00:02:47,836 [ Laughter ] 63 00:02:47,836 --> 00:02:50,996 >> That's just a straight shooter 64 00:02:50,996 --> 00:02:52,476 with upper management written all over him. 65 00:02:52,476 --> 00:02:54,406 >> We're gonna be getting rid of these people here, 66 00:02:54,716 --> 00:02:55,346 Mr. Samir [inaudible]. 67 00:02:56,016 --> 00:02:56,306 [ Inaudible Remark ] 68 00:02:56,306 --> 00:02:58,076 >> Not gonna work here anymore anyway. 69 00:02:59,066 --> 00:03:03,126 >> You haven't even shown up and you get to keep your job. 70 00:03:03,476 --> 00:03:04,406 >> Actually I'm being promoted. 71 00:03:04,596 --> 00:03:05,136 >> Thank you, Bob. 72 00:03:06,476 --> 00:03:08,946 >> This is a-- a suck. 73 00:03:09,226 --> 00:03:10,416 >> They're gonna throw you out on the street 74 00:03:10,666 --> 00:03:12,656 so that Bill Lumbergh stock will go up. 75 00:03:12,656 --> 00:03:14,636 >> Oh, it's completely unfair. 76 00:03:14,896 --> 00:03:16,256 Initech deserves to go down. 77 00:03:16,676 --> 00:03:18,076 We're just the guys to do it. 78 00:03:19,136 --> 00:03:21,416 Tell me about that virus you're always talking about, 79 00:03:21,446 --> 00:03:22,976 the one that could rip off the company for a bunch of money. 80 00:03:23,056 --> 00:03:25,016 >> I'm not going to do anything illegal. 81 00:03:25,646 --> 00:03:26,146 >> Illegal? 82 00:03:26,426 --> 00:03:27,506 Samir, this is America. 83 00:03:28,516 --> 00:03:32,096 [ Music ] 84 00:03:32,596 --> 00:03:33,956 >> The worst they're gonna do is they put you 85 00:03:33,956 --> 00:03:35,856 in a white collar minimum security resort 86 00:03:36,026 --> 00:03:36,836 for a couple of months. 87 00:03:36,836 --> 00:03:38,596 Do you know they have conjugal visits there? 88 00:03:39,136 --> 00:03:40,546 >> I might be showing her my oh face. 89 00:03:40,796 --> 00:03:41,106 Oh, oh-- 90 00:03:41,106 --> 00:03:42,456 >> They let you have sex with women? 91 00:03:42,686 --> 00:03:43,276 >> They sure do. 92 00:03:43,476 --> 00:03:43,916 >> Okay, I'll do it. 93 00:03:44,516 --> 00:03:46,636 [ Background Music ] 94 00:03:47,136 --> 00:03:47,436 >> Office Space. 95 00:03:47,726 --> 00:03:52,076 >> I know how you're getting pretty depressed about your job 96 00:03:52,246 --> 00:03:57,566 and everything and so I just want to tell you, 97 00:03:57,596 --> 00:03:58,496 good things can happen in this world. 98 00:03:58,526 --> 00:03:58,976 I mean look at me. 99 00:03:58,976 --> 00:03:59,043 [ Laughter ] 100 00:03:59,043 --> 00:04:04,000 [ Music ] 101 00:04:05,256 --> 00:04:07,836 >> So coming this Friday to CS50. 102 00:04:07,836 --> 00:04:10,946 So if you think you can go, do RSVP by the website. 103 00:04:10,946 --> 00:04:12,556 Space will be limited but we will follow 104 00:04:12,556 --> 00:04:14,896 up via email once we know the logistics. 105 00:04:15,186 --> 00:04:17,896 So also coming up, our CS50 seminars, 106 00:04:17,896 --> 00:04:19,586 this is a tradition we've had for several years 107 00:04:19,776 --> 00:04:21,686 where the teaching fellows and course assistants 108 00:04:21,686 --> 00:04:24,396 and Harvard affiliates offer some hands on 109 00:04:24,396 --> 00:04:27,746 or conceptual seminars on material bits. 110 00:04:27,746 --> 00:04:29,256 Either just of technical interest to folks 111 00:04:29,256 --> 00:04:32,226 on campus specifically CS50 students or also on topics 112 00:04:32,226 --> 00:04:34,766 that might be of interest to you for final projects 113 00:04:34,766 --> 00:04:36,356 so that you can pick up some new skill 114 00:04:36,626 --> 00:04:38,696 or leverage some new understanding. 115 00:04:38,696 --> 00:04:43,116 This year's line up includes such titles as these, 116 00:04:43,116 --> 00:04:46,076 Blackberry application development or crash course 117 00:04:46,076 --> 00:04:49,106 in Java, creating awesome websites with Ruby on Rails, 118 00:04:49,426 --> 00:04:51,376 which is another programming language and framework . 119 00:04:51,546 --> 00:04:54,706 Developing apps for iPhone, iPod Touch and iPad, 120 00:04:55,156 --> 00:04:56,756 educational software developments 121 00:04:56,756 --> 00:04:59,806 and Linux demystified, if you're still a little mystified. 122 00:05:00,326 --> 00:05:02,616 Making SMS mobile applications, 123 00:05:02,616 --> 00:05:04,746 modern client side web programming, 124 00:05:04,746 --> 00:05:07,686 socializing your apps with the Facebook platform VIM, 125 00:05:07,966 --> 00:05:10,876 and then we have dozens of past seminars 126 00:05:11,116 --> 00:05:13,376 and videos thereof on this website here. 127 00:05:13,376 --> 00:05:17,176 So if you go to cs50.net/seminars, you can one, 128 00:05:17,176 --> 00:05:20,206 see those videos and two, RSVP for this year's lineup. 129 00:05:20,206 --> 00:05:22,036 Essentially all of these seminars are in the process 130 00:05:22,036 --> 00:05:22,966 of being scheduled now. 131 00:05:23,226 --> 00:05:26,006 They'll be like an hour or two some time, ideally between now 132 00:05:26,006 --> 00:05:28,386 and Thanksgiving, and the seminar leader will follow 133 00:05:28,386 --> 00:05:31,746 up with you once you've RSVP'd for it to figure 134 00:05:31,746 --> 00:05:33,876 out what might be an optimal day and time. 135 00:05:34,386 --> 00:05:37,076 And rest assured if you can't make this seminar's day time 136 00:05:37,076 --> 00:05:39,526 this year, it too will be videotaped and put online 137 00:05:39,526 --> 00:05:41,636 within a couple of days thereafter, so plenty of time 138 00:05:41,636 --> 00:05:44,266 to pick up some new skills for the final project. 139 00:05:44,266 --> 00:05:45,926 And just to plant this reminder, 140 00:05:46,186 --> 00:05:49,176 the final project's pre-proposal is due this coming Monday. 141 00:05:49,176 --> 00:05:51,706 This is a very casual but very much expected email 142 00:05:51,706 --> 00:05:53,306 to your teaching fellow just to let him 143 00:05:53,306 --> 00:05:55,386 or her know what you're thinking, to bounce ideas off 144 00:05:55,386 --> 00:05:57,446 of them and to perhaps have a little sanity check 145 00:05:57,446 --> 00:06:00,596 as to whether what you're thinking is too easy, too hard, 146 00:06:00,676 --> 00:06:03,656 too much time, too little time, it's really just an opportunity 147 00:06:03,656 --> 00:06:05,166 to get the juices flowing. 148 00:06:05,166 --> 00:06:07,516 And then in a couple of weeks will the actual proposal be due. 149 00:06:07,826 --> 00:06:11,196 Also coming up from the IOP, if you would like today 150 00:06:11,196 --> 00:06:15,306 in Mather House at 5 p.m., you can met Alec Ross 151 00:06:15,306 --> 00:06:17,656 who is the current senior innovation adviser 152 00:06:17,656 --> 00:06:19,916 to Hillary Clinton where he leads the state department's 153 00:06:19,916 --> 00:06:22,666 efforts to find practical technology solutions for some 154 00:06:22,666 --> 00:06:25,436 of the globe's most vexing problems on healthcare, poverty, 155 00:06:25,436 --> 00:06:27,486 human rights and ethnic conflicts. 156 00:06:27,486 --> 00:06:29,106 So if you're interested in how technology 157 00:06:29,106 --> 00:06:31,736 and social networking tools can be used in diplomacy 158 00:06:31,736 --> 00:06:34,126 and social development, do check out this event 159 00:06:34,226 --> 00:06:36,406 in Mather House this afternoon. 160 00:06:36,406 --> 00:06:38,546 So, my teaching fellows and CA's and some 161 00:06:38,546 --> 00:06:40,756 of your classmates had a little Halloween party yesterday 162 00:06:40,756 --> 00:06:44,176 and I couldn't help but delight in the geekery of the jokes 163 00:06:44,206 --> 00:06:46,146 that get tossed around at such events like this. 164 00:06:46,146 --> 00:06:48,996 So the risk of embarrassing one of them anonymously, 165 00:06:48,996 --> 00:06:51,776 we heard this line here during the preparation of the event 166 00:06:51,996 --> 00:06:53,336 where some balloons were being hung 167 00:06:53,336 --> 00:06:55,736 and some Halloween decorations were being hung. 168 00:06:55,736 --> 00:06:58,126 This volunteer simply asked this here. 169 00:06:59,066 --> 00:07:02,866 And his friend's answer, his or her friend's answer was-- 170 00:07:04,296 --> 00:07:08,406 [laughter] That's sad, we all laugh now 'cause we all get it 171 00:07:08,406 --> 00:07:09,426 for better or for worse. 172 00:07:09,466 --> 00:07:13,116 So, that was a cute thing to see certainly for a teacher. 173 00:07:13,116 --> 00:07:15,176 So, I got this spam actually this morning. 174 00:07:15,406 --> 00:07:16,466 Some of you probably did too. 175 00:07:16,466 --> 00:07:18,146 Hopefully none of you actually clicked the link 176 00:07:18,146 --> 00:07:18,756 that you were given. 177 00:07:19,326 --> 00:07:22,686 This is from Harvard University, it was sent to me, 178 00:07:23,066 --> 00:07:27,196 a dear web mail user and they explained that due to congestion 179 00:07:27,196 --> 00:07:29,796 in all Harvard University exclamation point, 180 00:07:29,796 --> 00:07:32,386 web mail users' accounts, Harvard University, 181 00:07:32,686 --> 00:07:35,216 would be shutting down some unused web mail account. 182 00:07:35,216 --> 00:07:36,696 In order to avoid the deactivation 183 00:07:36,696 --> 00:07:39,966 of your web mail account, you will have to confirm in a-- 184 00:07:40,226 --> 00:07:43,486 confirm that it is a present used account 185 00:07:43,786 --> 00:07:46,376 by clicking the secure link, all caps below. 186 00:07:46,676 --> 00:07:48,406 The personal information requested is 187 00:07:48,406 --> 00:07:50,086 for the safety of your accounts. 188 00:07:50,336 --> 00:07:52,276 Please leave all information requested, 189 00:07:52,276 --> 00:07:53,446 then you can click here and go 190 00:07:53,446 --> 00:07:58,536 to what's clearly harvard.edu/secure/login, 191 00:07:58,806 --> 00:08:00,806 which makes it secure, and this is 192 00:08:00,806 --> 00:08:02,376 of course copyright the president 193 00:08:02,376 --> 00:08:03,736 and the fellows of Harvard College. 194 00:08:03,736 --> 00:08:06,246 So the thing is if you actually clicked through that link, 195 00:08:06,246 --> 00:08:08,686 you actually end up on this to your website. 196 00:08:08,986 --> 00:08:11,626 Too bad I clicked too late because whoever had-- 197 00:08:12,016 --> 00:08:14,716 you signed up for this account has been deactivated. 198 00:08:14,716 --> 00:08:17,086 But we probably would have seen a little web based form 199 00:08:17,086 --> 00:08:18,626 with text fields and a submit button. 200 00:08:18,856 --> 00:08:20,596 One of which probably would have said my user name. 201 00:08:20,846 --> 00:08:23,406 One of which would have said my password and, you know, 202 00:08:23,406 --> 00:08:26,056 we kind of maybe smile now or maybe you're a little worried 203 00:08:26,056 --> 00:08:29,566 that you did fill out a form at 123contactform.com. 204 00:08:29,626 --> 00:08:31,726 But it really is easy to do this. 205 00:08:31,726 --> 00:08:34,436 I mean this is what's generally known as a fishing attack 206 00:08:34,736 --> 00:08:37,676 where the adversary is essentially trying to bait you 207 00:08:37,676 --> 00:08:41,286 into doing something that sounds legitimate technologically 208 00:08:41,286 --> 00:08:44,406 or socially, and it looks like this is a harvard.edu link. 209 00:08:44,406 --> 00:08:46,816 So surely it must actually lead there. 210 00:08:46,996 --> 00:08:49,586 But of course as we've already realized a week ago in looking 211 00:08:49,586 --> 00:08:53,216 at HTML, all it takes to make a link in a web page is 212 00:08:53,216 --> 00:08:57,726 to say A HREF equals quote unquote HTTP slash slash. 213 00:08:57,976 --> 00:09:01,836 And then I could go to 123contacform.com 214 00:09:02,136 --> 00:09:03,126 and then some other stuff. 215 00:09:03,426 --> 00:09:05,716 But then I can close this tag, 216 00:09:05,996 --> 00:09:08,846 but recall that what goes inside this tag is the actual text 217 00:09:08,846 --> 00:09:09,916 that the user sees. 218 00:09:10,156 --> 00:09:12,716 So some websites would just say something like click here, 219 00:09:13,016 --> 00:09:14,996 some websites would say something like form, 220 00:09:15,206 --> 00:09:17,166 but some websites could very well just say 221 00:09:17,166 --> 00:09:23,176 http://harvard.edu/secure/login and voila, 222 00:09:23,176 --> 00:09:24,126 you have this duality. 223 00:09:24,126 --> 00:09:26,576 The link says one thing but actually goes somewhere else. 224 00:09:26,576 --> 00:09:29,236 So if you're not sort of savvy when it comes 225 00:09:29,236 --> 00:09:30,846 to detecting these things now, you know, 226 00:09:30,846 --> 00:09:33,876 most any email clients, you can hover your mouse over a link 227 00:09:33,876 --> 00:09:36,716 like that and actually see where it actually leads. 228 00:09:36,856 --> 00:09:39,326 You can click it but at least after you graduate 229 00:09:39,326 --> 00:09:41,166 from this course, stop short of actually filling 230 00:09:41,166 --> 00:09:42,376 out the form and clicking submit. 231 00:09:42,376 --> 00:09:44,776 At that point, you've indeed gone too far. 232 00:09:44,776 --> 00:09:46,186 But it all boils down to the basics 233 00:09:46,446 --> 00:09:47,876 that we've started looking at today. 234 00:09:47,946 --> 00:09:49,676 So, where are we going with this? 235 00:09:49,676 --> 00:09:51,416 Well, problem set 7, which some of you have dived 236 00:09:51,416 --> 00:09:54,106 into is on CS50 finance. 237 00:09:54,396 --> 00:09:59,146 This is your first of two web based programming challenges 238 00:09:59,146 --> 00:10:01,466 whereby you'll implement an e-trade like website, 239 00:10:01,756 --> 00:10:03,976 whereby thanks to Yahoo Finance, you'll be able 240 00:10:03,976 --> 00:10:05,896 to have users login or register for accounts. 241 00:10:06,286 --> 00:10:09,156 >> They'll be handed some 10,000 virtual dollars 242 00:10:09,356 --> 00:10:11,906 and then you can actually get nearly realtime stock quotes 243 00:10:11,906 --> 00:10:14,216 by typing in the stock symbol for a company. 244 00:10:14,666 --> 00:10:18,516 You can "buy" the stock from your 10,000 dollars in cash 245 00:10:18,726 --> 00:10:20,156 by checking with the current prices 246 00:10:20,156 --> 00:10:21,726 and then buying those numbers of shares. 247 00:10:21,726 --> 00:10:23,276 And then the code you will write 248 00:10:23,276 --> 00:10:25,816 for this problem set will actually keep track of all 249 00:10:25,816 --> 00:10:28,356 of these transactions, all of the buys, all of the sales, 250 00:10:28,356 --> 00:10:29,836 the sell point, the buy point, 251 00:10:29,836 --> 00:10:33,406 the prices at which you actually transacted these changes. 252 00:10:33,406 --> 00:10:37,026 And all of this will be logged in what's called a SQL database 253 00:10:37,026 --> 00:10:39,116 which is what we'll now introduce as a mechanism 254 00:10:39,116 --> 00:10:42,796 for actually storing data around on disk or in memory 255 00:10:42,796 --> 00:10:44,756 so that the next time the user visits this page, 256 00:10:45,016 --> 00:10:48,736 they can actually interact with it seeing their own profile. 257 00:10:48,736 --> 00:10:52,036 So if I go actually to cs50.net/finance, 258 00:10:52,256 --> 00:10:54,326 you'll see the stacks implementation of this. 259 00:10:54,396 --> 00:10:56,066 And if you actually follow the link here 260 00:10:56,066 --> 00:10:58,446 that says play the big board, you'll actually log 261 00:10:58,446 --> 00:11:01,516 in as your self, not as some fake testing account. 262 00:11:01,656 --> 00:11:04,656 And if you do that and then follow up through 263 00:11:04,786 --> 00:11:09,546 to the big board for problem set 7, you'll see that all 264 00:11:09,546 --> 00:11:12,556 of us have lost at least 1 percent of our 10,000 dollars, 265 00:11:12,556 --> 00:11:13,896 those of us who opted in to this here. 266 00:11:14,146 --> 00:11:16,986 So much like P set 6 had its own big board similarly will this 267 00:11:16,986 --> 00:11:18,546 one just for fun have its own big board. 268 00:11:18,846 --> 00:11:20,156 And now that I look at this, 269 00:11:20,246 --> 00:11:23,256 the mathematics are clearly off 'cause Michael Shan [phonetic] 270 00:11:23,256 --> 00:11:27,866 is-- has up to 32,000 dollars but he's only up 2 percent 271 00:11:27,866 --> 00:11:28,656 and he's ranked the last. 272 00:11:28,856 --> 00:11:31,426 So this is an example of a bug at the moment. 273 00:11:33,106 --> 00:11:35,576 In my defense, the markets were closed this weekend 274 00:11:35,576 --> 00:11:36,456 when I was testing. 275 00:11:36,456 --> 00:11:38,026 So I couldn't really get real data 276 00:11:38,026 --> 00:11:39,246 but this is clearly my fault. 277 00:11:39,286 --> 00:11:40,446 So I will fix. 278 00:11:40,446 --> 00:11:44,366 But as it has it, David J. Malan is actually number 1 279 00:11:44,366 --> 00:11:45,156 at the moment, so-- 280 00:11:45,156 --> 00:11:45,223 [ Laughter ] 281 00:11:45,223 --> 00:11:48,526 >> -- maybe I should leave it alone. 282 00:11:48,666 --> 00:11:50,636 So, what's really cool about this is 283 00:11:50,636 --> 00:11:53,206 that this project originated really just as kind 284 00:11:53,206 --> 00:11:56,356 of a random idea where we wanted to do something related 285 00:11:56,416 --> 00:11:58,286 to finance but to do this well, 286 00:11:58,526 --> 00:12:01,056 you really wanna get some kind of real data ideally. 287 00:12:01,056 --> 00:12:02,916 'Cause if we just handed you a big Excel file 288 00:12:02,916 --> 00:12:05,186 and said here are the prices of all these company's stocks 289 00:12:05,556 --> 00:12:08,286 on October 1st, 2010, I mean who cares, right? 290 00:12:08,286 --> 00:12:10,306 You could use that data, much more interesting 291 00:12:10,306 --> 00:12:12,316 to interact with it in realtime. 292 00:12:12,586 --> 00:12:14,816 So if I do a look up for a company 293 00:12:15,016 --> 00:12:18,616 like Google whose symbol is GOOG, what you'll get 294 00:12:18,616 --> 00:12:20,796 on Yahoo Finance really, any of these websites 295 00:12:20,796 --> 00:12:23,026 that give you free stock information are details 296 00:12:23,026 --> 00:12:24,386 like the last trade price, 297 00:12:24,386 --> 00:12:26,696 Google currently goes for 614 dollars. 298 00:12:26,946 --> 00:12:29,326 When the last trade was transacted, what the bid 299 00:12:29,326 --> 00:12:30,456 and asking prices are. 300 00:12:30,636 --> 00:12:32,006 If you're not familiar with some of this jargon, 301 00:12:32,006 --> 00:12:33,996 it's not really a big deal for the P set but we link 302 00:12:33,996 --> 00:12:36,046 to a nice tutorial and the PDF this week 303 00:12:36,046 --> 00:12:37,396 that will bring you up to speed on this. 304 00:12:37,736 --> 00:12:39,446 But what caught our eye is 305 00:12:39,446 --> 00:12:42,296 that there's all these interesting data on the page 306 00:12:42,526 --> 00:12:43,846 and we could resort 307 00:12:43,846 --> 00:12:45,976 to a technique called screen scraping. 308 00:12:45,976 --> 00:12:48,976 Screen scraping or web scrapping is just the buzz word 309 00:12:48,976 --> 00:12:53,116 that describes writing a program usually in a language like PHP 310 00:12:53,116 --> 00:12:55,856 or in Ruby or in Python, 311 00:12:55,856 --> 00:12:57,526 something called a scripting language 312 00:12:57,526 --> 00:12:59,266 which we'll revisit today and onward. 313 00:12:59,856 --> 00:13:03,756 That is whose purpose in life is to pretend to be a browser, 314 00:13:04,016 --> 00:13:07,346 make an HTTP request, and this is just a program you could run 315 00:13:07,346 --> 00:13:08,866 at the command line, on the cloud, 316 00:13:08,866 --> 00:13:10,146 on your own computer, wherever. 317 00:13:10,146 --> 00:13:10,906 It can be written in any 318 00:13:10,906 --> 00:13:12,676 of these new languages we're starting to play with. 319 00:13:13,056 --> 00:13:15,716 It makes HTTP request to yahoo.com 320 00:13:15,976 --> 00:13:18,076 as though it's a browser, and that's not all 321 00:13:18,076 --> 00:13:20,826 that hard 'cause we sniffed my own traffic last week and saw 322 00:13:20,826 --> 00:13:23,626 that when you make an HTTP request, this just sends some 323 00:13:23,626 --> 00:13:27,676 of these HTTP headers, host colon and GET and then dot, dot, 324 00:13:27,676 --> 00:13:30,196 dot and so you can mimic that stuff very easily 325 00:13:30,196 --> 00:13:32,046 with a few print calls in a program. 326 00:13:32,316 --> 00:13:35,606 So we could pretend to be a browser, get this page, 327 00:13:35,756 --> 00:13:39,786 specifically this URL, because notice what's nice here is Yahoo 328 00:13:39,786 --> 00:13:42,116 apparently is using the GET mechanism 329 00:13:42,286 --> 00:13:45,096 which means you can parameterize requests of a web page 330 00:13:45,336 --> 00:13:48,066 by using a HTTP parameter. 331 00:13:48,066 --> 00:13:50,336 In this case, notice that the URL starts 332 00:13:50,336 --> 00:13:53,796 with finance.yahoo.com/q, probably for query, 333 00:13:54,036 --> 00:13:57,036 question mark, and the question mark means here comes some 334 00:13:57,216 --> 00:14:00,636 parameters, here comes some inputs to this server 335 00:14:00,876 --> 00:14:03,636 and the first input is called S, that's a parameter 336 00:14:03,856 --> 00:14:07,086 and its value is apparently equal to GOOG. 337 00:14:07,376 --> 00:14:09,676 So what this means is I could literally copy this, 338 00:14:09,966 --> 00:14:13,956 paste this URL into my own PHP program and write code 339 00:14:13,956 --> 00:14:15,536 that says go get that URL. 340 00:14:15,536 --> 00:14:18,786 And I can say go get that URL every minute or every hour. 341 00:14:19,026 --> 00:14:21,616 I can use something as an aside called the cron job 342 00:14:21,776 --> 00:14:23,626 which actually automates the process 343 00:14:23,626 --> 00:14:25,026 of running your code on a schedule. 344 00:14:25,246 --> 00:14:26,826 So with all these little building blocks, 345 00:14:26,876 --> 00:14:30,726 something like PHP, something like a so called cron job, 346 00:14:30,726 --> 00:14:33,246 I can actually grab this data again and again. 347 00:14:33,606 --> 00:14:37,006 But unfortunately, even though it looks obvious to me, 348 00:14:37,006 --> 00:14:39,666 the human, that the number I probably want the most is this, 349 00:14:39,666 --> 00:14:40,816 the last trade time. 350 00:14:41,016 --> 00:14:43,146 Or you know what, maybe it'd be interesting 351 00:14:43,146 --> 00:14:44,986 to get the current change. 352 00:14:44,986 --> 00:14:46,156 Maybe it'd be interesting 353 00:14:46,156 --> 00:14:48,726 to get the current opening price or the bid part. 354 00:14:48,906 --> 00:14:50,806 In other words, there might be a lot of pieces of data 355 00:14:50,806 --> 00:14:53,056 on the screen and so those of-- 356 00:14:53,056 --> 00:14:54,466 those people in this world 357 00:14:54,466 --> 00:14:56,226 without a computer science background 358 00:14:56,226 --> 00:14:59,146 or any programming jobs probably would open up Excel 359 00:14:59,146 --> 00:15:01,536 or Google spreadsheet and then just start transcribing these 360 00:15:01,536 --> 00:15:03,276 numbers manually, right, copy and paste. 361 00:15:03,276 --> 00:15:04,846 And that's about as efficient as you could get. 362 00:15:05,336 --> 00:15:09,476 But remember that underneath the hood here is some HTML. 363 00:15:09,626 --> 00:15:12,716 So if I actually go and view the source of this page, 364 00:15:13,196 --> 00:15:14,996 let's do it this way, view source, 365 00:15:15,226 --> 00:15:16,706 I'll see all of these HTML. 366 00:15:16,706 --> 00:15:21,286 But my God, now finding those little needles in this mess 367 00:15:21,286 --> 00:15:23,426 of a haystack is really quite challenging. 368 00:15:23,616 --> 00:15:26,736 Even though the 600 dollars is in there, this just looks 369 00:15:26,736 --> 00:15:29,236 like a mess, and this is what would come back 370 00:15:29,236 --> 00:15:30,326 if I wrote a program 371 00:15:30,526 --> 00:15:33,406 that requested a URL pretending it's a web page. 372 00:15:33,626 --> 00:15:36,546 Browsers of course know how to render this nice and prettily 373 00:15:36,546 --> 00:15:37,886 like this in a web page. 374 00:15:38,026 --> 00:15:40,866 But if I'm writing a command line program with PHP, 375 00:15:40,906 --> 00:15:43,456 now I have to pars or analyze all of this code, 376 00:15:43,456 --> 00:15:44,836 and this is where screen scraping, 377 00:15:45,116 --> 00:15:48,766 the process of writing a program that just crosses its fingers 378 00:15:48,766 --> 00:15:51,696 that that web page structurally is gonna stay the same day 379 00:15:51,696 --> 00:15:53,406 after day so you can just grab data 380 00:15:53,406 --> 00:15:55,356 from it is actually nontrivial. 381 00:15:55,396 --> 00:15:57,636 We as a course actually do this every night 382 00:15:57,846 --> 00:16:00,256 with Harbor Dining Services website to grab all 383 00:16:00,256 --> 00:16:02,526 of the meal data everyday so that you guys 384 00:16:02,526 --> 00:16:04,676 for your final projects can use that kind of information. 385 00:16:04,676 --> 00:16:07,166 But long story short, it's not fun, generally, 386 00:16:07,166 --> 00:16:08,686 though sometimes you have to resort to it, 387 00:16:08,916 --> 00:16:11,366 but what caught our eye is at the bottom of this page 388 00:16:11,996 --> 00:16:14,926 under this thing they called toolbox is download data. 389 00:16:14,926 --> 00:16:16,936 And in fact when I hover over this, 390 00:16:17,186 --> 00:16:18,546 I see that this is just a URL. 391 00:16:18,546 --> 00:16:20,836 It's gonna look a little small here but I can see 392 00:16:20,836 --> 00:16:24,626 that this download data link is just another URL, a get request 393 00:16:24,626 --> 00:16:28,156 where S equals GOOG and then F equals a long string 394 00:16:28,156 --> 00:16:29,056 and then CSV. 395 00:16:29,056 --> 00:16:31,986 CSV is comma-separated values and it's sort 396 00:16:31,986 --> 00:16:33,716 of a poor man's Excel file. 397 00:16:33,716 --> 00:16:37,146 It's a spreadsheet but it just uses commas to separate columns. 398 00:16:37,386 --> 00:16:41,176 And so if you have a program like Microsoft Excel that knows 399 00:16:41,176 --> 00:16:43,106 to look for commas as delimiters 400 00:16:43,106 --> 00:16:45,116 between what conceptually should be commas, 401 00:16:45,346 --> 00:16:47,786 you can then open this file in something like Excel. 402 00:16:47,786 --> 00:16:49,766 So I'm gonna go ahead and click download data. 403 00:16:50,056 --> 00:16:52,856 It indeed says I'm downloading a file called quotes.csv, 404 00:16:52,856 --> 00:16:55,186 so let me go ahead and save that. 405 00:16:55,186 --> 00:16:58,256 And then if I double click this file, because I have Excel 406 00:16:58,256 --> 00:17:00,646 on this particular computer, it's Excel that opens. 407 00:17:00,646 --> 00:17:03,376 And what's really neat is that I have the illusion 408 00:17:03,376 --> 00:17:06,076 of some columns here, GOOG in the left column. 409 00:17:06,076 --> 00:17:08,856 Then what appears to be its last trade price, what appears 410 00:17:08,856 --> 00:17:11,596 to be the date at which it was last traded today, 411 00:17:11,596 --> 00:17:13,506 the time at which it was last traded today. 412 00:17:13,806 --> 00:17:16,206 There are of course slight delay is in a lot of these websites 413 00:17:16,206 --> 00:17:17,686 which is why it's trailing by a few minutes, 414 00:17:17,896 --> 00:17:20,196 and then some other data that if I compare back and forth 415 00:17:20,196 --> 00:17:22,086 with the website, I could figure out which 416 00:17:22,086 --> 00:17:23,176 of these fields means what. 417 00:17:23,416 --> 00:17:25,246 But if I actually look at the text file 418 00:17:25,246 --> 00:17:29,476 that I just downloaded, this is just a file called quotes.csv. 419 00:17:29,476 --> 00:17:33,396 If I actually open this with something like text edit, 420 00:17:33,396 --> 00:17:37,576 this simple little text program, notice that's all in this-- 421 00:17:37,666 --> 00:17:41,196 all that's in this file is that data there separated by commas. 422 00:17:41,196 --> 00:17:44,486 And now, as a programmer, this is really interesting to me 423 00:17:44,486 --> 00:17:47,416 because now I don't have all this [inaudible] of HTML 424 00:17:47,416 --> 00:17:49,616 and hyperlinks and colors and fonts, 425 00:17:49,616 --> 00:17:51,306 all these useless information. 426 00:17:51,576 --> 00:17:53,136 All I have now is the raw data. 427 00:17:53,136 --> 00:17:55,626 So this caught our eye, and so what you'll do in problem, 428 00:17:55,626 --> 00:17:59,956 set 7 for instance, is write code that calls a function 429 00:17:59,956 --> 00:18:01,956 that we wrote that grabs this URL 430 00:18:02,366 --> 00:18:04,806 that has a stock symbol in it. 431 00:18:04,806 --> 00:18:06,986 Whatever stock symbol you wanna pass in as an argument 432 00:18:06,986 --> 00:18:09,486 to this function, we make the request to the web page, 433 00:18:09,726 --> 00:18:11,826 get back what essentially is an Excel file. 434 00:18:11,946 --> 00:18:15,606 A CSV file, we then split it on all these commas 435 00:18:15,826 --> 00:18:19,256 and then hand you back a struct essentially called a class 436 00:18:19,286 --> 00:18:22,226 in PHP that contains all of these interesting information. 437 00:18:22,486 --> 00:18:25,066 Now, not to dwell too much on Yahoo Finance, but moving ahead, 438 00:18:25,066 --> 00:18:28,946 whether it's for your research in the physical sciences 439 00:18:28,946 --> 00:18:31,786 or biological science or economics or really any field 440 00:18:31,906 --> 00:18:34,056 where you might actually wanna analyze data 441 00:18:34,056 --> 00:18:36,166 or manipulate something or do something more efficiently, 442 00:18:36,166 --> 00:18:38,396 then you, the human could do by a copy and paste, 443 00:18:38,736 --> 00:18:41,246 looking on the web or looking on computers 444 00:18:41,246 --> 00:18:44,536 for actually machine readable data like this is 445 00:18:44,536 --> 00:18:45,976 where things get really interesting 446 00:18:45,976 --> 00:18:48,086 because it means you can automate so much. 447 00:18:48,086 --> 00:18:50,476 And the simplest thing we automated last week, recall, 448 00:18:50,656 --> 00:18:53,656 was simply automating the idea of freshmen intramurals. 449 00:18:53,936 --> 00:18:56,196 And what we were able to do last week is 450 00:18:56,246 --> 00:18:59,366 when the user submits a form saying this is my name, 451 00:18:59,366 --> 00:19:02,016 this is my dorm, my gender, I'm gonna be a captain or not, 452 00:19:02,376 --> 00:19:05,616 we were able to first completely throw that information away, 453 00:19:05,816 --> 00:19:07,556 which clearly was not all that useful. 454 00:19:07,556 --> 00:19:09,546 We just said, you're registered but not really. 455 00:19:09,776 --> 00:19:13,176 But in the third version of last week's Frosh IMs example, 456 00:19:13,176 --> 00:19:16,336 what did I finally do with that data. 457 00:19:16,516 --> 00:19:19,336 Yeah, so I sent myself an email, and back in the day, 458 00:19:19,336 --> 00:19:21,926 this would have been an email not to me but to the proctor 459 00:19:21,926 --> 00:19:23,796 who was actually running the freshmen intramurals 460 00:19:23,796 --> 00:19:24,586 sports program. 461 00:19:24,786 --> 00:19:28,606 And if I take a look at that code, what you'll see here is 462 00:19:28,606 --> 00:19:31,626 that this was register3.php. 463 00:19:31,626 --> 00:19:34,896 Recall that at the very tail end of that last lecture, 464 00:19:35,186 --> 00:19:37,686 sending an email on a computer program reduced 465 00:19:37,686 --> 00:19:39,246 to just a few lines of code. 466 00:19:39,416 --> 00:19:42,516 I had a few variables and recall that in PHP, a variable starts 467 00:19:42,516 --> 00:19:44,116 with a dollar sign just by convention, 468 00:19:44,396 --> 00:19:46,536 so I declared a variable called two and just put 469 00:19:46,536 --> 00:19:47,706 in my own email address. 470 00:19:47,706 --> 00:19:50,706 And notice the similarities with C, double quotes around strings, 471 00:19:51,026 --> 00:19:54,616 although as an aside in PHP, you can often use single quotes 472 00:19:54,696 --> 00:19:57,536 as well, semicolon at the end, so that's the same. 473 00:19:57,876 --> 00:20:00,656 Subject equals registration, body equals-- 474 00:20:00,656 --> 00:20:02,906 and this one got a little interesting 'cause I didn't 475 00:20:02,906 --> 00:20:03,976 wanna send like a short phrase. 476 00:20:04,056 --> 00:20:07,016 >> I want kind of a longer sentence and so I wrote 477 00:20:07,016 --> 00:20:11,626 out body equals this person just registered colon backslash n 478 00:20:11,626 --> 00:20:14,186 backslash n 'cause I wanna move the cursor down a couple 479 00:20:14,186 --> 00:20:14,906 of lines in the email. 480 00:20:14,906 --> 00:20:17,046 And then notice this, the period. 481 00:20:17,136 --> 00:20:20,686 So the period or the dot is the concatenation operator in PHP. 482 00:20:20,916 --> 00:20:23,556 So whereas in C, it's really actually a pain 483 00:20:23,736 --> 00:20:26,246 to take one string and add more string to it 484 00:20:26,246 --> 00:20:27,546 and more string and more string. 485 00:20:27,736 --> 00:20:30,126 Because remember that a string in C is an array. 486 00:20:30,126 --> 00:20:32,236 An array usually has a fixed amount of memory 487 00:20:32,396 --> 00:20:34,966 so you can't just blindly add more and more characters 488 00:20:35,006 --> 00:20:37,586 to the end of it, but in PHP, you can. 489 00:20:37,646 --> 00:20:39,876 Underneath the hood, the same kind 490 00:20:39,876 --> 00:20:41,056 of magic is still happening. 491 00:20:41,056 --> 00:20:42,936 The same kind of memory is getting allocated 492 00:20:42,936 --> 00:20:44,816 and deallocated as needed but all 493 00:20:44,816 --> 00:20:46,446 of that is taken care of for you. 494 00:20:46,676 --> 00:20:50,506 And so notice what I concatenate on to that phrase is this. 495 00:20:51,006 --> 00:20:54,276 Dollar sign underscore post bracket quote unquote name. 496 00:20:54,576 --> 00:20:57,546 So what was this thing called dollar sign underscore post, 497 00:20:58,066 --> 00:20:58,876 generally speaking? 498 00:20:59,426 --> 00:21:04,276 What was the point of this thing? 499 00:21:04,496 --> 00:21:05,126 Awkward silence. 500 00:21:06,216 --> 00:21:06,986 Someone must know. 501 00:21:07,706 --> 00:21:09,816 Just conceptually like what's-- what is this thing? 502 00:21:10,386 --> 00:21:10,946 >> It's an array. 503 00:21:11,046 --> 00:21:11,566 >> So it's an array. 504 00:21:11,916 --> 00:21:13,766 So it's an array and you can infer that frankly 505 00:21:13,766 --> 00:21:15,026 from the square brackets. 506 00:21:15,026 --> 00:21:18,326 The notation is just like C. We don't have a number inside 507 00:21:18,326 --> 00:21:20,996 of those square brackets but this is because we get a new 508 00:21:20,996 --> 00:21:24,486 and improved version in array called an associate of array 509 00:21:24,616 --> 00:21:27,556 in PHP, whereby the indices, the things that you use to index 510 00:21:27,556 --> 00:21:30,026 into the array no longer have to be numbers. 511 00:21:30,026 --> 00:21:32,816 They can actually be words or phrases, sentences 512 00:21:32,946 --> 00:21:35,716 or more generally, things called keys. 513 00:21:35,966 --> 00:21:41,076 And so what I can now do is grab the value inside of this array 514 00:21:41,076 --> 00:21:43,376 at the location called name. 515 00:21:43,586 --> 00:21:43,726 Yeah. 516 00:21:44,516 --> 00:21:49,276 [ Inaudible Remark ] 517 00:21:49,776 --> 00:21:50,726 >> Good question. 518 00:21:50,726 --> 00:21:53,296 What if you use the same syntax and I say, 519 00:21:53,296 --> 00:21:54,676 you know what I actually want to include 520 00:21:54,676 --> 00:21:57,196 in this email even though I'm completely making this up, 521 00:21:57,196 --> 00:22:01,166 I wanna say the value of the foo key, F-O-O. 522 00:22:01,336 --> 00:22:03,716 Well, what would come back is essentially the "empty string", 523 00:22:03,716 --> 00:22:05,406 nothing would actually happen. 524 00:22:06,896 --> 00:22:08,346 Alright, so maybe that's okay 525 00:22:08,346 --> 00:22:10,076 if it wasn't actually a required field 526 00:22:10,196 --> 00:22:12,256 but in this case I know what these fields were called. 527 00:22:12,416 --> 00:22:15,576 Now what's special about dollar sign underscore post is that, 528 00:22:15,576 --> 00:22:16,356 yes, it's an array. 529 00:22:16,356 --> 00:22:17,826 Yes, it's an associate of array 530 00:22:18,046 --> 00:22:20,596 but it's generally what PHP calls a super global. 531 00:22:20,596 --> 00:22:23,346 It's a special global variable that you just get handed 532 00:22:23,346 --> 00:22:26,716 for free anytime you write a PHP based website 533 00:22:27,086 --> 00:22:30,466 that is automatically filled with any parameters 534 00:22:30,466 --> 00:22:33,996 that were submitted by some user via form submissions. 535 00:22:34,076 --> 00:22:36,136 So remember we had the whole premise here was 536 00:22:36,136 --> 00:22:38,906 that we made a form, open bracket form in HTML. 537 00:22:39,186 --> 00:22:41,826 Recall that we specified method equals something rather, 538 00:22:41,826 --> 00:22:43,586 so let me actually pull that up. 539 00:22:43,896 --> 00:22:46,636 Froshims3.php, recall that we introduced this notion 540 00:22:46,636 --> 00:22:50,526 of a form last week, and this is fairly self explanatory once you 541 00:22:50,526 --> 00:22:52,976 start-- once you get the hang of the tags, 542 00:22:53,286 --> 00:22:59,036 up at the top here we have form action equals register3.php. 543 00:22:59,036 --> 00:23:01,396 So action just says, what is the action of this form? 544 00:23:01,396 --> 00:23:03,136 Where does it send its data to? 545 00:23:03,136 --> 00:23:04,716 Where does the data get submitted? 546 00:23:04,906 --> 00:23:06,556 And I decided that in addition 547 00:23:06,556 --> 00:23:09,126 to this file called froshims3.php, 548 00:23:09,126 --> 00:23:12,016 I'm gonna write a file called register3.php. 549 00:23:12,016 --> 00:23:14,976 The purpose in life is to receive the form submission 550 00:23:15,056 --> 00:23:16,466 from this particular page. 551 00:23:16,656 --> 00:23:18,696 Alright, the method I'm gonna use is POST 552 00:23:18,866 --> 00:23:20,856 and we quickly mentioned this last week, 553 00:23:21,076 --> 00:23:22,606 there's two main methods. 554 00:23:22,606 --> 00:23:24,096 One is POST and one is GET. 555 00:23:24,196 --> 00:23:25,886 And what's perhaps the most obvious difference 556 00:23:25,886 --> 00:23:29,696 between the two? 557 00:23:29,696 --> 00:23:29,926 [ Inaudible Remark ] 558 00:23:29,926 --> 00:23:32,786 >> Yeah, so using method equals "GET" means 559 00:23:32,786 --> 00:23:34,796 that the parameter show up in the URL. 560 00:23:35,056 --> 00:23:38,106 So in the case of Yahoo Finance, when I filled out that form 561 00:23:38,106 --> 00:23:40,986 in the top left corner and type GOOG and hit enter, 562 00:23:41,196 --> 00:23:43,316 notice that-- recall that the URL changed 563 00:23:43,506 --> 00:23:46,146 and you could actually see what I typed in the URL, 564 00:23:46,146 --> 00:23:47,876 and so that's because underneath the hood, 565 00:23:47,876 --> 00:23:49,816 Yahoo must be using the GET method. 566 00:23:50,126 --> 00:23:52,206 Now why is that a good thing perhaps? 567 00:23:53,796 --> 00:23:54,406 Why use GET? 568 00:23:54,406 --> 00:23:54,576 Yeah. 569 00:23:55,646 --> 00:23:57,136 >> Bookmark it. 570 00:23:57,136 --> 00:23:58,356 >> Yeah, so you can bookmark it, right? 571 00:23:58,356 --> 00:24:01,396 If you wanna add a bookmark to your browser, if you wanna copy 572 00:24:01,396 --> 00:24:02,556 and paste it into an email, 573 00:24:02,906 --> 00:24:05,146 what's nice about the GET method is that state, 574 00:24:05,236 --> 00:24:06,336 the state of the world 575 00:24:06,336 --> 00:24:09,266 as you currently see it is embedded inside of the URL 576 00:24:09,266 --> 00:24:10,616 so the state is retained. 577 00:24:10,616 --> 00:24:11,866 Someone else can follow that link 578 00:24:12,016 --> 00:24:13,846 and see exactly the same thing as you. 579 00:24:14,036 --> 00:24:16,226 Now this is probably not the best method if you're trying 580 00:24:16,226 --> 00:24:17,486 to log into some account. 581 00:24:17,836 --> 00:24:20,096 You fill out a form with your user name and password 582 00:24:20,096 --> 00:24:22,436 or maybe your credit card number and your 3 583 00:24:22,436 --> 00:24:25,546 or 4 digit secret code on the back of it and then hit submit. 584 00:24:25,846 --> 00:24:28,966 Well, it's probably not a huge deal if you're sitting at home 585 00:24:29,186 --> 00:24:31,456 or in your dorm and the form is getting submitted 586 00:24:31,456 --> 00:24:33,366 from your own laptop to some server. 587 00:24:33,516 --> 00:24:34,966 But if you're on a public machine 588 00:24:34,966 --> 00:24:38,026 or if other roommates are in the habit of using your computer, 589 00:24:38,256 --> 00:24:41,066 anytime the URL changes that's in your browser, 590 00:24:41,186 --> 00:24:43,286 what's a side effect of using GET? 591 00:24:43,416 --> 00:24:44,996 What's that? 592 00:24:45,136 --> 00:24:49,916 >> Password shows up as a plain text. 593 00:24:49,916 --> 00:24:51,886 >> Yeah, so the password is gonna show up as plain text 594 00:24:51,966 --> 00:24:53,926 in the URL, or more specifically, 595 00:24:54,136 --> 00:24:56,226 your history is going to remember 596 00:24:56,226 --> 00:24:57,486 that you visited that URL. 597 00:24:57,946 --> 00:25:00,566 So if you've ever gotten a little nosy and crossed that, 598 00:25:00,566 --> 00:25:01,826 let's call it unethical line, 599 00:25:02,026 --> 00:25:04,146 and poked around at what URL is your friends 600 00:25:04,146 --> 00:25:05,856 or roommates have actually been visiting, 601 00:25:05,856 --> 00:25:07,396 it's got to be a few of you here, right? 602 00:25:07,396 --> 00:25:09,406 So that's the so called history of a browser, 603 00:25:09,526 --> 00:25:12,586 and that pretty much records pretty much every GET request 604 00:25:12,586 --> 00:25:13,866 that was made with the browser, 605 00:25:14,116 --> 00:25:15,826 it's just logged in that drop-down. 606 00:25:15,856 --> 00:25:18,706 And of course you can go to like tools and options and clear 607 00:25:18,706 --> 00:25:22,476 that kind of cache, but GET is not very good for privacy sake. 608 00:25:22,506 --> 00:25:25,506 POST is generally better for that and POST is actually called 609 00:25:25,506 --> 00:25:28,346 for anytime you wanna have the user upload something 610 00:25:28,346 --> 00:25:29,686 like a JPEG to Facebook, 611 00:25:29,926 --> 00:25:33,526 you can't really fit an image conceptually or even technically 612 00:25:33,716 --> 00:25:37,156 in a URL, you can change it to zeros and ones or some kind 613 00:25:37,256 --> 00:25:40,326 of encoding but it doesn't really fit very well in the URL. 614 00:25:40,326 --> 00:25:42,826 So, POST is also used when you wanna submit large amounts 615 00:25:42,826 --> 00:25:43,556 of information. 616 00:25:43,866 --> 00:25:46,106 But the relevance to the Frosh IMs example is 617 00:25:46,106 --> 00:25:48,726 that inside this form, there's an input called name. 618 00:25:48,996 --> 00:25:50,446 There's an input called captain. 619 00:25:50,506 --> 00:25:53,346 There's an input called gender and each of this happens to be 620 00:25:53,346 --> 00:25:54,656 of slightly different types. 621 00:25:54,736 --> 00:25:56,576 I know this by just having read the manual 622 00:25:56,576 --> 00:25:59,846 or having learned how HTML works and so I know that in input, 623 00:26:00,056 --> 00:26:02,976 its type can be text if you want a text field. 624 00:26:02,976 --> 00:26:04,796 It can be check box if you want a check box. 625 00:26:05,116 --> 00:26:06,646 Radio, if you want a radio button, 626 00:26:06,826 --> 00:26:07,876 and there're a few others. 627 00:26:07,876 --> 00:26:09,746 But pretty much it's straightforward 628 00:26:09,746 --> 00:26:12,286 as just saying what piece of-- or what type of data you want. 629 00:26:12,826 --> 00:26:17,226 But because the action of this form was register3.php, 630 00:26:17,226 --> 00:26:20,896 what happens when I actually click submit is that this page, 631 00:26:20,946 --> 00:26:23,866 register3.php, which lives at a URL. 632 00:26:24,186 --> 00:26:28,046 If I go to this in a browser, I can absolutely visit this. 633 00:26:28,046 --> 00:26:31,616 I can go to froshim3.php which, recall, looked like this. 634 00:26:31,986 --> 00:26:36,876 I can also go directly to register3.php but notice that-- 635 00:26:37,596 --> 00:26:39,486 let me disable this for a moment. 636 00:26:40,316 --> 00:26:41,996 I'm gonna do one quick thing here. 637 00:26:41,996 --> 00:26:45,176 Print, yes, here exit. 638 00:26:45,436 --> 00:26:48,576 Just to prove that this file called register3.php can 639 00:26:48,736 --> 00:26:51,476 in fact be visited directly, I click here, 640 00:26:51,766 --> 00:26:54,426 and indeed this is now just a web page on the internet. 641 00:26:54,426 --> 00:26:57,566 It's not actually returning legit HTML yet, but the URL is 642 00:26:57,566 --> 00:26:59,336 in fact web accessible. 643 00:26:59,556 --> 00:27:02,006 So, I'm not actually submitting any parameters 644 00:27:02,006 --> 00:27:03,886 to this form right now but if I get rid of this, 645 00:27:04,316 --> 00:27:08,316 and actually access register 3 by going to froshims3 646 00:27:08,316 --> 00:27:12,716 and saying, I am David, I'll be a captain and Mathews register, 647 00:27:13,156 --> 00:27:15,186 now it claims you are registered really. 648 00:27:15,376 --> 00:27:17,806 Notice I'm again at register3.php, 649 00:27:17,916 --> 00:27:20,206 so that begs the question, what happened this time? 650 00:27:20,386 --> 00:27:22,936 Well, if we look at this code, notice at the very top 651 00:27:22,936 --> 00:27:27,436 of the file, register3.php, notice the very first character, 652 00:27:27,436 --> 00:27:28,876 open bracket question mark. 653 00:27:28,876 --> 00:27:30,656 This says here comes some PHP code. 654 00:27:30,946 --> 00:27:33,086 Then the rest of the stuff for a little while is just comments, 655 00:27:33,086 --> 00:27:34,766 so uninteresting for our purposes now. 656 00:27:35,006 --> 00:27:37,586 But down here, we actually see some logic 657 00:27:37,966 --> 00:27:39,756 and then we see close bracket-- 658 00:27:39,756 --> 00:27:41,996 close question mark close bracket 659 00:27:42,216 --> 00:27:43,806 which means end of PHP mode. 660 00:27:43,806 --> 00:27:45,446 So what is this PHP code doing? 661 00:27:45,796 --> 00:27:49,096 Well, it is this code that sort of magically, 662 00:27:49,166 --> 00:27:51,306 thanks to its being accessed by the web, 663 00:27:51,306 --> 00:27:54,976 has access to a superglobal associative array, 664 00:27:55,316 --> 00:27:58,216 inside of which are all those key value pairs from the form 665 00:27:58,216 --> 00:27:59,386 that I myself created. 666 00:27:59,576 --> 00:28:01,936 So if I had made a much longer form with ten fields, 667 00:28:02,176 --> 00:28:05,976 this associative array would have ten different keys inside 668 00:28:05,976 --> 00:28:07,716 of it handed to me with the users input. 669 00:28:08,046 --> 00:28:09,356 So I first do a sanity check. 670 00:28:09,466 --> 00:28:14,956 If the name key in this ray, it is not equal to quote unquote, 671 00:28:15,366 --> 00:28:19,086 and the gender keys value is not equal to quote unquote 672 00:28:19,086 --> 00:28:23,016 and the dorm keys value is not equal to quote unquote, 673 00:28:23,096 --> 00:28:26,906 what's the implication sort of just in layman's terms? 674 00:28:26,906 --> 00:28:27,856 [ Inaudible Remark ] 675 00:28:27,856 --> 00:28:29,406 >> They build out the form, right? 676 00:28:29,406 --> 00:28:33,386 They must-- because those values are not the empty string 677 00:28:33,386 --> 00:28:34,616 because they're not blanks, 678 00:28:34,676 --> 00:28:36,566 obviously the user typed something in 679 00:28:36,736 --> 00:28:37,676 and so they're not blank, 680 00:28:37,676 --> 00:28:39,346 and so now I wanna do something with that. 681 00:28:39,346 --> 00:28:41,896 I'm going to assume without doing much error checking 682 00:28:41,896 --> 00:28:43,136 in this version, but you know what, 683 00:28:43,136 --> 00:28:44,416 this person just registered. 684 00:28:44,416 --> 00:28:46,986 So I'm gonna compose this email to the proctor 685 00:28:46,986 --> 00:28:48,196 or to myself in this case. 686 00:28:48,476 --> 00:28:50,896 I'm gonna-- I read the manual to figure out that 687 00:28:50,896 --> 00:28:53,516 if I wanna send it from myself, I can just say from: 688 00:28:53,516 --> 00:28:57,366 malan@cs50.net and then the stupid convention here backslash 689 00:28:57,366 --> 00:28:59,896 r backslash n, you might recall that, but that was just 690 00:28:59,896 --> 00:29:00,866 from the documentation. 691 00:29:01,156 --> 00:29:03,486 But the real magic is just in this one line. 692 00:29:03,566 --> 00:29:06,176 It turns out that there is a function built into PHP, 693 00:29:06,176 --> 00:29:09,176 definitely doesn't exist in C, that is called mail, 694 00:29:09,416 --> 00:29:12,826 it takes 4 arguments, in this case, the two argument, 695 00:29:12,856 --> 00:29:15,416 the subject, the body and then those things called headers, 696 00:29:15,416 --> 00:29:16,966 the additional metadata at the top. 697 00:29:17,166 --> 00:29:19,356 And the end result, recall, was that I was able 698 00:29:19,356 --> 00:29:21,126 to send an email to myself. 699 00:29:21,366 --> 00:29:23,816 And if I actually go check my mail now here 700 00:29:24,646 --> 00:29:27,686 in this Gmail interface, this is what the proctor would see. 701 00:29:27,966 --> 00:29:32,016 But here is the sort of tidbit that's worth mentioning perhaps 702 00:29:32,016 --> 00:29:33,466 for security and privacy sake. 703 00:29:33,726 --> 00:29:35,986 If I actually view the details of this, indeed, 704 00:29:36,226 --> 00:29:39,686 it looks like I've sent an email from myself to myself. 705 00:29:40,156 --> 00:29:44,136 But it looks like with this programming power, I can say, 706 00:29:44,136 --> 00:29:46,736 you know what, I don't want these emails coming from me. 707 00:29:46,736 --> 00:29:51,896 I want them coming from Cansu, aydede@fas.harvard.edu. 708 00:29:52,546 --> 00:29:55,116 Save that, Cansu is not here today. 709 00:29:55,636 --> 00:29:57,716 So, now I'm gonna go back to my inbox. 710 00:29:57,926 --> 00:29:59,036 I'm gonna go back to the form. 711 00:29:59,036 --> 00:30:02,296 I'm gonna reregister as, let's say, Yuhki this time, 712 00:30:02,706 --> 00:30:03,976 also for Mathews, register. 713 00:30:04,936 --> 00:30:05,756 >> Says I'm registered. 714 00:30:05,756 --> 00:30:08,266 Let's go to CS50 mail, reload the page. 715 00:30:08,426 --> 00:30:09,656 Oh, Cansu emailed me. 716 00:30:10,036 --> 00:30:13,936 And indeed I have an email now from aydede@fas.harvard.edu. 717 00:30:14,256 --> 00:30:15,896 So, don't even get us started 718 00:30:15,896 --> 00:30:17,686 on the insecurity of email, frankly. 719 00:30:17,686 --> 00:30:20,836 There is absolutely no fundamental authentication built 720 00:30:20,836 --> 00:30:22,966 into the email accounts that you and I use everyday. 721 00:30:23,316 --> 00:30:25,386 Very often, if you have a sponsored account 722 00:30:25,386 --> 00:30:26,856 with a university or a company, 723 00:30:27,166 --> 00:30:29,986 the system administrators could very well prevent you 724 00:30:29,986 --> 00:30:32,716 from changing that address to something else. 725 00:30:33,066 --> 00:30:34,906 But even I use Gmail all the time. 726 00:30:34,906 --> 00:30:36,806 Yet if you've ever gotten an email from me personally, 727 00:30:36,806 --> 00:30:38,476 it still says harvard.edu 728 00:30:38,476 --> 00:30:40,516 because I'm essentially spoofing the from address. 729 00:30:40,876 --> 00:30:43,636 Now sometimes when you do this, you increase the risk 730 00:30:43,636 --> 00:30:45,166 of your email getting flagged as spam 731 00:30:45,336 --> 00:30:48,246 because servers are getting increasingly sophisticated 732 00:30:48,516 --> 00:30:51,536 and they realize, wait a minute, this is from harvard.edu 733 00:30:51,536 --> 00:30:53,496 but it clearly came from Google servers 734 00:30:53,496 --> 00:30:55,196 on the West Coast, this can't be. 735 00:30:55,196 --> 00:30:56,826 This feels like it's probably spam. 736 00:30:57,196 --> 00:30:59,496 So it's not a perfect system, but fundamentally now, 737 00:30:59,496 --> 00:31:01,636 emails are very easily forged. 738 00:31:01,636 --> 00:31:04,406 And that's why I was able to get that email about the 123-- 739 00:31:04,466 --> 00:31:09,126 what was that, 123contactform.com. 740 00:31:09,466 --> 00:31:11,026 It's just as easy for spammers 741 00:31:11,026 --> 00:31:12,656 to forge any one of our addresses. 742 00:31:12,656 --> 00:31:14,746 So as a rule of thumb, if you ever do get an email 743 00:31:14,746 --> 00:31:17,736 that perhaps seems to be forged, frankly what you can do 744 00:31:17,736 --> 00:31:19,896 in various email clients including Google, 745 00:31:20,116 --> 00:31:21,296 if you look at the original, 746 00:31:21,336 --> 00:31:23,626 you'll see some interesting things, and we won't spend time 747 00:31:23,626 --> 00:31:26,986 on this here but every line in the original part 748 00:31:26,986 --> 00:31:29,806 of an email shows you the IP address or the name 749 00:31:29,806 --> 00:31:31,656 of the server that this email passed through. 750 00:31:31,796 --> 00:31:34,246 So you can often do a bit of forensics and infer 751 00:31:34,246 --> 00:31:36,966 from these headers where this email actually came from. 752 00:31:36,966 --> 00:31:38,876 And if we dwelled on this example, we would see that, 753 00:31:38,876 --> 00:31:42,086 it came from aydede@fas and yet entirely 754 00:31:42,086 --> 00:31:44,796 through Google server, so how could that be. 755 00:31:44,906 --> 00:31:47,316 Or actually not even Harvard's Google servers, 756 00:31:47,806 --> 00:31:51,006 in this case it came from our own cloud server, 757 00:31:51,006 --> 00:31:54,386 which is not FAS, it's of course CS50's own domain. 758 00:31:54,386 --> 00:31:57,896 So I would be remiss if I didn't say don't actually do this. 759 00:31:57,896 --> 00:32:00,776 Actually I-- and I'll say this from personal example. 760 00:32:00,776 --> 00:32:02,646 Freshman year, I was really proud of my self 761 00:32:02,646 --> 00:32:03,466 when I learned this trick 762 00:32:03,466 --> 00:32:05,566 in how you can just put any email address you want 763 00:32:05,566 --> 00:32:07,396 in your email client and voila, send an email. 764 00:32:07,726 --> 00:32:13,326 So I made the unfortunate social and perhaps political decision 765 00:32:13,596 --> 00:32:16,236 to send an email from someone else in my proctor group, 766 00:32:16,516 --> 00:32:19,716 but like a complete moron forgot that I sent out emails 767 00:32:19,716 --> 00:32:21,546 at the time with an automatic signature 768 00:32:21,546 --> 00:32:22,746 which happened to say DJM. 769 00:32:23,346 --> 00:32:25,196 So this email I sent to my whole proctor group 770 00:32:25,196 --> 00:32:29,136 on some stupid kind of issue has made some point on behalf 771 00:32:29,136 --> 00:32:31,366 of a roommate whose opinion I was trying to change, 772 00:32:31,366 --> 00:32:33,516 whatever the stupid-- the story was at the time. 773 00:32:33,876 --> 00:32:38,326 And it was like sincerely Joe or whoever the person was, DJM. 774 00:32:38,326 --> 00:32:38,576 [ Laughter ] 775 00:32:38,576 --> 00:32:38,796 >> Caught. 776 00:32:39,316 --> 00:32:42,216 That was not a good time. 777 00:32:42,216 --> 00:32:45,716 So, again, do as I say, not as I actually do. 778 00:32:45,716 --> 00:32:47,756 Kind of recurring theme here perhaps. 779 00:32:48,216 --> 00:32:51,306 So-- but really the takeaway for today is 780 00:32:51,306 --> 00:32:54,126 that the cool power here is our ability now 781 00:32:54,126 --> 00:32:57,766 to automate very mundane, very tedious tasks and also 782 00:32:57,766 --> 00:32:59,126 to have these processes scale. 783 00:32:59,126 --> 00:33:01,096 Frankly, one of the neatest things about being able 784 00:33:01,096 --> 00:33:02,586 to make a website that's not static, 785 00:33:02,806 --> 00:33:04,746 but that's dynamic using a language like PHP 786 00:33:04,746 --> 00:33:07,896 and we'll see today using a database like MySQL is 787 00:33:07,896 --> 00:33:09,236 that you write this kind of code 788 00:33:09,236 --> 00:33:11,106 and then you walk away, you go to dinner. 789 00:33:11,106 --> 00:33:13,706 You go about your business and the thing runs itself. 790 00:33:13,746 --> 00:33:15,786 Frosh IMs continues to get registrations. 791 00:33:16,056 --> 00:33:18,496 Some of you have probably RSVP'd for the movie already and that's 792 00:33:18,496 --> 00:33:20,936 because we set up a form that's doing that automatically. 793 00:33:21,126 --> 00:33:24,736 So you really get this ability to automate processes and free 794 00:33:24,736 --> 00:33:25,816 up your own human cycles 795 00:33:25,816 --> 00:33:28,016 to solve much more interesting problems. 796 00:33:28,016 --> 00:33:29,006 We do this all of the time. 797 00:33:29,006 --> 00:33:31,586 Certainly this semester, with 500 some students, 798 00:33:31,826 --> 00:33:33,546 anytime you submit those damn forms, 799 00:33:33,546 --> 00:33:36,146 we get 500 new submissions to deal with 800 00:33:36,326 --> 00:33:38,576 but we automate the process of dispatching all 801 00:33:38,576 --> 00:33:40,626 of your individual responses to your teaching fellow. 802 00:33:40,626 --> 00:33:43,736 We synchronize with the server to do so and really humans have 803 00:33:43,736 --> 00:33:46,166 to be relatively uninvolved in that process. 804 00:33:46,166 --> 00:33:48,136 So, you can start to do some neat things 805 00:33:48,136 --> 00:33:49,986 that benefit you, the person. 806 00:33:50,046 --> 00:33:51,886 Alright. So, what more can we do? 807 00:33:51,886 --> 00:33:54,766 Well, let's take a look at froshims4.php 808 00:33:54,766 --> 00:33:57,756 and inch our way toward actually using a database 'cause frankly 809 00:33:57,756 --> 00:34:01,126 at some point, the proctor's expectations are going to rise. 810 00:34:01,126 --> 00:34:02,736 And he or she is not gonna be cool 811 00:34:02,736 --> 00:34:04,456 with getting an email every time one 812 00:34:04,456 --> 00:34:06,706 of 1600 freshmen registers for a sport. 813 00:34:06,986 --> 00:34:08,586 It'd much rather this information end 814 00:34:08,586 --> 00:34:11,526 up in a spreadsheet or end up in a database so that he 815 00:34:11,526 --> 00:34:14,296 or she can look at it anytime they want but not have 816 00:34:14,346 --> 00:34:16,526 to manually copy and paste from this email. 817 00:34:16,526 --> 00:34:20,116 So in 1996 or whatever, sending an email, this was improvement, 818 00:34:20,116 --> 00:34:21,186 'cause it meant no more paper. 819 00:34:21,416 --> 00:34:22,466 But we can do much better 820 00:34:22,466 --> 00:34:24,576 and we can do much better relatively easily. 821 00:34:24,856 --> 00:34:26,206 So first, take notice of this. 822 00:34:26,906 --> 00:34:31,536 This is froshims4.php and you may encounter this paradigm 823 00:34:31,536 --> 00:34:35,156 in section or an example code that you see in books or online, 824 00:34:35,156 --> 00:34:38,146 realize the action of a form does not need 825 00:34:38,146 --> 00:34:39,566 to point to a separate file. 826 00:34:39,616 --> 00:34:42,366 You'll see in problem set 7 that we do this consistently. 827 00:34:42,366 --> 00:34:44,776 We have one file, say, login.php submit 828 00:34:45,016 --> 00:34:47,866 to login2.php 'cause I think in terms 829 00:34:47,866 --> 00:34:49,556 of the mental model, it's nice and simple. 830 00:34:49,556 --> 00:34:51,536 There's step 1 and then there's step 2. 831 00:34:51,606 --> 00:34:53,866 But realize once you now have the ability 832 00:34:53,866 --> 00:34:56,776 to write this code yourself, you can actually have, 833 00:34:56,776 --> 00:35:01,956 as in this case, a file called froshims4.php submit back 834 00:35:02,096 --> 00:35:02,866 to its self. 835 00:35:03,596 --> 00:35:06,746 Now why in the world would you want a web page like a form 836 00:35:06,946 --> 00:35:10,326 to submit not to a different URL but to the same exact URL, 837 00:35:10,626 --> 00:35:11,826 to the same file, in fact? 838 00:35:12,866 --> 00:35:17,926 What might be the value in that? 839 00:35:19,416 --> 00:35:19,536 Some [inaudible]. 840 00:35:19,536 --> 00:35:19,603 Yeah. 841 00:35:19,603 --> 00:35:19,746 [ Inaudible Remark ] 842 00:35:19,746 --> 00:35:22,276 >> Update the what? 843 00:35:22,466 --> 00:35:24,346 So, update the web page of the user data. 844 00:35:24,526 --> 00:35:26,606 Possibly, possibly. 845 00:35:26,606 --> 00:35:29,546 Let me point out one of the sort of downsides 846 00:35:29,546 --> 00:35:30,536 of this current approach. 847 00:35:30,536 --> 00:35:33,146 If I go back to register 3, 848 00:35:33,386 --> 00:35:35,996 suppose that I actually don't fill out this form 849 00:35:35,996 --> 00:35:38,376 and just click register-- oh, actually what-- 850 00:35:38,376 --> 00:35:39,556 I can't demo with this example. 851 00:35:39,766 --> 00:35:41,736 What happens on the most annoying of sites? 852 00:35:41,736 --> 00:35:44,456 You click submit, you then get to a page and it says, sorry, 853 00:35:44,486 --> 00:35:45,816 you need to provide your email address. 854 00:35:45,816 --> 00:35:48,016 And then you have to hit the back button and sometimes 855 00:35:48,016 --> 00:35:49,316 on this horribly designed website, 856 00:35:49,316 --> 00:35:51,696 the whole form is then blank and you have 857 00:35:51,696 --> 00:35:52,846 to start all over again. 858 00:35:53,066 --> 00:35:55,376 So if you're actually sending the user from point A 859 00:35:55,376 --> 00:35:57,476 to point B, the problem is 860 00:35:57,476 --> 00:35:59,696 that point B is probably gonna look different and 861 00:35:59,696 --> 00:36:02,106 yet if they made a mistake, you want them to go fill 862 00:36:02,106 --> 00:36:05,226 out point A again, and so why not just leave them there 863 00:36:05,276 --> 00:36:05,876 if possible. 864 00:36:05,876 --> 00:36:09,146 So, one of the tricks we can see here in this next example is 865 00:36:09,146 --> 00:36:13,396 if I look at froshims5.php, if I want to detect 866 00:36:14,106 --> 00:36:17,066 that an error has happened, I can do this at the top 867 00:36:17,066 --> 00:36:19,536 of the same file and then leverage this information. 868 00:36:19,656 --> 00:36:21,306 So, let's see what this thing does. 869 00:36:21,306 --> 00:36:26,716 First, I'm gonna go to froshims4, 5 rather .php. 870 00:36:26,716 --> 00:36:30,256 Let me suppress this error message with a little trick 871 00:36:30,256 --> 00:36:32,276 for now, ignore that little detail, I'll fix it later. 872 00:36:32,766 --> 00:36:36,966 Oh, another trick, ignore what I just did there, fix that later. 873 00:36:37,196 --> 00:36:38,536 Okay. Dammit. 874 00:36:39,446 --> 00:36:43,856 Alright, close your eyes for another moment, line 37, 875 00:36:44,176 --> 00:36:45,766 the server I'm using is slightly different 876 00:36:45,766 --> 00:36:47,046 from the server you'll be using. 877 00:36:47,516 --> 00:36:48,136 That's my excuse. 878 00:36:49,716 --> 00:36:51,116 Alright, I'm losing credibility today. 879 00:36:51,226 --> 00:36:52,476 Okay, perfect form, right? 880 00:36:52,526 --> 00:36:54,466 So now this is froshims5. 881 00:36:54,616 --> 00:36:56,376 Now suppose I just say, alright, you don't need 882 00:36:56,376 --> 00:36:58,426 to know this information, I'm just David, register. 883 00:36:58,956 --> 00:37:01,746 Dammit, line 15th. 884 00:37:02,146 --> 00:37:02,286 Here. 885 00:37:02,286 --> 00:37:03,776 [ Inaudible Remark ] 886 00:37:03,776 --> 00:37:04,486 >> This is fast. 887 00:37:04,616 --> 00:37:06,576 This is one line of configuration on the server 888 00:37:06,576 --> 00:37:07,596 that will make that problem go away. 889 00:37:08,076 --> 00:37:09,896 Okay, so notice here, I said David. 890 00:37:09,996 --> 00:37:12,766 I clicked register and then I got yelled at in red text 891 00:37:12,866 --> 00:37:14,096 but I'm on the same form. 892 00:37:14,316 --> 00:37:17,506 So it looks as though that that red text you must fill 893 00:37:17,506 --> 00:37:19,926 out the form is maybe being conditionally shown. 894 00:37:19,926 --> 00:37:23,576 And sure enough, if we just have some logic in the same PHP file, 895 00:37:23,576 --> 00:37:25,476 we can check was there an error. 896 00:37:25,476 --> 00:37:27,496 If so, let me yell at the user, 897 00:37:27,496 --> 00:37:30,106 otherwise let me just show the form as usual. 898 00:37:30,106 --> 00:37:35,156 So this is froshims5 and notice that froshims5.php first of all, 899 00:37:35,286 --> 00:37:36,546 this is almost copy and paste 900 00:37:36,546 --> 00:37:37,836 from everything we've seen thus far. 901 00:37:37,956 --> 00:37:39,246 So I gloss over some details. 902 00:37:39,546 --> 00:37:43,156 Notice that froshims5.php submits back to itself. 903 00:37:43,226 --> 00:37:45,696 And that's what initially is gonna enable this neat trick 904 00:37:45,916 --> 00:37:48,676 of having this immediate feedback loop on the same page. 905 00:37:48,936 --> 00:37:50,866 But at the top of this file, notice what I did, 906 00:37:51,376 --> 00:37:54,236 ignore all of these at signs. 907 00:37:54,236 --> 00:37:55,906 Though for those perhaps more familiar, 908 00:37:55,906 --> 00:37:58,336 the at sign is essentially suppressing these things called 909 00:37:58,336 --> 00:38:00,206 notices that we were seeing, but again, 910 00:38:00,206 --> 00:38:02,216 we'll disable those permanently for you. 911 00:38:03,096 --> 00:38:04,456 So notice this. 912 00:38:04,456 --> 00:38:09,816 If the value of the action parameter is true, 913 00:38:09,916 --> 00:38:11,626 go ahead and do this. 914 00:38:11,626 --> 00:38:12,756 Well, what's going on here? 915 00:38:12,956 --> 00:38:15,566 Well notice here, I'm gonna wave my hands at some of the details 916 00:38:15,566 --> 00:38:18,106 for now but notice that if the value 917 00:38:18,106 --> 00:38:21,296 of name equals equals blank or the value 918 00:38:21,296 --> 00:38:24,196 of gender equals equals blank or the value 919 00:38:24,196 --> 00:38:26,816 of dorm equals equals blank, this time, 920 00:38:26,956 --> 00:38:29,376 I'm actually gonna set a variable called dollar sign 921 00:38:29,416 --> 00:38:32,486 error and just set it equal to true. 922 00:38:32,766 --> 00:38:36,366 One of the minor weaknesses in PHP is 923 00:38:36,366 --> 00:38:39,366 that it's case insensitive sometimes but not always 924 00:38:39,456 --> 00:38:41,146 so you will see some textbooks and resource 925 00:38:41,146 --> 00:38:42,346 that say uppercase true. 926 00:38:42,616 --> 00:38:44,126 Sometimes you'll see lowercase true. 927 00:38:44,126 --> 00:38:45,956 Sometimes you'll see capital T true. 928 00:38:46,236 --> 00:38:46,966 It's kind of a mess. 929 00:38:47,096 --> 00:38:50,096 I would just as always with style be consistent so I'll go 930 00:38:50,096 --> 00:38:51,286 with uppercase this time around. 931 00:38:51,586 --> 00:38:53,356 And so now error is true. 932 00:38:53,506 --> 00:38:55,066 So notice what's gonna happen here. 933 00:38:55,066 --> 00:38:57,456 If I scroll down, notice this line of code. 934 00:38:57,926 --> 00:39:00,716 Recall that you can have if conditions in PHP code 935 00:39:00,856 --> 00:39:03,936 and recall that you can commingle PHP code and HTML. 936 00:39:04,186 --> 00:39:07,416 So notice I have HTML, HTML, HTML, HTML. 937 00:39:07,416 --> 00:39:10,406 Oh, open bracket question mark, here comes some PHP code, 938 00:39:10,406 --> 00:39:11,776 I'm gonna ask a question. 939 00:39:12,076 --> 00:39:15,676 If error is true, so again, ignore the at sign for now. 940 00:39:15,676 --> 00:39:19,636 But if dollar sign error is true, colon, do the following. 941 00:39:19,636 --> 00:39:23,196 So it's okay in PHP to then exit PHP mode because so long 942 00:39:23,196 --> 00:39:25,386 as you've just answered true to that question, 943 00:39:25,686 --> 00:39:27,816 only the following lines are going to print. 944 00:39:28,196 --> 00:39:31,006 So, div style, so this is where I get that red 945 00:39:31,006 --> 00:39:32,746 from div again is the division of the page. 946 00:39:32,746 --> 00:39:34,076 Style is for CSS. 947 00:39:34,376 --> 00:39:36,136 Color colon red makes the text red. 948 00:39:36,136 --> 00:39:37,766 And notice there, there is that sentence. 949 00:39:37,766 --> 00:39:39,826 You must fill out the form, exclamation point, 950 00:39:40,006 --> 00:39:42,666 and at the end of that is going to be my close div tag 951 00:39:43,006 --> 00:39:45,516 which looks like that, and then endif. 952 00:39:45,956 --> 00:39:47,446 So in short, I just have a condition. 953 00:39:47,526 --> 00:39:50,126 In my PHP code, it checks the value of error 954 00:39:50,126 --> 00:39:53,376 which I myself set at the top of this file for the purposes 955 00:39:53,376 --> 00:39:54,936 of reminding my self later 956 00:39:54,936 --> 00:39:56,986 when I actually render the web page was 957 00:39:56,986 --> 00:39:59,556 in fact there an error in this case. 958 00:40:00,086 --> 00:40:02,436 >> But we're still not doing anything with this information. 959 00:40:02,516 --> 00:40:05,566 So let's actually take one more step toward that 960 00:40:05,716 --> 00:40:08,886 and also move away from hard coding everything into our page. 961 00:40:08,886 --> 00:40:12,806 As soon as you find yourself in pset7 or 8 or any final project, 962 00:40:13,076 --> 00:40:15,316 copying and pasting on, it's probably time 963 00:40:15,316 --> 00:40:17,266 to start automating the process somehow. 964 00:40:17,506 --> 00:40:20,206 So it turns out in PHP, you can declare an array, 965 00:40:20,486 --> 00:40:23,606 just as you can in C, and you can statically initialize it 966 00:40:23,606 --> 00:40:26,266 which means you can put values in it right from the get-go. 967 00:40:26,496 --> 00:40:28,566 And they don't have to have numbers associated 968 00:40:28,566 --> 00:40:31,156 with them yet, they'll be infer, and here's how we do this. 969 00:40:31,306 --> 00:40:34,526 I know from just having, you know, looked up some list 970 00:40:34,526 --> 00:40:36,806 of all the dorms on campus or figure them out off the top 971 00:40:36,806 --> 00:40:38,736 of my head that here all the dorms, 972 00:40:39,026 --> 00:40:40,916 feels like this is a good candidate for an array. 973 00:40:41,006 --> 00:40:43,656 Otherwise, I'm gonna have to copy and paste the same HTML 974 00:40:43,656 --> 00:40:45,226 for each of these dorms so I can have 975 00:40:45,226 --> 00:40:47,386 that drop again and again and again. 976 00:40:47,706 --> 00:40:50,646 So let me go ahead and declare a variable called "dorms." 977 00:40:50,946 --> 00:40:53,556 I wrote it in all caps this time just like you might in C 978 00:40:53,556 --> 00:40:55,246 to say this is some global variable, 979 00:40:55,246 --> 00:40:56,466 this is a constant rather, 980 00:40:56,516 --> 00:40:59,266 this is a constant storing all the values 981 00:40:59,266 --> 00:41:00,166 that aren't gonna change. 982 00:41:00,556 --> 00:41:04,786 In PHP, there's actually a function called array whose 983 00:41:04,786 --> 00:41:06,726 purpose in life is to take 1 or-- 984 00:41:06,816 --> 00:41:10,376 0 or more arguments and those arguments become the elements 985 00:41:10,426 --> 00:41:11,296 inside that array. 986 00:41:11,706 --> 00:41:14,106 So whereas in C, you would've just done a curly brace. 987 00:41:14,266 --> 00:41:16,806 Unfortunately in PHP made the slightly annoying decision 988 00:41:16,806 --> 00:41:19,956 to call it array as a function and so you have parenthesis 989 00:41:20,246 --> 00:41:23,716 and then white space as in C doesn't really matter 990 00:41:23,716 --> 00:41:27,516 and decided rather than having this be a huge long line of text 991 00:41:27,516 --> 00:41:30,156 with commas and quotes, I decided to put every dorm 992 00:41:30,156 --> 00:41:32,556 on its own line with commas separating them just 993 00:41:32,556 --> 00:41:33,746 to keep things kind of pretty, 994 00:41:33,746 --> 00:41:35,976 but that's just an arbitrary stylistic convention. 995 00:41:36,306 --> 00:41:37,936 But now notice what I do down here. 996 00:41:38,176 --> 00:41:40,726 You can generate forms even dynamically. 997 00:41:40,726 --> 00:41:42,296 So now notice what I've done here. 998 00:41:42,546 --> 00:41:45,766 The TD tags are part of the table. 999 00:41:46,076 --> 00:41:47,396 So TD is Table Data. 1000 00:41:47,656 --> 00:41:50,936 So ignore, for today's purposes, some of the markup like TR 1001 00:41:50,936 --> 00:41:53,156 which is Table Row, TD which is Table Data, 1002 00:41:53,436 --> 00:41:55,056 'cause like we saw last week, 1003 00:41:55,056 --> 00:41:57,276 that just let us structure something behind the scenes. 1004 00:41:57,276 --> 00:41:58,466 And if it's new to you, 1005 00:41:58,736 --> 00:42:00,446 it actually is pretty quick to pick up on. 1006 00:42:00,726 --> 00:42:01,886 But the point for now is this. 1007 00:42:02,346 --> 00:42:03,496 There is this other element, 1008 00:42:03,496 --> 00:42:06,486 for some reason it's not called an input, it's called a select. 1009 00:42:06,876 --> 00:42:09,536 This is what the code with which you make a drop-down menu 1010 00:42:09,566 --> 00:42:10,116 in HTML. 1011 00:42:10,536 --> 00:42:13,276 But notice, I can commingle some PHP here, too. 1012 00:42:13,456 --> 00:42:16,046 I'm gonna say select name equals dorm. 1013 00:42:16,046 --> 00:42:18,816 So this is declaring a drop-down menu called "dorm," 1014 00:42:19,056 --> 00:42:21,616 whose size is 1, which means you're only gonna see one dorm 1015 00:42:21,616 --> 00:42:23,716 at a time which is generally the default. 1016 00:42:24,116 --> 00:42:28,016 Notice that I wanted this menu to be blank initially 1017 00:42:28,316 --> 00:42:30,916 so I declared an option whose value is blank 1018 00:42:31,166 --> 00:42:34,306 and who has nothing inside the open tag and close tag, 1019 00:42:34,486 --> 00:42:36,596 and that's how you just create a blank option in one 1020 00:42:36,596 --> 00:42:38,776 of these drop-down menus and then I have this. 1021 00:42:38,776 --> 00:42:40,306 And this is where it gets interesting. 1022 00:42:40,686 --> 00:42:42,036 What's really nice about PHP is 1023 00:42:42,036 --> 00:42:44,836 that it doesn't just have four loops in wild loops 1024 00:42:44,836 --> 00:42:47,516 and do wild loops, it has some other useful mechanisms 1025 00:42:47,516 --> 00:42:48,846 that some of you might have seen in Java 1026 00:42:48,846 --> 00:42:51,016 or other language namely foreach. 1027 00:42:51,256 --> 00:42:52,906 Foreach is just a for loop. 1028 00:42:52,906 --> 00:42:55,426 It doesn't do anything fundamentally new 1029 00:42:55,696 --> 00:42:58,196 but it allows you to write some code a little more simply 1030 00:42:58,406 --> 00:43:01,056 and a little more quickly and I can say something like this, 1031 00:43:01,456 --> 00:43:04,556 foreach array as variable. 1032 00:43:04,836 --> 00:43:05,856 So what do I mean by that? 1033 00:43:06,086 --> 00:43:09,346 Its first keyword inside its pair of parenthesis is 1034 00:43:09,596 --> 00:43:11,226 to put the name of an array-- 1035 00:43:11,496 --> 00:43:14,256 the variable for an array in which case, dorms. 1036 00:43:14,496 --> 00:43:15,826 Then you literarily write as, 1037 00:43:15,826 --> 00:43:19,476 and then you choose any variable name you want, dollar sign I, 1038 00:43:19,476 --> 00:43:22,406 dollar sign N, dollar sign dorm in this case, 1039 00:43:22,406 --> 00:43:23,896 just to be conceptually consistent. 1040 00:43:24,136 --> 00:43:26,236 And what's really neat about this construct is 1041 00:43:26,236 --> 00:43:28,476 on every iteration of this foreach loop, 1042 00:43:28,736 --> 00:43:32,406 it's going to assign to this value the first element 1043 00:43:32,406 --> 00:43:35,346 in dorms; then on the next iteration, the second element 1044 00:43:35,346 --> 00:43:37,546 in dorms; then on the next iteration, the third 1045 00:43:37,546 --> 00:43:38,846 and so forth so you don't have 1046 00:43:38,846 --> 00:43:42,346 to do this very annoying bracket dollar sign I notation 1047 00:43:42,346 --> 00:43:43,386 that we've been doing for weeks. 1048 00:43:43,626 --> 00:43:46,396 You can just conceptually loop over all the elements in array 1049 00:43:46,396 --> 00:43:50,126 and assign each of them to dollar sign dorm one at a time. 1050 00:43:50,416 --> 00:43:53,056 Now I need to dynamically output this option element. 1051 00:43:53,336 --> 00:43:57,366 So notice what I'm doing here, option value equals "". 1052 00:43:57,696 --> 00:44:00,736 But notice again, I'm commingling PHP and HTML here 1053 00:44:00,986 --> 00:44:04,356 so I need to quickly drop into PHP mode, output the value 1054 00:44:04,356 --> 00:44:07,556 of some variable, then drop out of PHP mode 1055 00:44:07,556 --> 00:44:09,986 and so that's what I'm doing, open bracket ? 1056 00:44:09,986 --> 00:44:13,106 equal sign which says put the value 1057 00:44:13,106 --> 00:44:14,546 of the following variable here. 1058 00:44:14,546 --> 00:44:15,826 What variable? 1059 00:44:16,126 --> 00:44:20,226 Dorm, "". And then also because the option element not unlike 1060 00:44:20,226 --> 00:44:23,786 hyper references has both a value that you actually-- 1061 00:44:23,786 --> 00:44:26,766 that actually get stored like a URL and what you see. 1062 00:44:27,026 --> 00:44:28,706 I'm also just gonna put verbatim, 1063 00:44:28,706 --> 00:44:31,196 the dorm's name out here as well. 1064 00:44:31,196 --> 00:44:34,356 And so the end result if we go to this example here, 1065 00:44:34,636 --> 00:44:37,596 froshims6.php, is really the same form. 1066 00:44:37,596 --> 00:44:39,556 But now we're starting to leverage some 1067 00:44:39,556 --> 00:44:41,626 of our program-- oh, dammit. 1068 00:44:41,626 --> 00:44:44,946 Now we're starting to leverage some of our programming skills. 1069 00:44:44,976 --> 00:44:45,906 I'm gonna cheat and tell 1070 00:44:45,906 --> 00:44:47,846 that this is it 'cause I already fixed this one. 1071 00:44:48,216 --> 00:44:50,976 And now we have this drop-down whose first element is blank, 1072 00:44:51,046 --> 00:44:53,396 but then whose subsequent elements actually have all 1073 00:44:53,396 --> 00:44:54,146 of these dorms. 1074 00:44:54,146 --> 00:44:55,896 And so here, too, is where things start 1075 00:44:55,896 --> 00:44:57,666 to get even more and more powerful. 1076 00:44:57,896 --> 00:45:01,256 Just to contextualize this, something like-- 1077 00:45:01,256 --> 00:45:03,366 I mean, frankly, even something like Harvard FML 1078 00:45:03,366 --> 00:45:05,546 which is actually outsourced to, I think, Tumblr, 1079 00:45:05,546 --> 00:45:07,216 which is a third party blogging software. 1080 00:45:07,506 --> 00:45:10,356 They use some kind of database and in that database are row 1081 00:45:10,356 --> 00:45:12,716 by row, all of the POSTs that people have made. 1082 00:45:12,996 --> 00:45:15,296 If that site happens to be implemented in PHP, 1083 00:45:15,296 --> 00:45:16,946 it doesn't have to be, but maybe it is, 1084 00:45:17,136 --> 00:45:19,986 you can imagine getting back an array of all of the POST 1085 00:45:19,986 --> 00:45:23,036 on Harvard FML and then just using some fairly succinct 1086 00:45:23,186 --> 00:45:26,776 syntax like foreach POST as POST 1087 00:45:27,166 --> 00:45:29,996 and then this is how you see the exact same structure 1088 00:45:29,996 --> 00:45:32,476 for everyone of the POST on something like Harvard FML 1089 00:45:32,696 --> 00:45:33,956 but the content changes. 1090 00:45:33,956 --> 00:45:36,016 But it's really just being generated by a for loop. 1091 00:45:36,016 --> 00:45:39,116 So much like we use for loops in C to generate any kind 1092 00:45:39,116 --> 00:45:40,086 of cyclical structures, 1093 00:45:40,426 --> 00:45:45,556 similarly might we do this here in PHP as well. 1094 00:45:45,626 --> 00:45:50,066 So let me go ahead and spoil just a couple of more details 1095 00:45:51,006 --> 00:45:56,846 and show us the most fun one which is going to be this one. 1096 00:45:56,896 --> 00:46:00,676 Alright, so froshims8.php, 1097 00:46:01,076 --> 00:46:03,136 we finally have-- alright, there we go. 1098 00:46:03,136 --> 00:46:04,756 This one is clean. 1099 00:46:04,786 --> 00:46:07,686 In froshims8.php, notice that it actually submits 1100 00:46:08,026 --> 00:46:11,326 to a file called register8.php. 1101 00:46:11,326 --> 00:46:13,576 And-- I don't actually have eight versions of registration. 1102 00:46:13,576 --> 00:46:14,806 I just wanted the numbers to line up, 1103 00:46:14,856 --> 00:46:16,116 if you're following along on paper. 1104 00:46:16,366 --> 00:46:18,856 So this form looks exactly the same as every other, 1105 00:46:19,086 --> 00:46:21,096 but it submits to register8.php. 1106 00:46:21,226 --> 00:46:25,066 'Cause I got tired being the proctor of dealing with all 1107 00:46:25,066 --> 00:46:27,596 of these emails, so now I actually wanna store this 1108 00:46:27,596 --> 00:46:28,876 information in a database. 1109 00:46:28,986 --> 00:46:31,676 So I'll look back at the code in a moment, but let's go ahead 1110 00:46:31,676 --> 00:46:33,406 and introduce the actual database 1111 00:46:33,406 --> 00:46:34,286 in which we'll store this. 1112 00:46:34,626 --> 00:46:36,826 So a database is really just-- 1113 00:46:37,166 --> 00:46:39,366 a database as most people know it is what's called a 1114 00:46:39,366 --> 00:46:40,446 relational database. 1115 00:46:40,526 --> 00:46:43,896 And a relational database is essentially some kind 1116 00:46:43,896 --> 00:46:46,856 of special server software that stores lots of tables. 1117 00:46:46,856 --> 00:46:48,936 And a table is just something with rows and columns. 1118 00:46:48,936 --> 00:46:52,546 It's just a spreadsheet for-- if that's the most familiar notion. 1119 00:46:52,886 --> 00:46:55,616 So there exist various implementations of this idea 1120 00:46:55,616 --> 00:46:58,186 of a database, there exist Microsoft Access, 1121 00:46:58,186 --> 00:47:00,356 Microsoft SQL Server, Oracle, 1122 00:47:00,546 --> 00:47:03,866 and then something called MySQL, and dozens of others. 1123 00:47:03,896 --> 00:47:06,356 But MySQL is one of the most popular, free, 1124 00:47:06,426 --> 00:47:09,026 open source database servers. 1125 00:47:09,026 --> 00:47:11,416 And by open source, that means you can look at the source code 1126 00:47:11,416 --> 00:47:13,546 that other people have written and it power 1127 00:47:13,546 --> 00:47:14,816 such sites as Facebook. 1128 00:47:14,856 --> 00:47:15,776 Frankly, it was Facebook-- 1129 00:47:15,776 --> 00:47:18,806 was really one of its biggest proponents in recent years 1130 00:47:18,806 --> 00:47:22,486 that really pushing it to its limits in terms of scalability 1131 00:47:22,486 --> 00:47:24,526 and they still use it for much of their data. 1132 00:47:24,526 --> 00:47:27,416 So what better option is there when it's free 1133 00:47:27,636 --> 00:47:29,976 and apparently it scales pretty darn well? 1134 00:47:29,976 --> 00:47:32,976 So we too, because of its relative ease of use 1135 00:47:32,976 --> 00:47:35,566 and its free availability, use MySQL for this portion 1136 00:47:35,566 --> 00:47:37,476 of the course, which is to say that we, the course, 1137 00:47:37,726 --> 00:47:40,116 run a database server and what's neat is you can go 1138 00:47:40,116 --> 00:47:42,486 on your own laptop and download the same software 1139 00:47:42,486 --> 00:47:44,186 and run a database on your laptop. 1140 00:47:44,506 --> 00:47:45,706 I'm sorry, that's not useful 1141 00:47:45,706 --> 00:47:48,206 for other people 'cause your laptop is probably not a web 1142 00:47:48,206 --> 00:47:49,206 server on the internet. 1143 00:47:49,446 --> 00:47:51,176 So generally, when you have a database server, 1144 00:47:51,176 --> 00:47:53,746 it leaves on some central server, like the cloud. 1145 00:47:53,746 --> 00:47:55,696 If you decide to commercialize 1146 00:47:55,696 --> 00:47:57,466 or just migrate your final projects though off 1147 00:47:57,466 --> 00:47:59,366 to a commercial web host at the end of the semester, 1148 00:47:59,596 --> 00:48:00,956 almost every commercial web POST 1149 00:48:00,956 --> 00:48:03,316 out there these days provides MySQL server. 1150 00:48:03,316 --> 00:48:05,196 So it's very easy to run your data elsewhere. 1151 00:48:05,566 --> 00:48:06,886 So what does this actually mean? 1152 00:48:06,886 --> 00:48:08,376 Well, I need at some way 1153 00:48:08,646 --> 00:48:10,746 of actually creating these things called tables 1154 00:48:10,806 --> 00:48:12,386 in the course's database server. 1155 00:48:12,616 --> 00:48:15,046 And for this, something like this froshims feels 1156 00:48:15,046 --> 00:48:17,296 like I just need one table, one spreadsheet, 1157 00:48:17,516 --> 00:48:20,956 each of whose columns are gonna name and then a captain column 1158 00:48:20,996 --> 00:48:23,776 and a gender column, and a dorm column, and that's about it. 1159 00:48:23,976 --> 00:48:26,906 So if you were to pull up Google Docs or Google Spreadsheets 1160 00:48:26,906 --> 00:48:28,836 or Excel, you would just write those labels 1161 00:48:28,836 --> 00:48:29,816 at the top of the field. 1162 00:48:29,816 --> 00:48:32,516 But because we're actually using this in a programing context, 1163 00:48:32,776 --> 00:48:34,196 I'm actually gonna pull up this tool. 1164 00:48:34,796 --> 00:48:39,826 So there is a program that leaves per Problem Set 7 1165 00:48:39,826 --> 00:48:43,116 at cloud.cs50.net/phpmyadmin. 1166 00:48:43,226 --> 00:48:46,636 It's actually coincidence that the thing is called phpmyadmin. 1167 00:48:46,906 --> 00:48:48,446 It does happen to be in-- 1168 00:48:48,446 --> 00:48:50,346 written in PHP but we're using it 1169 00:48:50,346 --> 00:48:53,516 because it's a wonderful user-friendly web-based GUI 1170 00:48:53,766 --> 00:48:55,586 for interacting with a database server. 1171 00:48:55,586 --> 00:48:58,116 So when you pull up this URL, you're prompted to login 1172 00:48:58,116 --> 00:49:00,856 with a username and password, pset7 will tell you exactly what 1173 00:49:00,856 --> 00:49:03,556 that username and password are and you'll see this interface. 1174 00:49:03,556 --> 00:49:05,496 And frankly, this is a little overwhelming at first 1175 00:49:05,706 --> 00:49:06,496 but almost everything 1176 00:49:06,496 --> 00:49:08,976 on the right hand side we can ignore from now on. 1177 00:49:08,976 --> 00:49:11,986 Because the only I care about at the moment is the fact that now 1178 00:49:11,986 --> 00:49:14,676 that I've logged in, I have access to a database 1179 00:49:14,796 --> 00:49:17,316 that we've created for you all and mine happens 1180 00:49:17,316 --> 00:49:19,356 to be called Malan_Lecture. 1181 00:49:19,436 --> 00:49:21,606 Yours will be called Username_pset7. 1182 00:49:21,606 --> 00:49:23,286 So I'm gonna click this. 1183 00:49:23,286 --> 00:49:26,296 And now notice, no tables found in database. 1184 00:49:26,406 --> 00:49:28,776 So this is what would happen too in a commercial web host 1185 00:49:28,776 --> 00:49:30,766 or if you install the software on your own laptop, 1186 00:49:30,986 --> 00:49:34,706 you would initially have no actual tables in your database. 1187 00:49:35,036 --> 00:49:37,366 So you can think of table really as a worksheet, 1188 00:49:37,506 --> 00:49:39,766 like a spreadsheet has multiple worksheets in Excel 1189 00:49:39,766 --> 00:49:42,896 and Google Docs, so I have no tables yet, so I need one. 1190 00:49:42,926 --> 00:49:45,486 So I'm gonna create one called registrants, let's say, 1191 00:49:45,596 --> 00:49:46,886 for all the people who have registered, 1192 00:49:47,146 --> 00:49:49,796 and then how many fields, quick sanity check for, 1193 00:49:49,796 --> 00:49:53,936 so then I'm gonna click go and realize there are different ways 1194 00:49:53,936 --> 00:49:55,576 of interacting with a database server. 1195 00:49:55,766 --> 00:49:58,986 This is just one free user friendly way of doing it. 1196 00:49:59,346 --> 00:50:00,976 So now you'll see on the page that appears. 1197 00:50:01,046 --> 00:50:03,236 >> It's kind of wide on my screen here. 1198 00:50:03,466 --> 00:50:06,636 But I'm being asked for a few answers to questions. 1199 00:50:06,696 --> 00:50:08,556 First, I'm being asked to answer 1200 00:50:08,716 --> 00:50:10,156 "What do you want me to call this field?" 1201 00:50:10,256 --> 00:50:11,846 So I'm gonna quickly say name field. 1202 00:50:12,226 --> 00:50:15,936 This one is going to be, let's see, what was it, captain. 1203 00:50:16,376 --> 00:50:18,106 This next one is gonna be gender. 1204 00:50:18,106 --> 00:50:19,876 And this last one is going to be dorm. 1205 00:50:19,876 --> 00:50:22,266 But there're a few other questions I need to answer. 1206 00:50:22,606 --> 00:50:27,066 Unlike PHP which doesn't really have explicit data types, 1207 00:50:27,066 --> 00:50:29,026 at least that you need to mention, it's a little more 1208 00:50:29,026 --> 00:50:31,956 like C MySQL because when you're using a database, 1209 00:50:32,216 --> 00:50:34,326 it's actually really useful to know what type 1210 00:50:34,326 --> 00:50:36,476 of data you're storing for performance reasons. 1211 00:50:36,476 --> 00:50:38,756 Now for our example here, there's never gonna be more 1212 00:50:38,756 --> 00:50:40,586 than like 1600 freshman register, 1213 00:50:40,856 --> 00:50:43,086 but again consider Facebook, consider Google Docs, 1214 00:50:43,086 --> 00:50:45,826 consider any concepts where there's actually thousands 1215 00:50:45,826 --> 00:50:47,806 of entries or millions of entries. 1216 00:50:48,076 --> 00:50:50,706 In fact, we've been running some of those CS50 apps now 1217 00:50:50,706 --> 00:50:53,026 that you-- you might have played with this semester for two 1218 00:50:53,026 --> 00:50:56,656 or three years and some of those databases case and points, 1219 00:50:57,526 --> 00:51:01,276 if we go to tweets.cs50.net, we have a MySQL table 1220 00:51:01,276 --> 00:51:06,476 that stores all the tweets and right now it has 105,654 tweets 1221 00:51:06,546 --> 00:51:09,846 that people have tweeted just in a row in a database 1222 00:51:09,846 --> 00:51:11,506 and that's not even considered that big. 1223 00:51:11,506 --> 00:51:13,756 So you can actually do some neat things with the software 1224 00:51:13,916 --> 00:51:14,896 but we need to choose a type. 1225 00:51:14,946 --> 00:51:17,716 Now for a name, we want a string conceptually. 1226 00:51:17,946 --> 00:51:19,846 But in MySQL, there's different type of strings 1227 00:51:19,846 --> 00:51:21,356 but we'll highlight just one for now, 1228 00:51:21,626 --> 00:51:23,726 VARCHAR is perhaps the most common. 1229 00:51:23,726 --> 00:51:26,036 VARCHAR is variable char and this is 1230 00:51:26,036 --> 00:51:28,316 when you know you want a string of characters 1231 00:51:28,456 --> 00:51:31,136 but you're not quite sure how long that string is gonna be 1232 00:51:31,296 --> 00:51:34,206 but MySQL does demand that you give it an upper bound. 1233 00:51:34,356 --> 00:51:37,286 So very common for name might be, how many let-- 1234 00:51:37,286 --> 00:51:39,946 characters do we need to allow for a person's name. 1235 00:51:41,076 --> 00:51:44,766 I mean like 10 is feels too short, 20 feels like it's short, 1236 00:51:44,766 --> 00:51:46,496 I mean frankly there's not that much harm 1237 00:51:46,496 --> 00:51:47,956 in just rounding up, frankly. 1238 00:51:47,956 --> 00:51:51,396 So let's say 255 is a pretty good upper bound even 1239 00:51:51,396 --> 00:51:53,406 for certain foreign names which might be longer 1240 00:51:53,406 --> 00:51:54,586 than traditional American names 1241 00:51:54,586 --> 00:51:56,116 like that gives us a pretty good buffer 1242 00:51:56,116 --> 00:51:59,616 but we could go even higher, thousand and 24, you know, 1243 00:51:59,616 --> 00:52:01,496 generally people have rules of thumb that they stick to, 1244 00:52:01,496 --> 00:52:05,446 255 is a popular convention because years ago, 1245 00:52:05,446 --> 00:52:08,626 this actually used to be the maximum though now it's 65,000 1246 00:52:08,626 --> 00:52:10,866 characters, that's probably overkill for someone's name. 1247 00:52:11,246 --> 00:52:12,366 Now what about captain? 1248 00:52:12,646 --> 00:52:14,186 So how do you implement the notion of a captain, 1249 00:52:15,146 --> 00:52:17,106 what data type instinctively might you want? 1250 00:52:17,926 --> 00:52:18,676 So a Boolean. 1251 00:52:18,676 --> 00:52:20,656 So it turns out that MySQL 1252 00:52:20,836 --> 00:52:24,336 and generally SQL databases might not support Booleans per 1253 00:52:24,336 --> 00:52:26,316 se but they can mimic them. 1254 00:52:26,316 --> 00:52:29,216 In fact even if we see it here, let me scroll back up, 1255 00:52:29,416 --> 00:52:31,256 there is a Boolean value there 1256 00:52:31,706 --> 00:52:34,726 but you can actually implement a Boolean frankly with just an int 1257 00:52:35,026 --> 00:52:37,346 or short or 8-- or char frankly 1258 00:52:37,556 --> 00:52:39,336 so that's actually what the database server is doing. 1259 00:52:39,336 --> 00:52:41,146 It's calling it a Boolean but to be honest, 1260 00:52:41,146 --> 00:52:43,476 this is probably gonna cost us at least 8 bits. 1261 00:52:43,886 --> 00:52:46,666 It's just the computers deal usually with bytes, 1262 00:52:46,696 --> 00:52:48,406 not individual bits, so that's fine. 1263 00:52:48,496 --> 00:52:49,816 Now captain is gonna be a Boolean. 1264 00:52:50,056 --> 00:52:52,616 Gender, meanwhile, I actually have a few options here. 1265 00:52:52,616 --> 00:52:54,616 So I could do something like another Boolean 1266 00:52:54,616 --> 00:52:57,006 and I could rename gender to be female 1267 00:52:57,006 --> 00:52:58,696 and then it can just be true or false 1268 00:52:58,696 --> 00:53:00,426 or could be male and be false or true. 1269 00:53:00,606 --> 00:53:02,726 I could do something like an int and just assume 1270 00:53:02,726 --> 00:53:06,436 that 0 is female, 1 is male, I could do a string 1271 00:53:06,436 --> 00:53:10,056 and actually store M or F, I could store male or female. 1272 00:53:10,316 --> 00:53:11,936 Frankly, there's so many different ways. 1273 00:53:11,966 --> 00:53:15,346 Let's go ahead here and let's just leave it as, let's say, 1274 00:53:15,346 --> 00:53:17,666 let's just do 255 again 'cause we won't think 1275 00:53:17,666 --> 00:53:19,536 about it too hard here but it's gonna be a string. 1276 00:53:19,536 --> 00:53:21,546 We'll store male or female or something like that 1277 00:53:21,676 --> 00:53:23,076 but it might not be the best decision 1278 00:53:23,166 --> 00:53:24,446 but it will get the job done for now. 1279 00:53:24,676 --> 00:53:27,106 And then dorm, this probably should be a VARCHAR 1280 00:53:27,106 --> 00:53:28,466 and we'll say 255. 1281 00:53:28,466 --> 00:53:32,216 But again, we're not using 255 bytes necessarily. 1282 00:53:32,436 --> 00:53:33,956 It will use a variable number. 1283 00:53:33,956 --> 00:53:35,316 This is just an upper bound. 1284 00:53:35,516 --> 00:53:37,106 Now finally if I scroll over here, 1285 00:53:37,106 --> 00:53:38,356 you're asked a few more questions 1286 00:53:38,356 --> 00:53:39,796 which eventually become relevant. 1287 00:53:39,966 --> 00:53:42,016 Do you want this thing to have a default value? 1288 00:53:42,076 --> 00:53:43,806 For instance, do you want it to be null, 1289 00:53:43,806 --> 00:53:46,616 do you want everybody's default name to be John Harvard? 1290 00:53:46,616 --> 00:53:49,136 You could do that at the database level by typing 1291 00:53:49,136 --> 00:53:51,976 into this field but for now I'm just gonna go ahead 1292 00:53:51,976 --> 00:53:53,726 and click save. 1293 00:53:53,816 --> 00:53:56,996 And now notice I'm returned to this tab here. 1294 00:53:56,996 --> 00:53:58,936 This is the so-called structure tab 1295 00:53:59,176 --> 00:54:01,356 and now you just see a little reminder of all 1296 00:54:01,356 --> 00:54:03,816 of the fields you just created, their default types 1297 00:54:03,816 --> 00:54:06,156 and then only because MySQL was originally written 1298 00:54:06,156 --> 00:54:09,056 by some Swedes, the default coalition is-- 1299 00:54:09,206 --> 00:54:11,716 refers to Swedish, it's not a problem. 1300 00:54:11,716 --> 00:54:15,386 You can fit all the American characters inside 1301 00:54:15,386 --> 00:54:16,806 of the same encoding scheme. 1302 00:54:16,806 --> 00:54:19,146 So it's not a bug, it's a feature. 1303 00:54:19,176 --> 00:54:21,446 They wrote it, they get to decide the default encoding. 1304 00:54:21,646 --> 00:54:22,776 So what's now the takeaway? 1305 00:54:22,776 --> 00:54:25,956 Well let me go back to froshims8 and register8. 1306 00:54:26,386 --> 00:54:29,226 Notice now I have the following code and I'll just tease you 1307 00:54:29,226 --> 00:54:31,256 with some of it first then we'll look at more detail. 1308 00:54:31,636 --> 00:54:33,196 It turns out there's a function called 1309 00:54:33,256 --> 00:54:36,036 "mysql_connect" that's using my very public user name 1310 00:54:36,036 --> 00:54:36,856 and password now. 1311 00:54:37,146 --> 00:54:39,736 I then have a function called "mysql_select_database" 1312 00:54:39,786 --> 00:54:41,766 because there's gonna be hundreds of databases 1313 00:54:41,766 --> 00:54:45,146 on this server, I wanna select just mine called Malan_Lecture 1314 00:54:45,536 --> 00:54:47,766 then there's gonna be some code down here where I'm going 1315 00:54:47,766 --> 00:54:49,666 to scrub the user's input. 1316 00:54:49,826 --> 00:54:52,206 It turns out there's a lot of bad things people can do 1317 00:54:52,206 --> 00:54:54,376 by knowing this language we're about to look 1318 00:54:54,376 --> 00:54:57,796 at called SQL whereby they can log into your website, 1319 00:54:57,796 --> 00:54:59,966 they can delete your data if they know what they're doing. 1320 00:55:00,216 --> 00:55:01,936 But the real magic boils down to this. 1321 00:55:02,456 --> 00:55:03,636 Instead of sending an email, 1322 00:55:03,956 --> 00:55:06,986 I'm ultimately gonna call a function called mysql_query 1323 00:55:07,256 --> 00:55:09,806 whose purpose in life is to take a query which will right 1324 00:55:09,806 --> 00:55:12,446 in a moment store that data not in an email 1325 00:55:12,446 --> 00:55:14,026 but into that database. 1326 00:55:14,026 --> 00:55:16,366 So now, if I've done all this correctly, 1327 00:55:16,616 --> 00:55:21,506 I can visit froshims8.php, I can say David Malan 1328 00:55:21,686 --> 00:55:25,526 and will be a captain, gender and we'll say Matthew's 1329 00:55:25,596 --> 00:55:29,976 and click register and it says you are registered really, 1330 00:55:30,156 --> 00:55:30,896 that's means nothing. 1331 00:55:31,226 --> 00:55:32,866 So now let me go back to my database 1332 00:55:33,506 --> 00:55:34,576 which the proctor could do 1333 00:55:34,576 --> 00:55:37,056 or frankly I probably make a more user-friendly interphase 1334 00:55:37,056 --> 00:55:39,296 with proctor, I being the programmer don't mind so much. 1335 00:55:39,326 --> 00:55:44,406 I'm gonna click browse and, wow, I now have stored in my table, 1336 00:55:44,466 --> 00:55:46,166 my spreadsheet, now this record, 1337 00:55:46,206 --> 00:55:48,206 which means now I can do anything I want with this data, 1338 00:55:48,206 --> 00:55:51,216 I can email it out later, I can render it on a website, 1339 00:55:51,496 --> 00:55:59,906 I can search it, sort it, more on that after a 5-minute break. 1340 00:56:00,386 --> 00:56:02,346 Alright, so we are back. 1341 00:56:02,346 --> 00:56:04,456 That was enough time for me to fix my bug. 1342 00:56:04,456 --> 00:56:07,106 I forgot how to compute percents so 1343 00:56:07,376 --> 00:56:08,776 and I also forgot how to sort. 1344 00:56:09,176 --> 00:56:11,226 So both bugs had been fixed much 1345 00:56:11,376 --> 00:56:14,656 to my disappointment though thankfully Ben, Joseph, 1346 00:56:14,656 --> 00:56:17,256 and Brook [phonetic] have pulled behind me in the leadings. 1347 00:56:17,606 --> 00:56:22,166 I am now back at 0 percent, rank number 15 here since my stock, 1348 00:56:22,166 --> 00:56:25,646 my penny stocks have probably gone back up but Michael 1349 00:56:25,646 --> 00:56:27,336 and Zack [phonetic] are doing pretty well. 1350 00:56:27,336 --> 00:56:30,326 They are now up 200 and 100 percent respectively, 1351 00:56:30,616 --> 00:56:32,216 so good luck. 1352 00:56:32,216 --> 00:56:34,696 Inevitably, this turns out to be not so much. 1353 00:56:34,696 --> 00:56:37,336 He was really good in investing at Harvard but who's really good 1354 00:56:37,336 --> 00:56:38,816 about leveraging certain weaknesses 1355 00:56:38,816 --> 00:56:42,806 in the big board namely that one comes to mind, not to spoil. 1356 00:56:42,976 --> 00:56:43,716 We'll spoil this. 1357 00:56:44,086 --> 00:56:46,026 We'll give you guys the edge and for those not here, 1358 00:56:46,026 --> 00:56:46,806 they won't know this trick. 1359 00:56:47,296 --> 00:56:50,266 So it turns out that if stock quotes are not realtime, 1360 00:56:51,136 --> 00:56:53,506 and there are something like Yahoo! 1361 00:56:53,506 --> 00:56:57,716 Finance, but other stock quotes are realtime unlike Bloomberg TV 1362 00:56:57,716 --> 00:56:59,886 or CNN or your own E-Trade account, 1363 00:57:00,186 --> 00:57:02,026 turns out that you can effectively see 1364 00:57:02,026 --> 00:57:03,836 into the future by about 15 minutes. 1365 00:57:04,386 --> 00:57:07,096 So if you are in fact watching certain penny stocks 1366 00:57:08,616 --> 00:57:12,586 and realize, wow, that stock just shut 1367 00:57:12,586 --> 00:57:16,096 up on my real E-Trade account, still have about 15 minutes 1368 00:57:16,096 --> 00:57:17,776 to scoop up as many shares as you can 1369 00:57:18,126 --> 00:57:21,116 on the CS50 finance version of it. 1370 00:57:21,116 --> 00:57:23,606 Also too, with a lot of these penny stocks, 1371 00:57:23,606 --> 00:57:25,056 actually I don't mind just divulging this 1372 00:57:25,056 --> 00:57:26,906 because inevitably every semester, there is some student 1373 00:57:26,906 --> 00:57:28,616 who thinks here she's really being clever 1374 00:57:28,616 --> 00:57:30,926 in gaming the system when really we're not just telling you 1375 00:57:30,926 --> 00:57:31,706 about these weaknesses. 1376 00:57:31,706 --> 00:57:32,676 And now I pull the disclosure. 1377 00:57:32,676 --> 00:57:35,296 Let's see if we can really push the maximum amount 1378 00:57:35,296 --> 00:57:37,556 of money earned in three weeks' time up. 1379 00:57:37,626 --> 00:57:39,416 The other weakness of course is if you're buying 1380 00:57:39,416 --> 00:57:44,006 like 10,000 shares or 100,000 shares of some penny stock 1381 00:57:44,006 --> 00:57:46,496 in our simulator here, probably in the real world, 1382 00:57:46,556 --> 00:57:48,836 you yourself are gonna drive the price way up 1383 00:57:48,966 --> 00:57:50,006 and so you're not gonna actually get 1384 00:57:50,006 --> 00:57:51,276 that penny stock for a penny. 1385 00:57:51,326 --> 00:57:53,466 So realize that there-- you gotta take some of these 1386 00:57:53,466 --> 00:57:56,386 with a grain of salt but what's neat is you can actually see 1387 00:57:56,386 --> 00:57:57,466 what each other are doing. 1388 00:57:57,466 --> 00:57:59,046 If you'd like to learn just how good they are 1389 00:57:59,046 --> 00:58:00,426 or just how clever they're being. 1390 00:58:00,786 --> 00:58:04,156 For instance Michael has really been an active day trader here 1391 00:58:04,156 --> 00:58:07,266 in the one day this is available playing with our-- 1392 00:58:07,266 --> 00:58:10,806 actually not some terribly cheap stocks. 1393 00:58:10,896 --> 00:58:14,126 So perhaps he has some ability to see into the future. 1394 00:58:14,126 --> 00:58:17,656 I just went with one penny stock at 41 cents there. 1395 00:58:17,656 --> 00:58:18,516 I'm gonna hang on to it. 1396 00:58:18,516 --> 00:58:21,776 I'm a long term investor with these penny stocks. 1397 00:58:22,006 --> 00:58:23,166 [Laughter] So in any case, 1398 00:58:23,166 --> 00:58:26,106 how do we actually now start storing this data just 1399 00:58:26,106 --> 00:58:27,776 like the data you're seeing now on the big board 1400 00:58:27,976 --> 00:58:29,266 into an actual database. 1401 00:58:29,266 --> 00:58:31,256 Well it turns out the magic there derives 1402 00:58:31,256 --> 00:58:33,996 from a language called SQL, Structured Query Language. 1403 00:58:34,306 --> 00:58:36,936 This is not so much a programming language 1404 00:58:36,936 --> 00:58:38,426 as it is as the cue denotes. 1405 00:58:38,676 --> 00:58:41,256 A query language whereby if you have a database 1406 00:58:41,256 --> 00:58:44,286 and you wanna grab data from that database, you need some way 1407 00:58:44,286 --> 00:58:46,016 of expressing it and it turns 1408 00:58:46,016 --> 00:58:49,126 out you can do most database manipulations 1409 00:58:49,126 --> 00:58:50,996 with just four basic commands. 1410 00:58:50,996 --> 00:58:53,176 One is Insert and we actually used that already 1411 00:58:53,176 --> 00:58:55,876 and we'll pull back that layer in a moment of my code. 1412 00:58:56,106 --> 00:58:58,466 Select if you wanna grab data from the database. 1413 00:58:58,546 --> 00:59:00,176 Update if you just wanna tweet something. 1414 00:59:00,426 --> 00:59:02,456 And Delete if you wanna delete from the database. 1415 00:59:02,456 --> 00:59:04,376 And there are a bunch of other statements 1416 00:59:04,376 --> 00:59:07,096 that you can actually get in SQL but these are probably 1417 00:59:07,096 --> 00:59:10,046 by far the most common and certainly the most useful 1418 00:59:10,046 --> 00:59:13,296 to learn right up at-- right at from the get-go. 1419 00:59:13,556 --> 00:59:15,086 So let's go ahead and take a look here. 1420 00:59:15,086 --> 00:59:18,716 So if I go back into this very last froshims example, 1421 00:59:19,056 --> 00:59:21,936 you will see in froshims-- 1422 00:59:22,176 --> 00:59:25,006 in register8 that I did the following. 1423 00:59:25,086 --> 00:59:27,736 At the very top of the file, first I have my sanity check. 1424 00:59:27,846 --> 00:59:30,526 If name is blank or gender is blank or dorm is blank, 1425 00:59:30,796 --> 00:59:33,136 redirect the user to this location which is 1426 00:59:33,136 --> 00:59:35,676 that long URL just 'cause I put a lot of subdirectories there 1427 00:59:35,946 --> 00:59:37,776 but in other words get them out of here, like send them back 1428 00:59:37,776 --> 00:59:39,456 to the form and let them resubmit. 1429 00:59:39,666 --> 00:59:41,056 This isn't the most user friendly form. 1430 00:59:41,056 --> 00:59:41,976 There's no feedback here. 1431 00:59:41,976 --> 00:59:43,836 So realize each of these examples should be looked 1432 00:59:43,926 --> 00:59:44,716 in isolation. 1433 00:59:44,966 --> 00:59:46,966 Sometimes we have read texting, there's an error, 1434 00:59:46,966 --> 00:59:47,956 sometimes we don't bother. 1435 00:59:48,216 --> 00:59:50,986 Each of these examples is meant to illustrate per the comments 1436 00:59:50,986 --> 00:59:52,426 to top each a different point. 1437 00:59:52,656 --> 00:59:55,526 But let's supposed that we passed the validation. 1438 00:59:55,526 --> 00:59:58,246 In other words the user has not left any of those fields blank 1439 00:59:58,536 --> 01:00:00,256 so we don't execute this branch 1440 01:00:00,256 --> 01:00:01,826 and so we reach this line of code. 1441 01:00:02,066 --> 01:00:03,666 >> It turns out that if you wanna connect 1442 01:00:03,666 --> 01:00:07,676 to a MySQL database in PHP code, it's very simple and realize 1443 01:00:07,676 --> 01:00:09,736 that MySQL is not at all tied to PHP. 1444 01:00:09,736 --> 01:00:12,386 You can connect to it in Java, in C, in C plus plus, 1445 01:00:12,386 --> 01:00:15,636 in C sharp, really any of your favorite languages you can use 1446 01:00:15,906 --> 01:00:17,686 to connect to this type of database. 1447 01:00:17,686 --> 01:00:18,546 And so that's nice. 1448 01:00:18,546 --> 01:00:20,846 We're really not tying our hands with one language here. 1449 01:00:21,216 --> 01:00:22,696 So how do you connect to a database? 1450 01:00:23,336 --> 01:00:24,906 Well, I read the manual and found 1451 01:00:24,906 --> 01:00:26,656 that there's a function called mysql_connect 1452 01:00:26,656 --> 01:00:27,886 and it takes three arguments. 1453 01:00:28,026 --> 01:00:32,466 One, the IP address or the domain name of the server 1454 01:00:32,466 --> 01:00:34,986 to which you want to connect, as you'll see in the problems set 1455 01:00:34,986 --> 01:00:39,096 and in your distribution code, mysql.local domain is the made 1456 01:00:39,096 --> 01:00:42,156 up domain name that we created for our database server. 1457 01:00:42,386 --> 01:00:44,986 And I say made up because we don't want this database server 1458 01:00:44,986 --> 01:00:46,606 out there in the internet for other people 1459 01:00:46,606 --> 01:00:48,066 to connect to and interact with. 1460 01:00:48,066 --> 01:00:50,796 We want it just to be private to us on the cloud so we came 1461 01:00:50,796 --> 01:00:53,416 out with this local domain moniker instead 1462 01:00:53,416 --> 01:00:55,116 of using .com or .edu. 1463 01:00:55,116 --> 01:00:56,716 It's only accessible within the Cloud. 1464 01:00:57,046 --> 01:00:59,126 Now it takes my user name as my second argument. 1465 01:00:59,386 --> 01:01:03,156 My password as my third argument and then I now have a connection 1466 01:01:03,156 --> 01:01:05,296 to that database assuming everything was correct 1467 01:01:05,296 --> 01:01:08,296 and so now I have to select the specific database because again, 1468 01:01:08,296 --> 01:01:11,146 there's like 500 databases on this server. 1469 01:01:11,276 --> 01:01:13,116 I wanna choose specifically my own 1470 01:01:13,116 --> 01:01:14,826 which in this case it's called Malan_Lecture. 1471 01:01:15,076 --> 01:01:17,796 Yours again will be called JHarvard_pset7 1472 01:01:17,976 --> 01:01:18,716 or something like that. 1473 01:01:19,206 --> 01:01:21,576 Now notice this and I've comment to the codes 1474 01:01:21,576 --> 01:01:22,596 to make clear what's going on. 1475 01:01:22,596 --> 01:01:25,006 There're not many lines of codes required to get data 1476 01:01:25,006 --> 01:01:27,486 into a database, pretty much the same number as everybody 1477 01:01:27,486 --> 01:01:28,496 as required to make an email. 1478 01:01:29,016 --> 01:01:30,186 So scrub inputs. 1479 01:01:30,186 --> 01:01:34,036 So this is actually a good habit to get in to very early on. 1480 01:01:34,036 --> 01:01:36,236 There is what's known in the world something called a 1481 01:01:36,236 --> 01:01:37,396 "SQL injection attack." 1482 01:01:37,946 --> 01:01:39,206 This essentially is an attack 1483 01:01:39,576 --> 01:01:42,616 where by a sufficiently clever adversary goes to your web page 1484 01:01:42,616 --> 01:01:45,936 which has some kind of HTML form and instead of typing in David 1485 01:01:45,936 --> 01:01:50,416 to the form and instead of typing in any expected text 1486 01:01:50,606 --> 01:01:53,436 into that form, instead this adversary starts tossing 1487 01:01:53,436 --> 01:01:55,266 in weird characters like maybe some quotes, 1488 01:01:55,266 --> 01:01:58,796 maybe some semicolons, maybe the keyword delete. 1489 01:01:58,796 --> 01:02:00,996 The whole idea of being they're trying 1490 01:02:00,996 --> 01:02:04,446 to insert dangerous commands into your database 1491 01:02:04,446 --> 01:02:06,866 without you realizing it so that you might be trick 1492 01:02:06,866 --> 01:02:08,076 into executing this code. 1493 01:02:08,276 --> 01:02:10,856 We'll talk more about this in due time perhaps. 1494 01:02:11,106 --> 01:02:15,886 But for now, know that anytime you insert data into a database 1495 01:02:15,886 --> 01:02:17,476 that was handed to you by a user, 1496 01:02:17,726 --> 01:02:19,886 you should call this idiotically named function. 1497 01:02:20,376 --> 01:02:25,656 Frankly, mysql_real_escape_string, 1498 01:02:26,016 --> 01:02:27,746 so 0 point for style there, frankly. 1499 01:02:28,026 --> 01:02:30,746 But that's what we're stock with. 1500 01:02:30,746 --> 01:02:32,916 That function's purpose in life is essentially 1501 01:02:32,916 --> 01:02:35,666 to put backslashes in front of any of those scary characters 1502 01:02:35,696 --> 01:02:37,396 like semicolons and quotes, they're just 1503 01:02:37,396 --> 01:02:39,956 in general had caused us a little bit of concern 1504 01:02:39,956 --> 01:02:41,796 because they're used for programming syntax. 1505 01:02:42,066 --> 01:02:43,456 So for now, realize what I'm doing. 1506 01:02:44,026 --> 01:02:46,116 I'm declaring a variable called dollar sign name. 1507 01:02:46,526 --> 01:02:49,676 I am storing and ultimately, whatever the user types in, 1508 01:02:49,676 --> 01:02:51,866 the value of name and that's super global, 1509 01:02:51,866 --> 01:02:54,736 but I'm first escaping it with mysql_real_escape_string. 1510 01:02:55,086 --> 01:02:56,336 Now notice what I'm doing next. 1511 01:02:56,586 --> 01:02:58,706 It turns out POST for captain, 1512 01:02:58,976 --> 01:03:01,196 recall what's submitted for captain. 1513 01:03:01,296 --> 01:03:02,376 We saw this last week. 1514 01:03:02,636 --> 01:03:06,246 If you checked that box, the value of ON, O-N is submitted. 1515 01:03:06,246 --> 01:03:08,296 And if you don't check that box, nothing is submitted. 1516 01:03:08,586 --> 01:03:10,676 So my little trick here is to just treat 1517 01:03:10,676 --> 01:03:12,216 that kind of as Boolean value. 1518 01:03:12,576 --> 01:03:16,796 If the captain field and the super global evaluates the true 1519 01:03:16,886 --> 01:03:19,266 and it will if there's anything there. 1520 01:03:19,266 --> 01:03:22,286 So remember there's a lot of implicit casting that's possible 1521 01:03:22,286 --> 01:03:26,416 in programing whereby anything non-zero is essentially true, 1522 01:03:26,416 --> 01:03:28,006 so I'm leveraging that understanding. 1523 01:03:28,156 --> 01:03:31,776 And I'm saying if the captain field is anything other 1524 01:03:31,776 --> 01:03:34,996 than false anything other than blank, then I'm gonna assumed 1525 01:03:34,996 --> 01:03:36,146 that the user check that box 1526 01:03:36,226 --> 01:03:39,086 and I'm gonna set a local variable called captain equal 1527 01:03:39,086 --> 01:03:39,646 to 1. 1528 01:03:39,996 --> 01:03:42,736 Else, I'm going to say it captain equal to 0. 1529 01:03:42,916 --> 01:03:45,766 Now here's a curiosity about PHP too and it kind 1530 01:03:45,826 --> 01:03:47,996 of gets a bad wrap for being a little too loose 1531 01:03:47,996 --> 01:03:48,946 with some of these details. 1532 01:03:49,286 --> 01:03:52,486 You do not need to declare variables in PHP. 1533 01:03:52,486 --> 01:03:55,076 Notice, I am just on the fly whenever the heck I want 1534 01:03:55,076 --> 01:03:57,796 declaring variables, dollar sign name, dollar sign captain. 1535 01:03:58,016 --> 01:03:59,656 In fact, in the context of C, 1536 01:03:59,656 --> 01:04:01,436 this would be a big no, no, right? 1537 01:04:01,436 --> 01:04:04,866 This is essentially-- this variable is scoped here 1538 01:04:04,866 --> 01:04:06,566 and you can use curly braces in PHP. 1539 01:04:06,656 --> 01:04:09,126 But like C, if you only have one line of code it doesn't matter. 1540 01:04:09,396 --> 01:04:12,326 In C, I think even on quiz 0, this got us into trouble 1541 01:04:12,546 --> 01:04:14,956 because these variables were scoped too tightly. 1542 01:04:15,306 --> 01:04:18,806 In PHP, once you declare a variable you're stock with it. 1543 01:04:18,806 --> 01:04:22,616 It now exists everywhere in that file even inside 1544 01:04:22,746 --> 01:04:25,366 of curly braces and outside of them. 1545 01:04:25,716 --> 01:04:27,496 So on the one hand, this is kind of useful 1546 01:04:27,496 --> 01:04:30,056 because it can let you, the programmer, be a little more lax 1547 01:04:30,276 --> 01:04:32,136 when it comes to the structuring of your code 1548 01:04:32,396 --> 01:04:34,766 but it can also very quickly lead to bad habit. 1549 01:04:34,766 --> 01:04:37,576 So realize here, it feels okay to be doing what I'm doing 1550 01:04:37,576 --> 01:04:40,856 because I'm always initializing captain to 1 or 0 1551 01:04:41,116 --> 01:04:43,606 but even I have got corners in the past where recall 1552 01:04:43,606 --> 01:04:45,226 from a previous example I set 1553 01:04:45,226 --> 01:04:48,956 that variable called dollar sign error and I set it to true 1554 01:04:49,116 --> 01:04:50,066 but nowhere in my code 1555 01:04:50,066 --> 01:04:51,676 that I ever explicitly said it's a false. 1556 01:04:51,886 --> 01:04:53,576 I just assumed that if I don't set it 1557 01:04:53,576 --> 01:04:55,246 to true, it would be false. 1558 01:04:55,246 --> 01:04:57,756 But again this is really just a different programming paradigm. 1559 01:04:57,866 --> 01:05:00,486 It's a language like PHP people do tend 1560 01:05:00,486 --> 01:05:02,066 to take these liberties whereas something 1561 01:05:02,066 --> 01:05:04,836 like C is much more anal about how you have to write your code. 1562 01:05:05,126 --> 01:05:08,426 So it's a good thing and a bad thing so long as you start 1563 01:05:08,426 --> 01:05:10,446 to not abuse some of these features 1564 01:05:10,446 --> 01:05:12,076 by just declaring things all over the place. 1565 01:05:12,076 --> 01:05:13,936 But here, I proceed to declare gender. 1566 01:05:14,246 --> 01:05:17,566 I'm storing the value of the escape version of gender 1567 01:05:17,566 --> 01:05:19,316 in that variable and same with dorm. 1568 01:05:19,316 --> 01:05:21,106 So in short, with those several lines of code, 1569 01:05:21,306 --> 01:05:24,166 I just wanted four new variables, name, captain, 1570 01:05:24,166 --> 01:05:27,136 gender, dorm that stored the same thing that the user typed 1571 01:05:27,136 --> 01:05:29,336 in but the escape versions of them. 1572 01:05:29,336 --> 01:05:32,546 Just so I don't accidentally delete my data by being tricked 1573 01:05:32,816 --> 01:05:36,216 into registering delete Malan and not David Malan. 1574 01:05:36,426 --> 01:05:38,456 So now I prepared the query. 1575 01:05:38,456 --> 01:05:39,526 There's different ways to do this. 1576 01:05:39,926 --> 01:05:41,216 But notice what I've done here. 1577 01:05:41,516 --> 01:05:44,186 Ultimately, I need to execute a query like this. 1578 01:05:44,406 --> 01:05:47,106 INSERT INTO, the name of the table. 1579 01:05:47,376 --> 01:05:50,476 Then in parenthesis, I specify the comma-- 1580 01:05:50,476 --> 01:05:53,216 a comma separated list of the fields that I want 1581 01:05:53,216 --> 01:05:54,396 to insert values into. 1582 01:05:54,396 --> 01:05:57,896 What's nice is with the database table, you can have 20 fields 1583 01:05:58,126 --> 01:06:00,086 and you don't have to fill all of them out. 1584 01:06:00,086 --> 01:06:02,056 It might be reasonable for some fields to be blank. 1585 01:06:02,116 --> 01:06:05,386 Maybe someone doesn't have a website, and so the URL 1586 01:06:05,386 --> 01:06:07,016 of their homepage should be blank. 1587 01:06:07,016 --> 01:06:08,776 Maybe they don't wanna give you their email address 1588 01:06:09,046 --> 01:06:10,696 so maybe you don't wanna fill in that field. 1589 01:06:10,926 --> 01:06:14,036 So with-- by parenthesizing this list of field names, 1590 01:06:14,036 --> 01:06:17,566 you can say, "I only wanna insert a row into my table 1591 01:06:18,006 --> 01:06:19,246 for the specific fields." 1592 01:06:19,246 --> 01:06:21,156 In this case, it's of course all four of them 1593 01:06:21,426 --> 01:06:22,386 but it doesn't have to be. 1594 01:06:22,696 --> 01:06:24,376 Now what values do we wanna put in there? 1595 01:06:25,016 --> 01:06:27,796 Well notice here, this wrap onto two lines and that's okay. 1596 01:06:27,796 --> 01:06:32,226 I just move the second down the below and that's fine in PHP. 1597 01:06:32,226 --> 01:06:36,046 Notice I have now values, parenthesis, close parenthesis, 1598 01:06:36,046 --> 01:06:39,006 and then another comma separated list but you have to bear 1599 01:06:39,006 --> 01:06:41,066 in mind and this is one of the most common sort of gotchas 1600 01:06:41,126 --> 01:06:42,646 in office hours and in these psets, 1601 01:06:43,036 --> 01:06:45,346 you realize that anytime you have a string 1602 01:06:45,346 --> 01:06:47,226 in PHP, you must quote it. 1603 01:06:47,356 --> 01:06:49,666 Now you can use double quotes, you can use single quotes 1604 01:06:49,666 --> 01:06:50,736 so long as you're consistent. 1605 01:06:50,966 --> 01:06:53,816 I use single quotes here but notice I put single quotes 1606 01:06:53,816 --> 01:06:56,826 around name, around gender, and around dorm but not 1607 01:06:56,826 --> 01:06:59,976 around captain because captain I decided would be an integer 1608 01:07:00,086 --> 01:07:01,656 so it doesn't need to have them there. 1609 01:07:01,996 --> 01:07:04,746 So at the end of the day, the string that I've just stored 1610 01:07:04,806 --> 01:07:08,456 in a variable called SQL looks a little something like this. 1611 01:07:08,716 --> 01:07:18,316 Insert into registrants the name, captain, gender, dorm, 1612 01:07:18,886 --> 01:07:24,446 values, "David Malan" captain I think I said-- 1613 01:07:24,706 --> 01:07:29,276 well, I think I sent an M and then dorm was Mathews. 1614 01:07:29,476 --> 01:07:32,816 So this is the string that I've just constructed dynamically 1615 01:07:33,096 --> 01:07:37,156 by way of using these variables and these placeholder, 1616 01:07:37,156 --> 01:07:38,996 these variables inside of this bigger string. 1617 01:07:39,216 --> 01:07:41,286 So the magic then happens with this one line of code. 1618 01:07:41,466 --> 01:07:44,256 I've now constructed what's called a SQL statement, 1619 01:07:44,256 --> 01:07:46,456 a SQL query, that's the insert statement. 1620 01:07:46,756 --> 01:07:50,436 I then past it to the function called my SQL query whose 1621 01:07:50,436 --> 01:07:52,356 purpose in life because I've already connected 1622 01:07:52,356 --> 01:07:54,346 to the database, I've already selected my database, 1623 01:07:54,346 --> 01:07:57,436 all that happened before is now to execute that query 1624 01:07:57,436 --> 01:08:01,016 against the database and so the reason that this row ended 1625 01:08:01,016 --> 01:08:02,876 up in my table a moment ago was 1626 01:08:02,906 --> 01:08:05,696 because that insert statement just got executed. 1627 01:08:05,946 --> 01:08:07,786 In fact, I can simulate this myself. 1628 01:08:07,916 --> 01:08:10,816 Rather than go through the web, let me actually show you 1629 01:08:10,816 --> 01:08:13,046 that this thing is in fact doing what I say. 1630 01:08:13,276 --> 01:08:16,216 I'm gonna go to PHP my admin, just this little tool. 1631 01:08:16,216 --> 01:08:17,476 We've seen the structure tab. 1632 01:08:17,566 --> 01:08:19,466 That just reminds me what this thing looks like. 1633 01:08:19,706 --> 01:08:20,736 We've seen the browse tab. 1634 01:08:20,736 --> 01:08:22,086 That shows me what's inside there. 1635 01:08:22,366 --> 01:08:24,556 I can actually interact with SQL directly. 1636 01:08:24,556 --> 01:08:28,606 If I click the SQL tab, notice I just get a big text area 1637 01:08:28,906 --> 01:08:31,356 that I can type any commands into that I want and here too, 1638 01:08:31,356 --> 01:08:33,216 this is why it's a wonderfully useful learning tool 1639 01:08:33,456 --> 01:08:35,956 because you can just play and it doesn't really matter especially 1640 01:08:35,986 --> 01:08:38,586 when you have no data to lose, if you get something wrong. 1641 01:08:38,816 --> 01:08:41,236 So I'm gonna try pasting this in and instead 1642 01:08:41,236 --> 01:08:42,346 of registering myself, 1643 01:08:42,586 --> 01:08:45,006 I'll register Jan Sue [phonetic] this time. 1644 01:08:45,006 --> 01:08:48,346 I'll change this to female, this to Eliot 1645 01:08:48,346 --> 01:08:53,716 and then let me go back here and click go and now it says up top, 1646 01:08:53,716 --> 01:08:56,496 one row inserted, so let's see if that's true. 1647 01:08:56,496 --> 01:08:59,116 Click Browse, Zoom Out and sure enough, 1648 01:08:59,206 --> 01:09:00,886 now I have two rows in this table. 1649 01:09:01,106 --> 01:09:02,866 Now, suppose, I want to get all those users back, 1650 01:09:03,456 --> 01:09:04,766 come to the question just for a moment. 1651 01:09:05,046 --> 01:09:07,066 Now I want them all back, I'm gonna actually go 1652 01:09:07,066 --> 01:09:11,096 to another piece of code I wrote here called registrants dot PHP 1653 01:09:11,096 --> 01:09:14,086 and now I dynamically generated a webpage 1654 01:09:14,086 --> 01:09:16,966 that executed instantaneously that does not have David 1655 01:09:16,966 --> 01:09:19,346 or Jan Sue hard coded into it but it's apparently 1656 01:09:19,346 --> 01:09:22,286 out putting a bulleted list by way of a select query 1657 01:09:22,386 --> 01:09:23,386 which we'll see in just a second. 1658 01:09:23,596 --> 01:09:23,686 Yeah. 1659 01:09:24,516 --> 01:09:33,776 [ Inaudible Remark ] 1660 01:09:34,276 --> 01:09:36,516 >> Very similar, yes. 1661 01:09:36,696 --> 01:09:38,566 So in C, you can use sprintf. 1662 01:09:38,566 --> 01:09:40,706 That actually exists in PHP as well. 1663 01:09:40,926 --> 01:09:43,396 There is many, many ways to construct the string on the fly 1664 01:09:43,646 --> 01:09:45,906 in PHP and just plugging in these variables 1665 01:09:45,906 --> 01:09:49,356 as I've done here is legitimate in PHP and frankly, 1666 01:09:49,586 --> 01:09:51,236 it's arguably a little simpler 1667 01:09:51,236 --> 01:09:54,466 than having use those percent S placeholders everywhere. 1668 01:09:55,336 --> 01:09:57,106 So let me draw our attention then to this. 1669 01:09:57,506 --> 01:10:00,496 So this might be for instance the PHP page that I give 1670 01:10:00,536 --> 01:10:02,796 to the proctor when it comes time for him or her 1671 01:10:02,796 --> 01:10:05,456 to see who's registered for some Spork at the top 1672 01:10:05,456 --> 01:10:07,536 of this page, registrants dot PHP. 1673 01:10:07,706 --> 01:10:09,596 Notice that I connect to the database again 1674 01:10:09,596 --> 01:10:11,036 with my username, with my password. 1675 01:10:11,216 --> 01:10:14,106 I select the same database and then I create this query, 1676 01:10:14,416 --> 01:10:16,956 select star where star means everything, 1677 01:10:16,956 --> 01:10:19,216 give me all of the rows from registrants. 1678 01:10:19,506 --> 01:10:22,616 Now I execute this query but this time because I'm asking 1679 01:10:22,616 --> 01:10:25,126 for data, I have to remember the return value. 1680 01:10:25,126 --> 01:10:27,816 I can't just call my SQL query and then call it a day. 1681 01:10:28,016 --> 01:10:30,556 I need to get back the server's answer so I store 1682 01:10:30,556 --> 01:10:32,116 in a variable a called result. 1683 01:10:32,396 --> 01:10:33,746 Now, let's fast forward. 1684 01:10:33,786 --> 01:10:37,966 I seem to be exiting PHP mode outputting a default webpage 1685 01:10:38,246 --> 01:10:41,726 but then notice this, what's really neat, I have this UL tag 1686 01:10:41,726 --> 01:10:44,426 which stands for Unordered List and if you look this 1687 01:10:44,426 --> 01:10:48,516 up in the manual, a UL tag has to have LI, list item tags, 1688 01:10:48,586 --> 01:10:49,976 inside of it and every one 1689 01:10:49,976 --> 01:10:51,976 of those list item tags becomes a bullet. 1690 01:10:52,206 --> 01:10:54,936 And so what I'm doing here is outputting one or more bullets 1691 01:10:55,316 --> 01:10:57,926 so how am I iterating over the results and here is 1692 01:10:57,926 --> 01:11:00,266 where the really neat feature is of this prog-- 1693 01:11:00,266 --> 01:11:02,286 of this being able to program against the database. 1694 01:11:02,676 --> 01:11:06,096 I can call a function called my SQL fetch array. 1695 01:11:06,526 --> 01:11:08,046 Where do I want to fetch an array from? 1696 01:11:08,276 --> 01:11:10,726 I specified dollars on results as the argument 1697 01:11:10,726 --> 01:11:13,426 and that says fetch them from the results I've just got 1698 01:11:13,426 --> 01:11:16,446 from the database on every iteration of this loop, 1699 01:11:16,576 --> 01:11:21,036 store that array in a variable called dollar sign row 1700 01:11:21,036 --> 01:11:23,096 because conceptually, when I say select star, 1701 01:11:23,096 --> 01:11:24,526 that means give me all the rows. 1702 01:11:24,776 --> 01:11:27,626 So when I iterate over each of these, I'm being handed 1703 01:11:27,626 --> 01:11:30,696 that row really nicely as an associative array. 1704 01:11:30,956 --> 01:11:34,576 So just these columns have names, name and dorm and gender 1705 01:11:34,576 --> 01:11:38,486 and captain, I can now get those values just 1706 01:11:38,486 --> 01:11:40,126 as though they were from an HTML form. 1707 01:11:40,126 --> 01:11:42,796 This time they're coming from a database by way of their names 1708 01:11:43,026 --> 01:11:45,946 and so this time, I'm gonna print a list item tag then I'm 1709 01:11:45,946 --> 01:11:48,896 gonna close it but inside of that, I'm gonna print 1710 01:11:48,896 --> 01:11:52,086 out dollar sign row "name" 1711 01:11:52,526 --> 01:11:55,256 and what that's gonna do is I'll put David Malan then Jan Sue 1712 01:11:55,256 --> 01:11:57,696 [inaudible] and then that's it for that loop. 1713 01:11:57,936 --> 01:12:01,246 And as an aside too to get us in the habit of best practices, 1714 01:12:01,246 --> 01:12:04,076 HTML special charge is a function that also takes care 1715 01:12:04,076 --> 01:12:05,726 of any dangerous characters so that 1716 01:12:05,726 --> 01:12:07,816 if a malicious user actually typed in something 1717 01:12:07,816 --> 01:12:11,616 like open bracket blink close bracket, they couldn't trick me 1718 01:12:11,826 --> 01:12:14,396 into outputting a webpage for this proctor where all 1719 01:12:14,396 --> 01:12:17,316 of the names are actually blinking by having entered, 1720 01:12:17,316 --> 01:12:19,526 again, a blink tag and not an actual name. 1721 01:12:19,526 --> 01:12:21,036 So we're really just scratching the surface 1722 01:12:21,036 --> 01:12:21,976 of all of these features. 1723 01:12:22,176 --> 01:12:24,506 On Wednesday, we'll introduce a language called Ajax-- 1724 01:12:24,506 --> 01:12:27,016 JavaScript and with that a technology called Ajax 1725 01:12:27,016 --> 01:12:29,716 with which all of today's modern sites are now leveraging. 1726 01:12:29,816 --> 01:12:34,156 We'll see you then. 1727 01:12:34,656 --> 01:12:37,540 [ Inaudible Remark ]