1 00:00:00,506 --> 00:00:10,546 [ Silence ] 2 00:00:11,046 --> 00:00:13,526 >> Alright everybody, welcome to the Walkthrough 3 00:00:13,596 --> 00:00:16,416 for our pset7: CS50 Finance. 4 00:00:16,746 --> 00:00:19,956 So now, we are beginning our transition from C 5 00:00:19,956 --> 00:00:22,096 and just working on the appliance and the terminal 6 00:00:22,096 --> 00:00:24,756 and writing C and compiling it into web applications 7 00:00:24,756 --> 00:00:26,536 which I think personally are much more exciting. 8 00:00:26,536 --> 00:00:28,036 And I've spent a lot of time writing these things. 9 00:00:28,496 --> 00:00:30,256 And so you're gonna be actually be able to run something 10 00:00:30,256 --> 00:00:32,316 in a web browser and show your friends and they won't have 11 00:00:32,316 --> 00:00:34,086 to download the appliance and that'll be awesome. 12 00:00:34,666 --> 00:00:37,176 So today's music was Basshunter, another classic. 13 00:00:37,876 --> 00:00:39,366 So today, we're going to being going 14 00:00:39,366 --> 00:00:40,976 through each part of this problem set. 15 00:00:40,976 --> 00:00:43,696 So we're gonna talk a lot about the background of web program 16 00:00:43,696 --> 00:00:45,506 in general since we haven't seen a lot of that yet, 17 00:00:46,106 --> 00:00:49,476 things like file permissions and what PHP in this mysql are 18 00:00:49,476 --> 00:00:51,426 and how you can use them, and then just go 19 00:00:51,426 --> 00:00:53,566 through each component of the problem set. 20 00:00:54,256 --> 00:00:57,416 So before you start, you wanna set up your appliance to be able 21 00:00:57,416 --> 00:01:00,056 to act as a server where a server is something 22 00:01:00,056 --> 00:01:03,336 that serves you websites whether they'd be HTML or PHP 23 00:01:03,396 --> 00:01:04,636 or whatever you have on inside 24 00:01:04,636 --> 00:01:07,656 of your server it's basically going to be able to display them 25 00:01:07,656 --> 00:01:11,696 to a user who access these items via URLs and their web browser. 26 00:01:12,026 --> 00:01:13,666 So in order to do this, the first thing we need 27 00:01:13,666 --> 00:01:15,666 to do is create some folder that's going 28 00:01:15,666 --> 00:01:17,146 to be the root of our server. 29 00:01:17,226 --> 00:01:20,756 So whenever I go to some URL, the server is gonna jump 30 00:01:20,756 --> 00:01:23,096 into this folder and start looking for content 31 00:01:23,096 --> 00:01:24,266 at the start of this folder. 32 00:01:24,736 --> 00:01:27,376 So this folder just happens to be called public_html 33 00:01:27,376 --> 00:01:30,986 and you're going to create that inside of your home directory. 34 00:01:31,296 --> 00:01:34,176 So if you say, remember from, you know, week one, this mkdir 35 00:01:34,376 --> 00:01:37,576 or make directory, you're going to create a new folder inside 36 00:01:37,576 --> 00:01:39,846 of your appliance called public HTML. 37 00:01:40,136 --> 00:01:43,006 And all of the web application code you write for this pset, 38 00:01:43,006 --> 00:01:44,966 the next pset and your final project is going 39 00:01:44,966 --> 00:01:46,836 to live inside of this folder. 40 00:01:47,926 --> 00:01:49,116 So after you create it, 41 00:01:49,336 --> 00:01:52,456 now that's where you wanna run this git command that's gonna 42 00:01:52,456 --> 00:01:54,716 download the distribution code which there's a lot 43 00:01:54,716 --> 00:01:56,566 but we're gonna go through it so it's not that scary. 44 00:01:56,786 --> 00:01:58,936 Because this is gonna pull down all of the starting code 45 00:01:58,936 --> 00:02:02,476 for your pset and make sure that you change directory 46 00:02:02,516 --> 00:02:04,786 into public HTML first so you don't pull 47 00:02:04,786 --> 00:02:06,286 down all this code inside 48 00:02:06,286 --> 00:02:08,016 of your home directory as you're used to. 49 00:02:08,126 --> 00:02:11,366 But make sure all of that gets downloaded into public HTML 50 00:02:11,566 --> 00:02:13,846 so that way you can access it from the web browser. 51 00:02:15,096 --> 00:02:16,756 So after you download anything, 52 00:02:16,836 --> 00:02:19,186 we need to change the permissions of everything. 53 00:02:19,476 --> 00:02:21,076 Oh, not everything but everything we just downloaded. 54 00:02:21,626 --> 00:02:23,626 So we have a new command called "chmod" 55 00:02:23,626 --> 00:02:24,786 that we may have seen before. 56 00:02:25,046 --> 00:02:27,656 But all chmod does is it's going to change the permissions 57 00:02:27,656 --> 00:02:29,996 of either a folder or a file. 58 00:02:29,996 --> 00:02:32,056 So if you wanted to make something executable 59 00:02:32,056 --> 00:02:34,236 for everyone like your home directory 60 00:02:34,236 --> 00:02:36,366 which is something you'll need to do, you're gonna say the word 61 00:02:36,366 --> 00:02:39,266 "chmod" so the command to invoke this permission changer, 62 00:02:39,556 --> 00:02:42,186 then this a + x. So what does that mean? 63 00:02:42,516 --> 00:02:46,496 So this A says I wanna operate on all users, so not just me 64 00:02:46,496 --> 00:02:48,656 or not just a certain group, I want everyone 65 00:02:49,106 --> 00:02:51,596 and I wanna add the executable permission. 66 00:02:51,926 --> 00:02:54,926 So that x for executable means that they can run programs 67 00:02:54,926 --> 00:02:57,286 or as we'll soon be doing, run this PHP files 68 00:02:57,336 --> 00:02:58,526 that can generate some output. 69 00:02:58,946 --> 00:03:01,046 And finally, the last one is just what we're changing. 70 00:03:01,306 --> 00:03:04,126 So this [inaudible] says I wanna change my home directory 71 00:03:04,126 --> 00:03:06,396 which is located in /home/jharvard. 72 00:03:07,826 --> 00:03:11,606 So if we wanted to, as the pset spec does change the permissions 73 00:03:11,606 --> 00:03:14,026 to make all of thesethree things executable do your home 74 00:03:14,026 --> 00:03:16,556 directory, public HTML, and pset7, 75 00:03:16,906 --> 00:03:18,636 all of these things have to be executable. 76 00:03:18,696 --> 00:03:20,886 So before you go anywhere, you're gonna need to say 77 00:03:20,886 --> 00:03:23,196 "chmod a + x" again, make it executable 78 00:03:23,196 --> 00:03:25,246 for everyone all three of these directories. 79 00:03:25,556 --> 00:03:27,686 You can specify as many as you want in a list and it's going 80 00:03:27,686 --> 00:03:29,716 to change all of those permissions at the same time. 81 00:03:30,656 --> 00:03:32,466 So that's for directories but we also wanted 82 00:03:32,466 --> 00:03:35,246 to set a different permission for things like images 83 00:03:35,246 --> 00:03:36,676 and CSS and HTML files. 84 00:03:37,126 --> 00:03:39,276 So if you wanna make sure if something is readable, 85 00:03:39,436 --> 00:03:42,276 so not necessarily executable like a binary but just readable 86 00:03:42,276 --> 00:03:45,376 like you would open a text file, you'd say chmod again a 87 00:03:45,376 --> 00:03:48,826 for everyone, + r this time where the r is gonna say, 88 00:03:48,826 --> 00:03:51,126 "I want you to add on the read permission." 89 00:03:51,606 --> 00:03:53,816 If you want to do something like subtract the read permission, 90 00:03:53,816 --> 00:03:55,626 you'd say "chmod a - r." 91 00:03:56,016 --> 00:03:57,996 That's gonna say, "Now, everyone can no longer read it." 92 00:03:58,256 --> 00:04:00,096 That's not really something you need to do for this pset. 93 00:04:00,626 --> 00:04:03,416 So now if you have a direct [inaudible] /star, 94 00:04:03,776 --> 00:04:05,086 that star is gonna say, "Well, 95 00:04:05,086 --> 00:04:06,836 everything that's inside of that folder." 96 00:04:07,156 --> 00:04:09,956 So the folder itself, you didn't just add the read permission to, 97 00:04:10,286 --> 00:04:12,486 you added this read permission to everything inside 98 00:04:12,486 --> 00:04:15,816 of the folder where the folder itself could have a different 99 00:04:15,816 --> 00:04:17,636 permission than all the files inside of it. 100 00:04:18,276 --> 00:04:19,096 So why do we wanna do that? 101 00:04:19,096 --> 00:04:21,906 Well, we can't really execute an image as a program, right. 102 00:04:21,906 --> 00:04:23,676 We can execute Sudoku and it run. 103 00:04:23,676 --> 00:04:25,166 But if we try to run like a jpeg, 104 00:04:25,476 --> 00:04:27,526 nothing is really gonna happen unless it's a cool jpeg. 105 00:04:28,356 --> 00:04:31,696 So here's a list of this more fine grain permissions. 106 00:04:32,176 --> 00:04:35,166 So if I say something like chmod 644 file. 107 00:04:35,776 --> 00:04:38,006 So this is gonna change permissions to some file. 108 00:04:38,346 --> 00:04:40,376 It's going to set them to 644. 109 00:04:40,896 --> 00:04:43,496 So this is unlike the syntax we just saw, we're only adding 110 00:04:43,496 --> 00:04:44,826 or subtracting something like the read 111 00:04:44,826 --> 00:04:46,246 or the executable permission. 112 00:04:46,516 --> 00:04:47,656 What this is doing, if it's going 113 00:04:47,656 --> 00:04:50,286 to set individually the permission for the user, 114 00:04:50,666 --> 00:04:53,236 some group of users, so every user belong to some group 115 00:04:53,236 --> 00:04:54,296 and we don't really care about that. 116 00:04:54,526 --> 00:04:56,506 And the last digit is for everyone else. 117 00:04:56,866 --> 00:04:58,726 So where do these numbers come from? 118 00:04:59,116 --> 00:05:01,526 Well, you'll notice if we have rwx, 119 00:05:01,796 --> 00:05:03,286 there are three places for letters. 120 00:05:04,016 --> 00:05:06,456 So if we have a letter in every single one of those places, 121 00:05:06,456 --> 00:05:08,766 we have kind of like the binary number 111. 122 00:05:09,386 --> 00:05:12,336 So that's-- what that's going to correspond to is the number 7. 123 00:05:13,206 --> 00:05:15,536 So in this 644, this first one is a 6. 124 00:05:15,536 --> 00:05:17,426 Where did that 6 come from? 125 00:05:17,426 --> 00:05:19,736 Well, I can read so that slot is gonna get a 1. 126 00:05:19,736 --> 00:05:22,046 I can write so that slot is gonna get a 1. 127 00:05:22,046 --> 00:05:25,216 And in binary, that's gonna be 4 plus 2 which is 6. 128 00:05:25,986 --> 00:05:28,726 So I've just said that myself, I can read 129 00:05:28,726 --> 00:05:30,746 and write this file called "file." 130 00:05:31,406 --> 00:05:33,746 Now for everyone else, I've set a permission of 4. 131 00:05:34,106 --> 00:05:34,846 So what does that mean? 132 00:05:34,846 --> 00:05:39,596 Well, if we can just jump off to our table and 4 in binary is 100 133 00:05:39,596 --> 00:05:41,236 which means only that R is set. 134 00:05:41,236 --> 00:05:43,946 So that means everyone else can just read this file 135 00:05:44,286 --> 00:05:47,306 but if I'm jharvard and this file lives inside my home 136 00:05:47,306 --> 00:05:48,886 directory, then I can read and write 137 00:05:48,886 --> 00:05:51,326 that file because I own it. 138 00:05:51,326 --> 00:05:54,916 Does that make sense? 139 00:05:54,916 --> 00:05:58,836 Okay. So just a little cheat sheet for you, for the purposes 140 00:05:58,836 --> 00:06:01,246 of this pset, every folder you create, 141 00:06:01,366 --> 00:06:03,416 you're gonna wanna say chmod 711. 142 00:06:03,866 --> 00:06:06,656 Every image HTML, CSS and soon JavaScript, 143 00:06:06,656 --> 00:06:08,136 you're gonna chmod 644, 144 00:06:08,496 --> 00:06:11,546 and every PHP file you're gonna chmod 600. 145 00:06:12,526 --> 00:06:13,976 So that's all you really-- that's all-- 146 00:06:13,976 --> 00:06:16,686 all these really boils down to, and if you forget to set one 147 00:06:16,686 --> 00:06:17,656 of these permission things, 148 00:06:17,936 --> 00:06:19,406 your website is just not gonna work right. 149 00:06:19,796 --> 00:06:22,246 So if at some point you end up at a blank screen, 150 00:06:22,356 --> 00:06:24,616 first thing you wanna check is your permissions to make sure 151 00:06:24,616 --> 00:06:26,626 that your server can actually read in the files 152 00:06:26,916 --> 00:06:27,896 that you're trying to read. 153 00:06:27,896 --> 00:06:30,946 So the first part of this assignment is 154 00:06:30,946 --> 00:06:32,616 to create your very own home page. 155 00:06:33,186 --> 00:06:37,856 So to do that, you wanna create a new file called index.html. 156 00:06:38,106 --> 00:06:40,976 You wanna put it inside of this public HTML folder. 157 00:06:41,846 --> 00:06:44,206 So if I'm a web browser and I'm going to some URL 158 00:06:44,836 --> 00:06:48,376 and it doesn't end in something like test.html but it just ends 159 00:06:48,376 --> 00:06:51,596 in some folder name, what the server is gonna do is it's going 160 00:06:51,596 --> 00:06:54,176 to look for a file called index. 161 00:06:55,006 --> 00:06:58,336 So if I just go to say local host or the IP of the appliance 162 00:06:58,336 --> 00:07:03,716 which is 192.168.565.0, I've been working with it too much. 163 00:07:03,716 --> 00:07:05,696 If you go to that and you don't say, "Well, 164 00:07:05,696 --> 00:07:07,716 I want this files specifically," I just say, 165 00:07:07,866 --> 00:07:09,986 "I want whatever is there," what the serve is got 166 00:07:09,986 --> 00:07:11,256 to do is it's gonna say, "Okay, 167 00:07:11,316 --> 00:07:12,886 I'm looking for something called index." 168 00:07:13,196 --> 00:07:16,546 So if I find index.html, I'm going to display that out 169 00:07:16,546 --> 00:07:20,606 to the user even though that URL doesn't contain index.html. 170 00:07:21,486 --> 00:07:23,896 So once you create it, the first thing you wanna do is make sure 171 00:07:23,896 --> 00:07:25,476 you do the chmod 644. 172 00:07:25,746 --> 00:07:26,596 So where did that come from? 173 00:07:26,596 --> 00:07:29,576 Just from our cheat sheet, HTML, so we're gonna have 644. 174 00:07:29,766 --> 00:07:30,846 We don't need to execute it. 175 00:07:30,846 --> 00:07:31,766 We just need to read it. 176 00:07:32,676 --> 00:07:35,226 So to get that, again, if we're inside the appliance, 177 00:07:35,226 --> 00:07:37,486 we can just say, "Local host tilde jharvard." 178 00:07:37,686 --> 00:07:38,956 If we're outside of the appliance 179 00:07:38,956 --> 00:07:41,356 on our own web browser, we need to have that IP address 180 00:07:41,846 --> 00:07:43,376 and then we can view our webpage. 181 00:07:44,146 --> 00:07:46,266 So as you make changes to this HTML file, 182 00:07:46,266 --> 00:07:48,206 no longer do you have to compile it. 183 00:07:48,206 --> 00:07:50,206 As soon as you make a change and you reload the page 184 00:07:50,206 --> 00:07:51,736 in your web browser, you're gonna see 185 00:07:51,736 --> 00:07:53,216 that change reflecting the page. 186 00:07:53,486 --> 00:07:55,306 So no more, you don't have to make HTML files 187 00:07:55,306 --> 00:07:56,096 or anything like that. 188 00:07:56,096 --> 00:07:57,936 You can just change them and then see your changes. 189 00:07:58,786 --> 00:08:00,436 So, one thing that's important for this pset is 190 00:08:00,436 --> 00:08:02,146 that the HTML you create inside 191 00:08:02,146 --> 00:08:04,526 of your home page has to be a valid HTML. 192 00:08:04,526 --> 00:08:06,586 So to do that, it's really, really simple, 193 00:08:06,586 --> 00:08:10,276 you can just upload your HTML file to validator.w3c.org, 194 00:08:10,496 --> 00:08:11,426 and it's just gonna spell out. 195 00:08:11,426 --> 00:08:13,096 Is this valid HTML, yes or no? 196 00:08:13,096 --> 00:08:15,496 And if it's not, it's gonna say, "On this line, you have a typo, 197 00:08:15,496 --> 00:08:17,326 you need to fix this and then it will be valid." 198 00:08:18,436 --> 00:08:20,506 So any questions on that part of the pset? 199 00:08:20,506 --> 00:08:20,636 Yup? 200 00:08:20,636 --> 00:08:23,046 >> Do we need to be commenting our webpage? 201 00:08:24,936 --> 00:08:27,286 >> So do we need to be commenting our webpage? 202 00:08:27,766 --> 00:08:30,656 So style counts just as much as it did before inside 203 00:08:30,656 --> 00:08:33,426 of web applications as it did for C programs. 204 00:08:33,946 --> 00:08:37,516 So maybe inside of your HTML you wanna say, "Like here is 205 00:08:37,516 --> 00:08:39,976 where the navigation bar is" like all that file is 206 00:08:39,976 --> 00:08:41,566 in navigation bar, here's the footer." 207 00:08:41,816 --> 00:08:43,456 You don't really need to say, here's the button, 208 00:08:43,456 --> 00:08:44,886 here's the text for the-- 209 00:08:44,886 --> 00:08:46,786 like you don't need to be that granular. 210 00:08:47,036 --> 00:08:49,756 Inside of your PHP though, your actual application logic, 211 00:08:49,756 --> 00:08:51,486 you'll probably gonna wanna be as thorough 212 00:08:51,486 --> 00:08:52,716 as you were with your C code. 213 00:08:52,846 --> 00:08:55,786 But generally with HTML comments, just kind of like 214 00:08:55,786 --> 00:08:57,276 where you are in the page roughly, 215 00:08:57,276 --> 00:08:59,746 so if I'll just kinda glance at it, I don't need to scroll up 216 00:08:59,746 --> 00:09:01,766 and figure out where in the page I'm looking at. 217 00:09:02,006 --> 00:09:03,776 I look at the code and the page side by side. 218 00:09:03,776 --> 00:09:06,106 I should have a general idea of where things are based 219 00:09:06,106 --> 00:09:10,806 on the HTML from the contents-- comments. 220 00:09:12,126 --> 00:09:13,406 Other questions? 221 00:09:14,086 --> 00:09:17,336 Okay. So, no longer are we using the language C 222 00:09:17,336 --> 00:09:20,156 but we're now introducing a new language to you called PHP 223 00:09:20,156 --> 00:09:23,936 which has one of the best acronyms ever because PH-- 224 00:09:23,936 --> 00:09:26,456 PHP stands for the PHP hypertext processor. 225 00:09:26,756 --> 00:09:28,346 It's one of the best recursive acronyms. 226 00:09:29,046 --> 00:09:31,946 So, some major differences between PHP and C, 227 00:09:32,236 --> 00:09:33,786 no longer are we writing dot C files, 228 00:09:33,786 --> 00:09:35,996 we're now writing dot PHP files. 229 00:09:36,036 --> 00:09:38,656 So get out of that habit of saving your files as dot C. 230 00:09:39,646 --> 00:09:42,746 So inside of PHP, all of your code is going to be contained 231 00:09:42,746 --> 00:09:45,456 within this bracket, question mark 232 00:09:45,686 --> 00:09:47,326 and then this PHP is optional. 233 00:09:47,586 --> 00:09:49,036 You can omit that if you want if you don't feel 234 00:09:49,036 --> 00:09:49,936 like typing it every time. 235 00:09:50,356 --> 00:09:52,756 And it's going to close with this question mark bracket. 236 00:09:53,006 --> 00:09:56,346 So any PHP code you write must be enclosed 237 00:09:56,556 --> 00:09:57,806 between these two characters. 238 00:09:58,116 --> 00:10:00,596 You can't just have PHP showing inside of your HTML 239 00:10:00,596 --> 00:10:03,956 or else it's not actually going to execute. 240 00:10:04,106 --> 00:10:05,526 >> So another perhaps really annoying difference 241 00:10:05,526 --> 00:10:07,676 with PHP is all of your variables must start 242 00:10:07,676 --> 00:10:08,446 with a dollar sign. 243 00:10:08,846 --> 00:10:11,406 There is no way around it, sorry, it gets annoying 244 00:10:11,796 --> 00:10:12,986 and you finally have a reason 245 00:10:12,986 --> 00:10:14,626 to start typing the 4 on your keyboard. 246 00:10:15,986 --> 00:10:18,046 And finally, variables are weekly typed. 247 00:10:18,606 --> 00:10:21,076 So when you create a variable, in C we needed 248 00:10:21,076 --> 00:10:23,516 to say int A equals something and that something needed 249 00:10:23,516 --> 00:10:26,076 to be an integer or you are going to get yelled at. 250 00:10:26,076 --> 00:10:27,926 In PHP, we can just say something 251 00:10:27,926 --> 00:10:29,546 like dollar sign X equals 5. 252 00:10:30,106 --> 00:10:32,966 You don't need to tell PHP that X is an integer because PHP, 253 00:10:32,966 --> 00:10:34,476 while it's executing, you can say, "Well, 254 00:10:34,686 --> 00:10:36,076 5 looks like an integer so looks 255 00:10:36,076 --> 00:10:37,356 like X is going to be an integer. 256 00:10:37,706 --> 00:10:39,916 You don't need to explicitly tell it to that. 257 00:10:39,916 --> 00:10:41,626 So simply, when you create a function, you don't need 258 00:10:41,626 --> 00:10:43,366 to declare the return type of your function. 259 00:10:43,366 --> 00:10:45,506 You can just say, "Here is a function and you figure 260 00:10:45,506 --> 00:10:47,376 out what it returns because you're really smart." 261 00:10:47,986 --> 00:10:48,476 Questions? 262 00:10:48,996 --> 00:10:52,376 Okay. So the major difference between a PHP 263 00:10:52,376 --> 00:10:56,176 and C is you no longer have to worry about things like malloc 264 00:10:56,176 --> 00:10:59,576 and segfaults and pointers and you'll be so excited 265 00:10:59,576 --> 00:11:00,956 when your code no longer segfaults. 266 00:11:00,956 --> 00:11:02,906 You just have this like nice little warning messages 267 00:11:02,906 --> 00:11:04,426 that tell you exactly where you went wrong. 268 00:11:05,006 --> 00:11:09,876 So let's just take a look at some examples of PHP. 269 00:11:09,876 --> 00:11:15,236 So I'm going to go inside of my web browser and you'll notice 270 00:11:15,406 --> 00:11:17,866 that I'm on my own computer, I'm not inside of my appliance 271 00:11:18,176 --> 00:11:20,576 and I've typed in this IP address of my appliance. 272 00:11:20,576 --> 00:11:23,846 So 192.168.565.0, that's never going 273 00:11:23,846 --> 00:11:26,466 to change whenever you have the appliance running even 274 00:11:26,466 --> 00:11:27,786 if it's minimized in the background, 275 00:11:28,056 --> 00:11:29,636 you can get at it from that URL. 276 00:11:29,636 --> 00:11:33,016 So next to it, I have this tilde jharvard and this says 277 00:11:33,016 --> 00:11:36,756 that I'm looking for the public_html folder inside 278 00:11:37,046 --> 00:11:38,236 of the jharvard folder. 279 00:11:38,786 --> 00:11:40,786 So if I had another user then it will be tilde 280 00:11:40,786 --> 00:11:41,636 and then that user's name. 281 00:11:41,946 --> 00:11:44,546 But because you always login as jharvard, you're gonna say, 282 00:11:44,696 --> 00:11:45,836 "Tilde jharvard," and that's 283 00:11:45,836 --> 00:11:47,246 where it's gonna look from public HTML. 284 00:11:47,976 --> 00:11:51,246 So inside of public HTML I have a folder. 285 00:11:51,596 --> 00:11:55,056 It's called pset7 and within that folder, I have a file, 286 00:11:55,056 --> 00:11:56,616 it's called "login.php." 287 00:11:57,156 --> 00:11:59,646 So when I type in this URL, the server is gonna say, "Okay, 288 00:11:59,646 --> 00:12:01,166 I know exactly what file to give you." 289 00:12:01,306 --> 00:12:03,706 It's gonna run the PHP code and display the output." 290 00:12:04,526 --> 00:12:06,506 So let's just take a look at what login.php does. 291 00:12:07,136 --> 00:12:08,536 So let's open up get it. 292 00:12:09,296 --> 00:12:11,206 We're gonna say "file open." 293 00:12:12,536 --> 00:12:15,836 So here's my public HTML pset7 and here's login. 294 00:12:16,276 --> 00:12:20,786 So, okay, so the first thing it does is it immediately starts a 295 00:12:20,786 --> 00:12:22,176 block of PHP code. 296 00:12:22,176 --> 00:12:23,106 How do we know that? 297 00:12:23,106 --> 00:12:25,516 Because we're starting with this bracket question mark. 298 00:12:25,886 --> 00:12:28,016 And until we close it with another bracket, 299 00:12:28,016 --> 00:12:30,706 question mark bracket, everything inside 300 00:12:30,706 --> 00:12:33,026 of that is going to be PHP. 301 00:12:33,056 --> 00:12:34,936 So we're just making a simple function call. 302 00:12:35,346 --> 00:12:37,896 So you notice first that this comment in PHP is the same 303 00:12:37,896 --> 00:12:39,626 as the comment in C, just slash, slash. 304 00:12:40,126 --> 00:12:42,976 And we're saying require_once includes/common.php. 305 00:12:42,976 --> 00:12:43,786 So what does that do? 306 00:12:44,546 --> 00:12:49,086 Well, that's gonna say, okay, there are some file that exists 307 00:12:49,146 --> 00:12:51,276 in the folder includes starting 308 00:12:51,276 --> 00:12:53,096 from where this PHP file is right now. 309 00:12:53,506 --> 00:12:56,156 And inside of that folder, there are some file called common.php. 310 00:12:56,156 --> 00:13:00,646 What I want you to do is basically go in to that file 311 00:13:00,646 --> 00:13:03,336 and copy and paste whatever is in there right here. 312 00:13:03,336 --> 00:13:06,326 So this is kind of like the define statement we saw on C 313 00:13:06,326 --> 00:13:07,366 or the include statement, sorry. 314 00:13:07,736 --> 00:13:09,326 We're gonna open some file and just copy 315 00:13:09,326 --> 00:13:11,006 and paste whatever is in there right here. 316 00:13:11,616 --> 00:13:13,166 So let's take a look at what that looks like. 317 00:13:13,166 --> 00:13:14,206 Well, it's open. 318 00:13:15,036 --> 00:13:16,826 Okay, here's our folder called includes 319 00:13:17,056 --> 00:13:19,866 and then here's common.php. 320 00:13:19,866 --> 00:13:20,866 So alright, so this looks 321 00:13:20,866 --> 00:13:23,386 like it's doing some kind of complicated stuff. 322 00:13:23,796 --> 00:13:25,176 So before we get into that, let's just look 323 00:13:25,176 --> 00:13:26,016 at the rest of login.php. 324 00:13:26,016 --> 00:13:31,216 So we see some title, so here's the top of my page. 325 00:13:31,216 --> 00:13:33,496 And at the top of my page, we have some image. 326 00:13:34,116 --> 00:13:36,926 And you'll notice that this image is located inside some 327 00:13:37,026 --> 00:13:40,296 folder called images and the image is called logo.gif. 328 00:13:41,216 --> 00:13:43,546 So let's just take a look at what that looks like. 329 00:13:43,546 --> 00:13:45,796 So if I open up my terminal, I'm gonna go 330 00:13:45,796 --> 00:13:49,726 into public_html pset7 images. 331 00:13:50,636 --> 00:13:52,426 And if I do an ls, well, there we go. 332 00:13:52,426 --> 00:13:53,846 I can see my logo.gif. 333 00:13:54,806 --> 00:13:58,756 So if I say ls -l, that -l is gonna tell me 334 00:13:58,756 --> 00:14:01,066 to display some additional information. 335 00:14:01,486 --> 00:14:03,346 And what's the additional information I've displayed? 336 00:14:03,476 --> 00:14:05,866 Well over to the left here you can see the permissions 337 00:14:05,916 --> 00:14:06,446 of this file. 338 00:14:06,976 --> 00:14:07,996 So if I look at logo.gif, 339 00:14:07,996 --> 00:14:11,596 I see that this file is currently set to 644, right. 340 00:14:11,596 --> 00:14:14,016 We have 2 bits, which is a 6 and then 2-- 341 00:14:14,176 --> 00:14:16,386 an r, another r, both of those are 4. 342 00:14:16,386 --> 00:14:19,676 So the current permissions of logo.g0ff are 644. 343 00:14:19,676 --> 00:14:23,106 And that means that I've-- if I'm the web server, 344 00:14:23,256 --> 00:14:25,346 I can open up that file and I can display it to you 345 00:14:25,346 --> 00:14:28,166 and that's why we can see this logo right there. 346 00:14:28,766 --> 00:14:34,786 So now, if I did something like chmod 000 logo.gif and we look 347 00:14:34,786 --> 00:14:36,646 at the permissions again, you now notice 348 00:14:36,646 --> 00:14:37,326 that they're different. 349 00:14:37,326 --> 00:14:39,096 Whoa, if I spell ls right. 350 00:14:39,096 --> 00:14:41,956 So you notice that they're different. 351 00:14:42,356 --> 00:14:44,096 So now, I've removed all permissions. 352 00:14:44,096 --> 00:14:46,586 I've said no one can do anything to this file ever. 353 00:14:46,636 --> 00:14:49,086 So now if we jump back to the web browser 354 00:14:49,666 --> 00:14:53,556 and we refresh the page, that image is gone 355 00:14:54,216 --> 00:14:55,906 because we're no longer allowed to read it. 356 00:14:56,396 --> 00:14:58,266 So if you find this happening in your code, 357 00:14:58,326 --> 00:15:00,376 first thing you wanna do is try to check permissions. 358 00:15:00,836 --> 00:15:02,686 Let's just change it back to 644. 359 00:15:03,866 --> 00:15:07,636 Refresh our page again and it's back. 360 00:15:08,726 --> 00:15:10,966 So everybody understand how that permissions is gonna work 361 00:15:10,966 --> 00:15:11,896 and what things are gonna look like? 362 00:15:13,146 --> 00:15:17,056 Okay, so let's a jump back into this login.php. 363 00:15:17,526 --> 00:15:18,906 So nothing else suspicious here, 364 00:15:18,906 --> 00:15:22,066 we're just displaying those two text fields, that makes sense. 365 00:15:22,066 --> 00:15:24,886 There's no more PHP on this page which is good 366 00:15:24,946 --> 00:15:25,696 for our understanding. 367 00:15:26,826 --> 00:15:29,536 So now let's jump in to common.php. 368 00:15:29,626 --> 00:15:32,866 So the first thing we're doing, we're just saying okay PHP, 369 00:15:32,916 --> 00:15:34,206 whenever you have some error 370 00:15:34,206 --> 00:15:36,386 like you encounter a syntax error or something like that, 371 00:15:36,736 --> 00:15:38,966 I want you to be super helpful and I want you 372 00:15:38,966 --> 00:15:41,006 to tell me exactly where those errors are. 373 00:15:41,436 --> 00:15:43,986 So instead of just core dumped I wanna see, "well, 374 00:15:43,986 --> 00:15:46,986 there's an error on line 15 and this is what your error is 375 00:15:46,986 --> 00:15:48,216 and this is how you can correct it." 376 00:15:48,566 --> 00:15:49,906 So that's just what these two lines say, 377 00:15:50,056 --> 00:15:52,306 they just say display all the errors as you possibly can 378 00:15:52,306 --> 00:15:53,376 and be super helpful please. 379 00:15:53,926 --> 00:15:57,606 So the next of this is just the security measure we're saying, 380 00:15:57,606 --> 00:16:00,006 "Well, we just wanna make sure that everything that comes 381 00:16:00,006 --> 00:16:02,406 from this cookie, that come from this site are restricted 382 00:16:02,406 --> 00:16:04,636 to the URL tilda something/pset7." 383 00:16:05,426 --> 00:16:08,556 You do not have to worry about how the hell you parched that, 384 00:16:09,396 --> 00:16:12,456 just assume that it works and it does. 385 00:16:12,666 --> 00:16:14,146 So now, we're doing this something called 386 00:16:14,146 --> 00:16:15,016 "Session Start." 387 00:16:15,836 --> 00:16:18,896 So this is creating a new session for the user. 388 00:16:19,486 --> 00:16:21,826 So a session is as called a "Super Global." 389 00:16:22,466 --> 00:16:25,876 So inside of a session I can store information that's going 390 00:16:25,876 --> 00:16:28,916 to persist as I go back and forth through pages. 391 00:16:28,916 --> 00:16:32,516 So if you've ever been on CS50.net or any site you login, 392 00:16:32,816 --> 00:16:35,706 you notice that when you change pages the site remembers 393 00:16:35,706 --> 00:16:36,346 who you are. 394 00:16:37,196 --> 00:16:39,326 So if you think about this PHP files look like 395 00:16:39,326 --> 00:16:42,106 and if I just create a variable on one PHP file I need 396 00:16:42,106 --> 00:16:43,506 to somehow pass that variable 397 00:16:43,506 --> 00:16:45,566 to any other PHP file you might rem-- 398 00:16:45,566 --> 00:16:47,936 you might visit so that I can remember who you are, 399 00:16:48,496 --> 00:16:50,686 the easy way to do that is just to put this 400 00:16:50,686 --> 00:16:52,606 in some magical variable called "Session." 401 00:16:53,096 --> 00:16:55,906 That's going to be accessible through every PHP file 402 00:16:55,906 --> 00:16:57,266 on the site that you create. 403 00:16:57,896 --> 00:16:59,926 So in order for this session global to work 404 00:16:59,926 --> 00:17:01,346 or to be active you need 405 00:17:01,346 --> 00:17:03,746 to first just make this function called "Session Start." 406 00:17:04,126 --> 00:17:06,156 That says "I'm gonna using session somewhere 407 00:17:06,266 --> 00:17:07,776 and I wanna make sure that it works." 408 00:17:08,536 --> 00:17:11,256 So now, [inaudible] we're gonna require three more files. 409 00:17:11,866 --> 00:17:13,226 So we can just open this up. 410 00:17:14,106 --> 00:17:17,466 So the first is called constant.php. 411 00:17:17,516 --> 00:17:18,286 Oh, thank God. 412 00:17:18,286 --> 00:17:19,336 This is really, really simple. 413 00:17:19,736 --> 00:17:21,526 This is just a series of define statements. 414 00:17:21,556 --> 00:17:23,526 Just like in C we had that sharp defined, 415 00:17:23,816 --> 00:17:26,956 we're just saying everywhere you see DB_NAME, I want you to find 416 00:17:26,956 --> 00:17:29,556 and replace that with jharvard_pset7. 417 00:17:30,016 --> 00:17:32,136 Of course these credentials probably look familiar to you 418 00:17:32,136 --> 00:17:34,206 by now just the user's password is going 419 00:17:34,206 --> 00:17:35,566 to be jharvard and crimson. 420 00:17:36,136 --> 00:17:38,336 So we're going to use that to get into our database 421 00:17:38,336 --> 00:17:39,306 which we'll see later. 422 00:17:39,306 --> 00:17:43,676 And so now, we just have a couple other files like helpers. 423 00:17:44,106 --> 00:17:45,656 And so this is just gonna contain some handy 424 00:17:45,656 --> 00:17:46,536 helper functions. 425 00:17:47,656 --> 00:17:50,306 So we can do things like display an error message to the user 426 00:17:50,306 --> 00:17:51,276 so we don't have to worry 427 00:17:51,276 --> 00:17:53,516 about like displaying an error on a page. 428 00:17:53,516 --> 00:17:55,886 If we just say apologize and pass it some string. 429 00:17:56,016 --> 00:17:57,826 What this is gonna do is redirect the user 430 00:17:57,826 --> 00:17:58,806 to some error page. 431 00:17:59,046 --> 00:18:01,426 The error message is going to be whatever you pass in, 432 00:18:01,596 --> 00:18:02,826 add this value message. 433 00:18:03,746 --> 00:18:06,036 We can also use dump which is really handy 434 00:18:06,036 --> 00:18:08,536 if we have some variable or some array or some object. 435 00:18:08,786 --> 00:18:10,856 We wanna know what everything inside of that is. 436 00:18:11,036 --> 00:18:13,346 If we just call dump, this is gonna redirect you 437 00:18:13,346 --> 00:18:15,466 to some other magical page that's just going 438 00:18:15,466 --> 00:18:17,936 to contain whatever the variable you pass in this. 439 00:18:18,356 --> 00:18:19,786 So this variable can be anything. 440 00:18:19,786 --> 00:18:20,416 It could be an array. 441 00:18:20,416 --> 00:18:22,586 It can be an object, whatever you want. 442 00:18:23,126 --> 00:18:24,096 So log out again, 443 00:18:24,096 --> 00:18:25,896 some complicated stuff you don't have to worry about. 444 00:18:26,216 --> 00:18:28,556 But you notice that the session destroy they're saying, "Okay, 445 00:18:28,556 --> 00:18:31,176 remember that session super global, I want you to wipe it. 446 00:18:31,176 --> 00:18:33,406 I wanna make sure that there is nothing there anymore." 447 00:18:34,226 --> 00:18:35,556 And so we'll get into the remainder 448 00:18:35,556 --> 00:18:37,576 of this file in just a bit. 449 00:18:38,466 --> 00:18:42,346 So that's gonna be index.php. 450 00:18:42,456 --> 00:18:44,386 So there're a couple of other files you need to worry about, 451 00:18:44,596 --> 00:18:46,156 namely these two login files. 452 00:18:46,836 --> 00:18:47,656 So we looked at login.php 453 00:18:47,656 --> 00:18:51,246 but now let's take a look at login2.php. 454 00:18:51,246 --> 00:18:56,576 So let's get rid of these guys and open up login2. 455 00:18:58,336 --> 00:19:02,466 So again, the first thing we're doing is requiring this 456 00:19:02,466 --> 00:19:03,236 common file. 457 00:19:03,436 --> 00:19:05,696 This common file is requiring a bunch of other files 458 00:19:05,866 --> 00:19:07,166 but just basically make available 459 00:19:07,166 --> 00:19:09,346 to you some helpful constants and functions. 460 00:19:10,376 --> 00:19:15,206 So now-- Well, so we're creating some new variable username. 461 00:19:15,716 --> 00:19:17,896 And notice that I did not give username a type 462 00:19:18,306 --> 00:19:19,936 but this is the first time I'm using it. 463 00:19:20,226 --> 00:19:23,306 So if I just say dollar sign username I'm now creating a new 464 00:19:23,306 --> 00:19:24,916 variable called username. 465 00:19:26,046 --> 00:19:29,206 So I'm setting that equal to the result of some function, 466 00:19:29,426 --> 00:19:33,626 mysql_real_escape_string, dollar sign underscore POST username. 467 00:19:34,366 --> 00:19:37,176 Wow! So what this function does, 468 00:19:37,326 --> 00:19:39,546 this mysql_real_escape_string is pretty simple. 469 00:19:39,546 --> 00:19:40,626 It's just a security measure. 470 00:19:40,716 --> 00:19:42,486 If someone is trying to hack your site and they try 471 00:19:42,486 --> 00:19:45,226 to inject some nasty code into-- as their username, 472 00:19:45,426 --> 00:19:46,696 this function is just gonna get rid of it 473 00:19:46,696 --> 00:19:48,386 so your site doesn't get hacked and you look like a [inaudible]. 474 00:19:49,536 --> 00:19:52,526 This POST is another super global. 475 00:19:53,066 --> 00:19:54,836 So just like session, it's gonna start 476 00:19:54,836 --> 00:19:56,866 with the dollar sign underscore and have capital letters. 477 00:19:56,866 --> 00:19:59,696 And this POST is going to be the result 478 00:19:59,696 --> 00:20:03,936 of whatever the users sent you from some form. 479 00:20:04,106 --> 00:20:04,716 >> So where is that form? 480 00:20:04,716 --> 00:20:06,996 Well, remember, that we first went to this login.php 481 00:20:06,996 --> 00:20:09,336 and that's where we saw that login form. 482 00:20:09,766 --> 00:20:12,276 So let's actually take a look at the HTML from that login form. 483 00:20:13,436 --> 00:20:16,116 Now what we care about is this form element. 484 00:20:16,566 --> 00:20:18,946 So this is what's going to start off the login form, 485 00:20:19,006 --> 00:20:20,096 everything that's contained 486 00:20:20,096 --> 00:20:22,536 within the form is gonna be a child of this form element. 487 00:20:22,876 --> 00:20:24,626 So there are two important attributes. 488 00:20:24,896 --> 00:20:26,626 The first of this is Action. 489 00:20:27,196 --> 00:20:30,856 You notice that it says login2.php. 490 00:20:30,856 --> 00:20:34,246 What this says is it's gonna be whatever form information you 491 00:20:34,246 --> 00:20:37,236 entered I wanna send that over to login2.php. 492 00:20:37,236 --> 00:20:41,866 So okay, so after the user submits this form they're gonna 493 00:20:41,866 --> 00:20:44,726 be redirected to login2.php. 494 00:20:44,726 --> 00:20:48,786 So this second parameter is gonna tell me how do I wanna 495 00:20:48,786 --> 00:20:52,326 pass the data from this file, login.php, 496 00:20:52,326 --> 00:20:55,496 to my other file, which is login2.php. 497 00:20:55,496 --> 00:20:57,086 I'm saying method equals POST. 498 00:20:57,486 --> 00:20:58,866 Well, that looks kinda familiar 499 00:20:59,606 --> 00:21:03,236 because I'm saying dollar underscore POST username. 500 00:21:03,976 --> 00:21:05,786 So okay, so that attributes just telling me how 501 00:21:05,786 --> 00:21:06,556 to get up the data. 502 00:21:07,216 --> 00:21:10,136 So now, let's take a look at this dump function that we saw. 503 00:21:10,336 --> 00:21:13,926 So let's say dump this dollar underscore post. 504 00:21:14,286 --> 00:21:17,816 So dump is just a function define the helpers.php, 505 00:21:17,816 --> 00:21:21,906 I just wanna take a look at what this dollar sign underscore POST 506 00:21:22,036 --> 00:21:22,516 thing is. 507 00:21:23,186 --> 00:21:26,766 So let's go back to my web browser and I refresh the page, 508 00:21:27,086 --> 00:21:28,876 inside of my username is gonna say Tommy, 509 00:21:29,676 --> 00:21:31,746 and my password is gonna be something really secret, 510 00:21:31,746 --> 00:21:33,026 I'm gonna click login. 511 00:21:34,186 --> 00:21:38,956 Okay, so you'll notice that I was sent 512 00:21:38,956 --> 00:21:42,686 to as we expected login2.php 513 00:21:42,686 --> 00:21:44,496 because that was the action of our forms. 514 00:21:44,496 --> 00:21:45,666 So that's where the form sent us. 515 00:21:46,446 --> 00:21:50,546 So now inside of this dollar underscore POST variable is 516 00:21:50,546 --> 00:21:51,566 going to be this array. 517 00:21:52,486 --> 00:21:54,506 So this array has two elements. 518 00:21:54,506 --> 00:21:56,586 It has a username, which is Tommy; 519 00:21:56,726 --> 00:21:58,846 and it has a password, which is secret. 520 00:21:59,626 --> 00:22:02,416 So okay, so this isn't just your regular, old C array. 521 00:22:02,486 --> 00:22:04,316 This is now it's called an associative array. 522 00:22:04,886 --> 00:22:08,306 Or effectively a hash table, 'cause we have some array 523 00:22:08,536 --> 00:22:11,366 that instead of numbers we're now accessing the indices 524 00:22:11,366 --> 00:22:13,196 of this array with strings. 525 00:22:13,636 --> 00:22:16,096 So PHP has taken care of pset6 for you 526 00:22:16,096 --> 00:22:17,496 and made a really nice hash table. 527 00:22:18,206 --> 00:22:21,466 And so we can just say, "Well, I want the value stored 528 00:22:21,466 --> 00:22:22,606 for the key username." 529 00:22:23,306 --> 00:22:25,536 So now username or password where did those come from? 530 00:22:25,976 --> 00:22:26,906 They're not just automatic 531 00:22:26,906 --> 00:22:28,896 because you called your file login although 532 00:22:28,896 --> 00:22:29,806 that would be really sweet. 533 00:22:30,876 --> 00:22:33,886 Instead they came from these two input elements. 534 00:22:34,356 --> 00:22:36,306 So this input says. 535 00:22:36,306 --> 00:22:38,996 "Okay, I want you to create some text field. 536 00:22:39,656 --> 00:22:41,996 And whatever the user types into that text field, 537 00:22:41,996 --> 00:22:44,586 I want to save it under the key password. 538 00:22:45,236 --> 00:22:48,786 So username and password, and because I said that method POST, 539 00:22:49,076 --> 00:22:52,516 that means that inside of the super global called POST, 540 00:22:52,816 --> 00:22:55,816 I wanna be able to get at whatever the user typed 541 00:22:56,036 --> 00:22:57,406 with the key "username." 542 00:22:58,686 --> 00:23:01,726 That makes sense? 543 00:23:01,876 --> 00:23:04,346 Okay, so now let's just take a look 544 00:23:04,836 --> 00:23:07,866 at some other PHP examples before we jump 545 00:23:07,866 --> 00:23:08,926 into the database stuff. 546 00:23:09,106 --> 00:23:10,836 So I'm gonna create a new file 547 00:23:11,376 --> 00:23:14,036 and I'm just gonna save it as test.php. 548 00:23:14,036 --> 00:23:17,986 So I'm just saving it inside of my public_html. 549 00:23:19,036 --> 00:23:23,256 So I saved it as test.php, the first thing I wanna do-- 550 00:23:23,916 --> 00:23:28,276 God it's so helpful-- is open up these two tags. 551 00:23:28,956 --> 00:23:31,966 And these two tags say, right here is gonna be some PHP. 552 00:23:31,966 --> 00:23:33,826 So let's do a couple of things. 553 00:23:33,826 --> 00:23:37,786 Let's just create a variable so the variable is gonna be 5. 554 00:23:37,876 --> 00:23:38,996 Now let's create a function 555 00:23:39,626 --> 00:23:42,586 so when the first functions we wrote in C was a function 556 00:23:42,586 --> 00:23:44,296 that returns to the sum of two numbers. 557 00:23:45,196 --> 00:23:48,776 So you notice I do not need to specify the return type 558 00:23:48,776 --> 00:23:50,736 of my function, I'm just going to say "Function." 559 00:23:51,226 --> 00:23:53,336 After that, just like we're used to, it's gonna be the name 560 00:23:53,336 --> 00:23:54,966 of the function and then the arguments 561 00:23:55,026 --> 00:23:55,956 that the function takes. 562 00:23:56,276 --> 00:23:58,706 So again these are going to have to start with a dollar sign 563 00:23:58,836 --> 00:24:01,306 because the variables and all variables annoyingly start 564 00:24:01,486 --> 00:24:02,096 with a dollar sign. 565 00:24:02,926 --> 00:24:05,696 So just like we're used to in C, let's just return A plus B. 566 00:24:05,696 --> 00:24:09,766 So a whole new language, PHP, but this is pretty simple. 567 00:24:09,766 --> 00:24:10,686 It's very, very similar 568 00:24:10,686 --> 00:24:13,366 to C. We're taking the concepts we learned with one language 569 00:24:13,366 --> 00:24:14,716 and we can just apply them to this one. 570 00:24:15,146 --> 00:24:16,336 We know exactly what that means. 571 00:24:16,336 --> 00:24:17,916 It says a little difference syntax. 572 00:24:18,666 --> 00:24:20,416 So okay, so that means that some-- 573 00:24:20,416 --> 00:24:22,496 where in this file I have this variable 574 00:24:22,496 --> 00:24:23,416 and I have this function. 575 00:24:23,976 --> 00:24:28,226 So now let's print out some text. 576 00:24:28,226 --> 00:24:29,696 So this H1 tag, this says, 577 00:24:29,696 --> 00:24:31,506 "I wanna make this text really, really big." 578 00:24:32,166 --> 00:24:35,466 So now we open up this file we can get there, 579 00:24:35,466 --> 00:24:39,106 via the URL, jharvard/test.php. 580 00:24:39,616 --> 00:24:44,906 So we run that and we just get high, right? 581 00:24:44,906 --> 00:24:47,286 Because that makes sense, 582 00:24:47,316 --> 00:24:49,386 the code we wrote didn't actually do anything. 583 00:24:49,386 --> 00:24:51,326 It didn't does have any output to the user. 584 00:24:51,646 --> 00:24:54,466 We just created some variable and create define some function 585 00:24:54,736 --> 00:24:55,816 that we haven't used yet. 586 00:24:56,696 --> 00:24:58,186 So now let's say that I wanna print 587 00:24:58,186 --> 00:24:59,956 out this variable to the user. 588 00:25:00,846 --> 00:25:04,606 So let's just say H2 which is just slightly smaller text 589 00:25:04,606 --> 00:25:05,266 than H1. 590 00:25:05,266 --> 00:25:08,496 So now let's open up another block of PHP. 591 00:25:08,496 --> 00:25:15,016 So again bracket and question mark and we're gonna say 592 00:25:15,016 --> 00:25:18,546 "print.f, print variable." 593 00:25:19,066 --> 00:25:20,776 Make sense? 594 00:25:20,936 --> 00:25:24,546 We have some variable it's defined in this file. 595 00:25:24,546 --> 00:25:26,296 And even though it's defined at a different block 596 00:25:26,296 --> 00:25:29,056 of PHP we can still access it from this other block. 597 00:25:29,056 --> 00:25:31,936 So we're gonna say, "Just print out the value of this variable." 598 00:25:32,726 --> 00:25:36,736 So let's close the HTML tag so that we're making attempt 599 00:25:36,736 --> 00:25:42,266 to be valid, jump back to our web page and run it. 600 00:25:43,176 --> 00:25:44,556 And so now, we printed f5. 601 00:25:45,366 --> 00:25:47,326 Something you might have noticed is that we didn't actually have 602 00:25:47,326 --> 00:25:50,736 to say "printf percent d/n whatever." 603 00:25:51,146 --> 00:25:53,576 We can just print out a variable and it doesn't matter what type 604 00:25:53,576 --> 00:25:55,516 that variable is because print is smart enough 605 00:25:55,636 --> 00:25:56,686 to just print the value itself. 606 00:25:57,796 --> 00:26:00,036 So now if we wanted to do something like print the result 607 00:26:00,036 --> 00:26:02,886 of some function, how could we do that? 608 00:26:03,096 --> 00:26:05,826 So what I wanna write inside of my PHP block here? 609 00:26:06,356 --> 00:26:11,656 So let's just say I wanna add up the number 1 and 2 610 00:26:11,656 --> 00:26:15,236 so I can print the sum of 1 and 2. 611 00:26:15,646 --> 00:26:19,586 So again, function defined up there but we can access it 612 00:26:20,116 --> 00:26:26,376 down here so let's jump over and we printed out 3. 613 00:26:26,376 --> 00:26:29,046 So a shortcut that you'll see throughout the pset, 614 00:26:29,496 --> 00:26:32,186 instead of typing this print, we can actually just say, 615 00:26:32,486 --> 00:26:35,206 "dollar sign equals and then the variable name." 616 00:26:35,856 --> 00:26:37,876 So this is equivalent to what we just wrote, 617 00:26:38,116 --> 00:26:40,406 this question mark print and then wherever you wanna print. 618 00:26:40,406 --> 00:26:42,786 If you just have this equal sign these are equivalent. 619 00:26:42,786 --> 00:26:44,386 If you just wanna quickly printout a value. 620 00:26:44,916 --> 00:26:46,576 So if we go back to our page and refresh, 621 00:26:46,626 --> 00:26:48,256 we notice nothing have-- nothing has changed 622 00:26:48,386 --> 00:26:50,496 because these two statements are equivalent. 623 00:26:51,806 --> 00:27:14,166 So any questions on how are we gonna be using PHP in this pset? 624 00:27:14,166 --> 00:27:14,286 Yup? 625 00:27:14,366 --> 00:27:16,916 >> So every different function is contained by-- 626 00:27:16,916 --> 00:27:22,226 if we put in brackets, it's not like in C where you 627 00:27:22,226 --> 00:27:27,466 like declare a function inside of something inside 628 00:27:27,466 --> 00:27:34,606 of a function then it can't be accessible outside of it, 629 00:27:34,606 --> 00:27:35,906 here you can, [inaudible] scope issue? 630 00:27:35,906 --> 00:27:36,436 >> Yeah, so this-- 631 00:27:36,436 --> 00:27:38,896 so the question is how does scoping as you work? 632 00:27:39,376 --> 00:27:42,286 So it is a little different than C. 633 00:27:42,286 --> 00:27:47,216 And this variable is effectively a global variable as far 634 00:27:47,216 --> 00:27:52,336 as this file is concerned anywhere inside this file I can 635 00:27:52,826 --> 00:27:54,296 access this variable. 636 00:27:54,926 --> 00:28:00,286 So you'll also notice that the blocks of PHP are kind 637 00:28:00,286 --> 00:28:03,236 of interspersed with block of non-PHP, right, 638 00:28:03,236 --> 00:28:10,706 like this H1 that's says it's high, that's not PHP. 639 00:28:10,956 --> 00:28:13,016 So when the server runs this file, 640 00:28:13,016 --> 00:28:14,886 it's going to process these blocks 641 00:28:14,886 --> 00:28:16,456 in the order that they appear. 642 00:28:16,456 --> 00:28:19,796 So if I do something above, 643 00:28:19,796 --> 00:28:21,436 I can use that anywhere I want below. 644 00:28:21,986 --> 00:28:27,956 But if I declare variable blow here and try to use it 645 00:28:27,956 --> 00:28:31,856 up at the top, that's not gonna work. 646 00:28:32,156 --> 00:28:37,096 So we can inters-- we don't have to have all of our PHP 647 00:28:37,096 --> 00:28:39,466 at the top or all at the bottom or something. 648 00:28:39,626 --> 00:28:45,826 We can actually intersperse it throughout the page, 649 00:28:45,826 --> 00:28:50,786 we can do so between HTML tags to take care of things 650 00:28:50,786 --> 00:28:53,686 like formatting and placement other stuff like that. 651 00:28:53,686 --> 00:28:53,866 Yup? 652 00:28:54,086 --> 00:28:55,356 >> Can you still see the webpage 653 00:28:55,686 --> 00:29:01,566 but it can still be invalid code? 654 00:29:01,906 --> 00:29:07,706 >> So can I see the webpage if it's invalid code? 655 00:29:07,966 --> 00:29:09,236 So let's make it invalid code. 656 00:29:09,236 --> 00:29:10,676 Let's just forget that semicolon. 657 00:29:10,846 --> 00:29:13,476 So just like in C, this is now a syntax error. 658 00:29:13,476 --> 00:29:16,076 So let's see what happens when I open up my webpage. 659 00:29:16,076 --> 00:29:17,646 It's like I'm here, we have this really nice message, 660 00:29:17,676 --> 00:29:18,936 syntax error expected a function on line 5. 661 00:29:18,966 --> 00:29:20,106 So I'm a programmer, I'm gonna go on line 5. 662 00:29:20,136 --> 00:29:20,976 Let's say, "Oh, here's a function here." 663 00:29:21,006 --> 00:29:22,476 Well, that's kind of unexpected because I'm in the middle 664 00:29:22,506 --> 00:29:24,066 of a statement I can't say something like 5 function I need 665 00:29:24,096 --> 00:29:25,566 to end this statement before I can create this function 666 00:29:25,596 --> 00:29:26,256 so I forgot a semicolon. 667 00:29:26,286 --> 00:29:27,966 So if-- and you make any syntax errors unfortunately PHP is not 668 00:29:27,996 --> 00:29:29,226 smart enough to tell you how to do the pset yet. 669 00:29:29,256 --> 00:29:30,006 But things like syntax errors, 670 00:29:30,036 --> 00:29:31,056 you're gonna get this nicer message perhaps 671 00:29:31,086 --> 00:29:31,896 than you used to seeing for make. 672 00:29:31,926 --> 00:29:32,286 Other questions? 673 00:29:32,316 --> 00:29:32,383 Yeah? 674 00:29:32,406 --> 00:29:33,366 >> How does it know to go to public.html 675 00:29:33,396 --> 00:29:33,906 like in your URL bar [inaudible]? 676 00:29:33,936 --> 00:29:35,016 >> So how does it know to get to public_html? 677 00:29:35,046 --> 00:29:36,396 So this is just a property of the server we're using, 678 00:29:36,426 --> 00:29:36,936 which is called Apache. 679 00:29:36,966 --> 00:29:38,376 And so when we're using Apache, Apache is gonna say, "Okay, 680 00:29:38,406 --> 00:29:39,756 I see this URL and I need to know somewhere on the server 681 00:29:39,786 --> 00:29:40,776 which can contain a bunch of other things 682 00:29:40,806 --> 00:29:42,006 that aren't necessarily displayed as a website, 683 00:29:42,036 --> 00:29:42,936 I need to know where to start looking." 684 00:29:42,966 --> 00:29:44,406 And we've just configured the appliance for you that says 685 00:29:44,436 --> 00:29:45,006 "I'm gonna start looking 686 00:29:45,036 --> 00:29:46,626 in any folder called public_html that's inside a home directory." 687 00:29:46,656 --> 00:29:48,126 You can change it if you want, but you certainly don't need 688 00:29:48,156 --> 00:29:49,086 to for this or anything else you'll do. 689 00:29:49,116 --> 00:29:50,196 So we've just kind of preset up for you 690 00:29:50,226 --> 00:29:51,126 to look inside of this public_html. 691 00:29:51,156 --> 00:29:51,516 Other questions? 692 00:29:51,546 --> 00:29:51,636 Yup? 693 00:29:51,666 --> 00:29:53,016 >> Is this webpage accessible if you close the appliance? 694 00:29:53,046 --> 00:29:54,396 >> Is this webpage accessible if you close the appliance? 695 00:29:54,426 --> 00:29:55,386 It's not. Because in order for something 696 00:29:55,416 --> 00:29:56,196 to send us this page it needs-- 697 00:29:56,226 --> 00:29:57,306 something used to be running that's listening 698 00:29:57,336 --> 00:29:57,816 for these requests. 699 00:29:57,846 --> 00:29:59,076 So if we shut that down by closing the appliance, 700 00:29:59,106 --> 00:29:59,976 we can no longer get up this URL. 701 00:30:00,146 --> 00:30:01,396 >> But if we, you know, minimize or something 702 00:30:01,396 --> 00:30:02,346 like that, we're still okay. 703 00:30:02,346 --> 00:30:03,796 We don't need to have it in the foreground. 704 00:30:03,956 --> 00:30:05,916 It just needs to be running somewhere on your computer. 705 00:30:06,326 --> 00:30:08,196 Other questions? 706 00:30:08,196 --> 00:30:15,416 Alright, so that's a quick walkthrough 707 00:30:15,416 --> 00:30:18,396 of the distribution code and we'll see these functions 708 00:30:18,396 --> 00:30:20,286 as we go through all the things that you're gonna need 709 00:30:20,286 --> 00:30:23,146 to for the purposes of this pset. 710 00:30:23,146 --> 00:30:27,456 So again, login2.php or getting the username from that form 711 00:30:27,456 --> 00:30:28,806 and restored inside a post. 712 00:30:29,146 --> 00:30:31,916 And now what we need to do is look up the user 713 00:30:32,136 --> 00:30:34,526 from the database because we can't just allow anyone 714 00:30:34,526 --> 00:30:35,726 to login, right. 715 00:30:35,726 --> 00:30:38,396 We need to make sure that, A, the user exists, that they typed 716 00:30:38,396 --> 00:30:42,116 in the right password before we can actually log them in. 717 00:30:42,116 --> 00:30:43,376 So let's take a look at how we do that. 718 00:30:43,996 --> 00:30:45,746 So we understand this line, we're just getting 719 00:30:45,816 --> 00:30:47,636 from that form on the previous page. 720 00:30:47,636 --> 00:30:50,446 We're getting the value the user typed in. 721 00:30:50,446 --> 00:30:53,796 So now, we have what's called a SQL query. 722 00:30:54,476 --> 00:30:56,896 So this says, "From my database, 723 00:30:57,536 --> 00:31:00,116 where a database is just some collection of tables, 724 00:31:00,116 --> 00:31:01,696 where tables have columns and rows 725 00:31:01,696 --> 00:31:04,036 and that's how you gonna represent all of your values 726 00:31:04,356 --> 00:31:05,866 from that database, I wanna look 727 00:31:05,866 --> 00:31:08,686 for someone who's username matches the username 728 00:31:08,686 --> 00:31:10,586 that I typed in." 729 00:31:10,706 --> 00:31:12,816 So were gonna say, "Okay, I wanna get that result. 730 00:31:13,306 --> 00:31:17,006 And if there is one person whose username matches 731 00:31:17,086 --> 00:31:19,196 because we can't have two people at the username DJM 732 00:31:19,366 --> 00:31:20,486 or we're gonna confuse David. 733 00:31:20,486 --> 00:31:24,356 So if there's exactly one person and this username exists, 734 00:31:24,356 --> 00:31:27,526 then that's when we wanna check what their password is." 735 00:31:28,536 --> 00:31:32,056 So now this is where we're comparing passwords. 736 00:31:32,056 --> 00:31:35,846 And so this is-- so this is a much more secure approach 737 00:31:36,156 --> 00:31:39,686 than we've used years previous but what we're saying is, 738 00:31:39,686 --> 00:31:41,586 "I'm gonna call this function crypt." 739 00:31:42,326 --> 00:31:43,966 And what crypt does is it's going 740 00:31:43,966 --> 00:31:46,736 to take your password and encrypt it." 741 00:31:47,326 --> 00:31:49,306 So when we create a new user, they're not-- 742 00:31:49,306 --> 00:31:52,066 we're not storing their actual password in a database. 743 00:31:52,396 --> 00:31:55,106 That will really be insecure because if you're like me 744 00:31:55,106 --> 00:31:57,186 and had a bunch of people registered for your site 745 00:31:57,186 --> 00:31:58,306 in the CS50 fair and they typed 746 00:31:58,306 --> 00:32:00,246 in like what the password they used for everything, 747 00:32:00,246 --> 00:32:01,336 you now know what their password is. 748 00:32:01,796 --> 00:32:03,916 And from our perspective that's really, really insecure 749 00:32:03,916 --> 00:32:05,376 because even though that's cool and you can login 750 00:32:05,376 --> 00:32:07,416 to their Gmail now you shouldn't actually have the right 751 00:32:07,416 --> 00:32:08,106 to know their password. 752 00:32:08,106 --> 00:32:11,666 So for security features, for security purposes, 753 00:32:11,836 --> 00:32:12,696 we're going to encrypt that. 754 00:32:13,236 --> 00:32:15,036 So when we store the password in the database, 755 00:32:15,036 --> 00:32:16,476 we're just gonna see some long-- 756 00:32:16,746 --> 00:32:18,426 what looks like meaningless string of characters 757 00:32:18,426 --> 00:32:20,946 that has what we-- what we perceive has no relation 758 00:32:20,946 --> 00:32:21,866 to their actual password. 759 00:32:22,636 --> 00:32:25,576 And so in order to convert this plain text password 760 00:32:25,576 --> 00:32:26,976 to this encrypted password, 761 00:32:27,306 --> 00:32:28,786 it's gonna be an algorithm that's a little more 762 00:32:28,786 --> 00:32:32,206 sophisticated than Visionaire but in order to invoke it, 763 00:32:32,206 --> 00:32:34,316 we don't need to know how it works we just need to know 764 00:32:34,546 --> 00:32:37,366 that this magical function crypt is going to do it for us. 765 00:32:38,006 --> 00:32:41,106 And so now, if we encrypt the password that was typed in 766 00:32:41,286 --> 00:32:43,546 and that matches the encrypted password in our database 767 00:32:43,746 --> 00:32:47,416 that must mean that the user typed in the right password. 768 00:32:48,126 --> 00:32:50,386 Because if they typed in a different password, that's going 769 00:32:50,386 --> 00:32:51,466 to hash to something else, 770 00:32:52,426 --> 00:32:54,766 which means that these two passwords don't match. 771 00:32:55,456 --> 00:32:58,396 Does that make sense? 772 00:32:58,566 --> 00:33:00,706 So here, we're effectively comparing what they typed 773 00:33:00,706 --> 00:33:03,056 in to what we remembered as their password, 774 00:33:03,056 --> 00:33:06,206 but we don't need to know what their password actually is 775 00:33:06,246 --> 00:33:08,426 in order to that. 776 00:33:08,426 --> 00:33:10,686 So if this is true, if these two hashes match 777 00:33:10,916 --> 00:33:13,046 that means the user typed in the right password and at 778 00:33:13,046 --> 00:33:15,636 that point we can log them in because we know 779 00:33:15,636 --> 00:33:17,556 that those credentials they entered must be valid. 780 00:33:17,816 --> 00:33:19,526 So they must actually be the persons they're trying 781 00:33:19,526 --> 00:33:20,116 to login as. 782 00:33:20,116 --> 00:33:22,926 So what we wanna do is we wanna remember 783 00:33:22,926 --> 00:33:24,956 who they are inside of our session. 784 00:33:25,676 --> 00:33:28,096 So remember that because we included common.php 785 00:33:28,096 --> 00:33:32,976 at the top here and that called that function session_start, 786 00:33:33,626 --> 00:33:34,986 that means that were now green light 787 00:33:34,986 --> 00:33:36,676 to use this magic session variable. 788 00:33:37,466 --> 00:33:39,356 So as we go through our different pages, 789 00:33:39,666 --> 00:33:41,186 we're going to store inside it-- 790 00:33:41,186 --> 00:33:43,916 we're gonna able to use what's inside of this session variable. 791 00:33:44,426 --> 00:33:46,706 So this session is basically just an array. 792 00:33:47,186 --> 00:33:50,016 Again it's an associative array where instead of using numbers 793 00:33:50,016 --> 00:33:52,966 to access buckets, we access those buckets just with strings. 794 00:33:53,126 --> 00:33:54,446 So again just to be cache table. 795 00:33:55,106 --> 00:33:57,106 So inside of ID, this key ID, 796 00:33:57,266 --> 00:33:59,836 we're going to store the user's ID. 797 00:34:00,686 --> 00:34:02,606 So every user is gonna have some unique ID 798 00:34:02,606 --> 00:34:05,416 and it's probably just gonna be a number the way we've set it 799 00:34:05,416 --> 00:34:05,646 up now. 800 00:34:06,286 --> 00:34:10,756 So if we take a look at our database, and to do that, 801 00:34:11,006 --> 00:34:14,006 I just want to, again, that same IP address 802 00:34:14,166 --> 00:34:16,796 and I want to /phpmyadmin. 803 00:34:17,276 --> 00:34:19,106 So this is already installed in the appliance for you. 804 00:34:19,386 --> 00:34:23,006 If you go to this URL, you can login with jharvard crimson 805 00:34:23,286 --> 00:34:25,616 and take a look at the database that we set up for you. 806 00:34:26,886 --> 00:34:28,286 So here's what my database looks like. 807 00:34:28,676 --> 00:34:31,746 So you'll see that each of these users has unique ID, 808 00:34:32,346 --> 00:34:34,236 it's just a number and it's different for everybody. 809 00:34:34,816 --> 00:34:37,486 So here's our username and here's our encrypted password. 810 00:34:38,286 --> 00:34:41,366 So we don't actually get to see what David's password is, 811 00:34:41,576 --> 00:34:43,846 instead we just see this random string of characters 812 00:34:43,886 --> 00:34:46,896 that doesn't tell us really anything about his password. 813 00:34:47,576 --> 00:34:50,176 So when David logs in, we're comparing this string 814 00:34:50,386 --> 00:34:52,416 to the hash of whatever it is that David typed in. 815 00:34:53,476 --> 00:34:57,056 So it's this ID that because it's unique to every user, 816 00:34:57,056 --> 00:34:59,646 we can use it to identify which user we are. 817 00:35:00,116 --> 00:35:02,806 So if we just remember this ID number then we can remember 818 00:35:02,806 --> 00:35:05,396 through all of our pages what user is currently logged in 819 00:35:05,626 --> 00:35:06,756 and take action accordingly. 820 00:35:07,926 --> 00:35:08,516 That makes sense? 821 00:35:08,676 --> 00:35:09,936 How we're logging somebody in? 822 00:35:10,386 --> 00:35:10,486 Yup? 823 00:35:11,076 --> 00:35:14,876 >> Where is the crypt hash function stored? 824 00:35:14,876 --> 00:35:16,976 >> So where is the crypt hash function stored? 825 00:35:17,796 --> 00:35:19,626 So when we're just logging someone in, 826 00:35:19,626 --> 00:35:22,136 we don't actually need to store the value, we'll just need 827 00:35:22,136 --> 00:35:23,796 to compare it to what's already there. 828 00:35:24,626 --> 00:35:28,326 So if this row hash says the row of my table 829 00:35:28,326 --> 00:35:30,226 that I just selected-- so if I-- 830 00:35:30,226 --> 00:35:33,466 my username is Malan then I'm now looking at the row 831 00:35:33,466 --> 00:35:34,376 that starts with Malan. 832 00:35:35,106 --> 00:35:38,706 And if that has password value is equal to the hash 833 00:35:38,706 --> 00:35:41,266 of whatever the user typed in, then we're okay. 834 00:35:41,806 --> 00:35:44,606 So when we login, we don't actually store this anywhere. 835 00:35:44,696 --> 00:35:46,966 This already must exist in the database, right, 836 00:35:46,966 --> 00:35:48,696 because if it didn't, then we couldn't login 837 00:35:48,696 --> 00:35:50,126 because that user doesn't exist yet. 838 00:35:50,746 --> 00:35:52,516 So in this case, and this is gonna be different 839 00:35:52,516 --> 00:35:55,016 when registered users, but for just logging in, 840 00:35:55,276 --> 00:35:57,316 we assumed that it already exists so we don't need 841 00:35:57,316 --> 00:35:59,816 to store anywhere 'cause we're just reading from the database, 842 00:35:59,816 --> 00:36:00,656 we're not writing to it. 843 00:36:01,916 --> 00:36:02,396 That makes sense? 844 00:36:02,706 --> 00:36:02,773 >> Yeah. 845 00:36:03,366 --> 00:36:03,966 >> Other questions? 846 00:36:04,806 --> 00:36:04,946 Yup? 847 00:36:04,946 --> 00:36:08,496 >> Where is the crypt function included? 848 00:36:08,496 --> 00:36:09,946 >> So where is the crypt function included? 849 00:36:10,016 --> 00:36:12,356 So just like things like print F and other stuff like that, 850 00:36:12,556 --> 00:36:14,436 this is just part of PHP. 851 00:36:14,436 --> 00:36:15,346 So this is written for you 852 00:36:15,346 --> 00:36:17,466 and it's just automatically included. 853 00:36:17,466 --> 00:36:20,486 And PHP has a lot of functions like a lot, like as soon 854 00:36:20,486 --> 00:36:22,216 as someone thought a function was a good idea, 855 00:36:22,216 --> 00:36:23,656 they just wrote it and duct tape it. 856 00:36:23,916 --> 00:36:25,206 So there's probably a function 857 00:36:25,206 --> 00:36:26,646 for anything you can possibly think 858 00:36:26,646 --> 00:36:28,366 of in PHP, which is fantastic. 859 00:36:29,476 --> 00:36:30,136 Other questions? 860 00:36:30,676 --> 00:36:35,846 Okay. So that's our logging someone in, to log someone 861 00:36:35,846 --> 00:36:37,606 in just means I'm gonna remember who you are 862 00:36:37,866 --> 00:36:40,926 and as you visit all these other pages I know you passed my 863 00:36:41,226 --> 00:36:43,656 authentication somehow, so you must be the person 864 00:36:43,656 --> 00:36:45,806 that I'm remembering right now. 865 00:36:47,026 --> 00:36:50,426 So now let's dissect this select query a little bit more. 866 00:36:50,996 --> 00:36:53,196 So SQL says for structured query language 867 00:36:53,396 --> 00:36:55,726 and it's not really a programming language as much 868 00:36:55,726 --> 00:36:58,956 as a way of describing how to retrieve data from a database. 869 00:36:59,516 --> 00:37:02,976 So the query we saw before was some select from users 870 00:37:02,976 --> 00:37:05,506 where username equals and we use a dollar sign username. 871 00:37:06,256 --> 00:37:08,036 So we don't just have to have a constant here, 872 00:37:08,036 --> 00:37:09,656 but if we say dollar sign username, 873 00:37:09,956 --> 00:37:11,676 then PHP is smart enough to say, "Okay, well, 874 00:37:11,676 --> 00:37:13,786 there's some variable username, I wanna use that, 875 00:37:14,256 --> 00:37:15,726 instead of the word username." 876 00:37:16,756 --> 00:37:18,826 So maybe that's why they decided variables just start the 877 00:37:18,826 --> 00:37:19,596 dollar sign. 878 00:37:20,046 --> 00:37:22,476 So this first part is gonna be my verb, 879 00:37:22,776 --> 00:37:24,096 what am I doing from the database? 880 00:37:24,176 --> 00:37:25,456 Well, I'm selecting data. 881 00:37:26,106 --> 00:37:27,296 What data do I wanna select? 882 00:37:27,756 --> 00:37:29,816 Well, remember the star means everything, so this says, 883 00:37:29,816 --> 00:37:31,906 "I wanna get every single column 884 00:37:32,256 --> 00:37:33,606 from the row that I'm selecting." 885 00:37:34,466 --> 00:37:37,406 So our database can have multiple tables so these 886 00:37:37,496 --> 00:37:40,566 from users that says that there's some table called users 887 00:37:40,746 --> 00:37:41,896 and I wanna get data from that. 888 00:37:42,096 --> 00:37:43,926 So I can have a bunch of tables and each 889 00:37:43,926 --> 00:37:46,176 of those tables must have a unique name so we know 890 00:37:46,176 --> 00:37:46,986 where to grab data from. 891 00:37:48,046 --> 00:37:50,886 Now this "where" is the condition that must be met 892 00:37:51,206 --> 00:37:52,656 in order for the row to be returned. 893 00:37:53,176 --> 00:37:55,416 So we're saying, "I want every single row 894 00:37:55,656 --> 00:37:56,946 where the username is Malan." 895 00:37:57,686 --> 00:38:00,026 Now for the user's table that's only gonna be one row. 896 00:38:00,736 --> 00:38:03,986 But it can be the case that this be returned more than one row. 897 00:38:05,006 --> 00:38:07,506 So if we said, "Well, I wanna get everything from users 898 00:38:07,506 --> 00:38:09,566 where either I'm logged in as David 899 00:38:09,736 --> 00:38:12,416 or that person has less than 9,000 dollars." 900 00:38:13,226 --> 00:38:16,456 So this will return an array of rows not just necessarily 1. 901 00:38:17,086 --> 00:38:19,116 So if we don't wanna select every single column, 902 00:38:19,116 --> 00:38:21,706 we can actually list out the column names we wanna select. 903 00:38:22,346 --> 00:38:24,566 So we can say I wanna select the username in the hash, 904 00:38:24,566 --> 00:38:25,576 I don't really care about the ID, 905 00:38:25,576 --> 00:38:28,046 this is actually gonna be faster as far 906 00:38:28,046 --> 00:38:29,206 as [inaudible] is concerned 'cause we don't need 907 00:38:29,206 --> 00:38:30,386 to read every single column. 908 00:38:30,856 --> 00:38:33,586 So I just want these two things, again, I've [inaudible] users 909 00:38:33,826 --> 00:38:35,426 but this time instead of equal to Malan, 910 00:38:35,426 --> 00:38:36,556 I'm saying not equal to Malan. 911 00:38:37,636 --> 00:38:38,326 Make sense? 912 00:38:38,776 --> 00:38:41,566 And finally, if we don't wanna return the rows in cells 913 00:38:41,866 --> 00:38:44,546 but instead want to return how many rows were returned, 914 00:38:44,806 --> 00:38:46,556 I can say something like "Select Count." 915 00:38:47,116 --> 00:38:48,266 This count is gonna say, "Well, 916 00:38:48,266 --> 00:38:51,146 I don't actually want the column data, I just want how many 917 00:38:51,146 --> 00:38:52,886 of those-- how many of the rows there are." 918 00:38:53,476 --> 00:38:56,146 So if we wanted to know inside of CS50 Finance, 919 00:38:56,146 --> 00:38:59,316 how many users right now have cash that's greater than 9,000? 920 00:38:59,466 --> 00:39:00,866 We could run some query like this. 921 00:39:01,356 --> 00:39:03,026 So sites like Facebook who say, you know, 922 00:39:03,026 --> 00:39:05,826 we have 750 million users, they probably just-- 923 00:39:05,876 --> 00:39:07,136 well, not really, but they probably just said 924 00:39:07,136 --> 00:39:08,946 like a select count from users that said, well, 925 00:39:08,946 --> 00:39:10,446 how many rows are inside of my database? 926 00:39:10,846 --> 00:39:11,636 So now I can write Facebook. 927 00:39:12,086 --> 00:39:14,656 So that's the SQL. 928 00:39:14,656 --> 00:39:16,456 But SQL is not a programming language. 929 00:39:16,736 --> 00:39:20,116 PHP is our programing language that's going to utilize SQL. 930 00:39:20,796 --> 00:39:23,596 So here are one, two or three, six-step process for using it. 931 00:39:24,396 --> 00:39:28,176 So the first thing we need to do is to connect to our database. 932 00:39:28,646 --> 00:39:30,146 So this is where those constants come 933 00:39:30,146 --> 00:39:31,426 in that we saw on constants.php. 934 00:39:31,616 --> 00:39:36,646 We basically need to login to our database from PHP. 935 00:39:36,646 --> 00:39:39,366 So this is just another security measure, right. 936 00:39:39,366 --> 00:39:42,386 If we have some password in our database that's separate 937 00:39:42,386 --> 00:39:43,576 from the password on our server, 938 00:39:43,826 --> 00:39:45,156 that means that if our server gets hacked, 939 00:39:45,456 --> 00:39:47,596 that means that whoever hacked us might not necessarily have 940 00:39:47,596 --> 00:39:49,676 all of our database information which is really good 941 00:39:49,676 --> 00:39:51,306 if your database has like credit card numbers 942 00:39:51,306 --> 00:39:52,646 which hopefully your final project doesn't. 943 00:39:52,646 --> 00:39:55,696 So we're gonna connect to the database with this username 944 00:39:55,696 --> 00:39:56,986 and password that we specified 945 00:39:56,986 --> 00:40:01,976 and after we connect we're going to select a database. 946 00:40:02,046 --> 00:40:03,426 >> So a database can have multiple tables 947 00:40:03,426 --> 00:40:05,276 but we can also have multiple databases 948 00:40:05,486 --> 00:40:06,726 that contain multiple tables. 949 00:40:07,276 --> 00:40:09,216 So the purpose of this pset, you're just working 950 00:40:09,216 --> 00:40:11,486 with one single database called pset7. 951 00:40:12,126 --> 00:40:15,216 And everything inside the database pset7 has all the 952 00:40:15,216 --> 00:40:17,236 tables that you need for this entire pset. 953 00:40:17,776 --> 00:40:19,576 So this DB_NAME is just a constant. 954 00:40:19,576 --> 00:40:22,106 It's never gonna change for the purposes of this pset. 955 00:40:22,666 --> 00:40:23,986 So we're just gonna use pset7. 956 00:40:25,186 --> 00:40:27,546 So now we can start running these queries. 957 00:40:28,106 --> 00:40:29,916 So we just saw an example of the select queries. 958 00:40:29,916 --> 00:40:32,766 So if I say "SELECT star FROM users," that means I'm going 959 00:40:32,766 --> 00:40:34,586 to get my entire user's table. 960 00:40:34,586 --> 00:40:37,386 I want every column and I have no condition 961 00:40:37,386 --> 00:40:38,796 so this is gonna return every row. 962 00:40:38,796 --> 00:40:41,876 So it's not gonna actually execute that statement 963 00:40:41,876 --> 00:40:44,016 yet because we've just created the string. 964 00:40:44,616 --> 00:40:48,866 In order to actually run that query we wanna say my SQL query 965 00:40:48,866 --> 00:40:50,956 and then pass in whatever our query was. 966 00:40:51,426 --> 00:40:52,566 So because we stored this 967 00:40:52,566 --> 00:40:54,886 in a variable called dollar sign query, 968 00:40:55,436 --> 00:40:56,856 that's how it knows what query to run. 969 00:40:57,346 --> 00:40:59,806 So it's going to return this result object 970 00:40:59,806 --> 00:41:03,296 and this result object contains all of the rows 971 00:41:03,686 --> 00:41:04,856 that returned by this query. 972 00:41:04,856 --> 00:41:08,726 So to iterate through those rows, you can say something 973 00:41:08,726 --> 00:41:11,426 like mysql_fetch_array from a result. 974 00:41:12,216 --> 00:41:14,916 So this is very similar to using this wild [inaudible] kind 975 00:41:14,916 --> 00:41:15,336 of thing. 976 00:41:15,486 --> 00:41:18,246 We're gonna have just like inside 977 00:41:18,246 --> 00:41:21,186 of our file some cursor inside of our result object. 978 00:41:21,736 --> 00:41:23,546 So if I called mysql_fetch_array, 979 00:41:23,816 --> 00:41:26,986 the first time I call that, I'm gonna get back the first row 980 00:41:26,986 --> 00:41:28,166 that was returned from my query. 981 00:41:28,796 --> 00:41:31,626 It's gonna be stored inside of this PHP array row. 982 00:41:32,136 --> 00:41:33,696 So from that array I can say something 983 00:41:33,696 --> 00:41:35,776 like row zero or row username. 984 00:41:36,286 --> 00:41:38,526 And if I call mysql_fetch_array again, 985 00:41:39,106 --> 00:41:40,336 it's going to give the next row. 986 00:41:40,336 --> 00:41:42,686 So you can kind of see how it can iterate 987 00:41:42,686 --> 00:41:43,846 through all the results of our query. 988 00:41:43,846 --> 00:41:45,046 We can just say "well, 989 00:41:45,046 --> 00:41:47,076 mysql_fetch_array returned something, 990 00:41:47,616 --> 00:41:50,376 that means I must have another row to go through and iterate 991 00:41:50,376 --> 00:41:52,836 through it-- you know, whatever it is that we need to do, 992 00:41:52,836 --> 00:41:54,416 print out the values or something like that." 993 00:41:55,296 --> 00:41:56,536 So questions on the structure? 994 00:41:56,536 --> 00:41:56,626 Yup? 995 00:41:56,626 --> 00:42:05,486 >> Do you ever have to say that something is SQL and-- 996 00:42:05,486 --> 00:42:06,136 but then brackets are not? 997 00:42:06,136 --> 00:42:07,686 >>So do we have the same brackets for SQL? 998 00:42:07,686 --> 00:42:10,966 We don't actually we can just say that this entire string 999 00:42:10,966 --> 00:42:12,316 that you're passing to mysql query 1000 00:42:12,516 --> 00:42:14,216 that entire thing is just a SQL thing. 1001 00:42:14,946 --> 00:42:17,386 And so if you have a syntax error in your SQL 1002 00:42:17,416 --> 00:42:19,286 or that query failed for some reason, 1003 00:42:19,446 --> 00:42:22,106 then this function mysql_query is gonna return null. 1004 00:42:22,106 --> 00:42:24,816 So that's a good if you're concerned about error checking 1005 00:42:24,816 --> 00:42:26,626 in which you are, that's a good thing to check. 1006 00:42:26,756 --> 00:42:28,776 What do this function actually returned, did it worked, 1007 00:42:28,776 --> 00:42:32,406 did I have a syntax error, or something like that. 1008 00:42:33,056 --> 00:42:33,786 Yup? 1009 00:42:34,186 --> 00:42:36,756 >> You said that mysql_fetch_array [inaudible]? 1010 00:42:36,756 --> 00:42:38,886 >> Yes, mysql_fetch_array will get one row at a time just 1011 00:42:38,886 --> 00:42:41,416 like something like fgets would get one line 1012 00:42:41,416 --> 00:42:42,436 at a time from a string. 1013 00:42:42,686 --> 00:42:47,456 >> So what kind of index can you use to [inaudible]? 1014 00:42:47,636 --> 00:42:50,106 >> So what kind of index can you use to kinda jump to a row? 1015 00:42:50,306 --> 00:42:53,056 So this you can't really just jump to, say, the third row. 1016 00:42:53,726 --> 00:42:55,946 There's kind of almost no need to do that really just 1017 00:42:55,946 --> 00:42:58,876 like if you can think of about a problem that would need to jump 1018 00:42:58,876 --> 00:43:01,026 like the third row to solve, doesn't really exist 1019 00:43:01,026 --> 00:43:02,906 because you could probably just refine your SQL query 1020 00:43:02,906 --> 00:43:04,446 to only get that row or something. 1021 00:43:04,826 --> 00:43:05,806 So the most common thing 1022 00:43:05,806 --> 00:43:08,606 that we're gonna do is either just get the single row, 1023 00:43:08,606 --> 00:43:10,166 in much case we're just gonna call it once, 1024 00:43:10,426 --> 00:43:12,506 or we need to iterate through some set of rows. 1025 00:43:12,696 --> 00:43:14,706 And to do that, we're just gonna need to put that in to the loop. 1026 00:43:14,706 --> 00:43:16,976 So because those are the two most common things you're gonna 1027 00:43:16,976 --> 00:43:18,416 need to do with the mysql result, 1028 00:43:18,516 --> 00:43:22,386 that's just the way this function was designed. 1029 00:43:22,506 --> 00:43:23,886 Other questions on using SQL? 1030 00:43:24,336 --> 00:43:30,436 Okay. So let's jump in to the five parts of this pset. 1031 00:43:31,026 --> 00:43:34,086 So the first thing we need to do is allow our users to register. 1032 00:43:34,876 --> 00:43:35,876 So to do that, we're gonna need 1033 00:43:35,876 --> 00:43:39,106 to create some new page that's equivalent to login.php 1034 00:43:39,526 --> 00:43:41,826 that displays a form to the user that allows them 1035 00:43:41,826 --> 00:43:43,326 to choose a username and password. 1036 00:43:44,106 --> 00:43:46,526 Now we need-- from that form we need to pass it 1037 00:43:46,526 --> 00:43:48,506 to some other file that's gonna do something 1038 00:43:48,506 --> 00:43:51,026 like make sure our passwords match 'cause we're asking you 1039 00:43:51,026 --> 00:43:53,036 to say type in the password, confirm your password. 1040 00:43:53,366 --> 00:43:55,046 So make sure that those are valid, 1041 00:43:55,176 --> 00:43:57,986 make sure the username doesn't already exist and that 1042 00:43:57,986 --> 00:43:59,346 if all those [inaudible] check passed, 1043 00:43:59,806 --> 00:44:02,026 then we actually need to create a new user. 1044 00:44:03,336 --> 00:44:04,636 So to display a new form, 1045 00:44:04,886 --> 00:44:07,416 if you like to practice your HTML then you can just start off 1046 00:44:07,416 --> 00:44:09,556 with the new blank PHP file and start writing 1047 00:44:09,846 --> 00:44:10,936 but if you're pressed for time 1048 00:44:10,936 --> 00:44:13,646 like I'm sure you are then you probably just wanna start off 1049 00:44:13,646 --> 00:44:16,066 with the copying login.php into register.php. 1050 00:44:16,066 --> 00:44:19,676 And so now we just have this really nice framework we can 1051 00:44:19,676 --> 00:44:22,236 start operating with because we only need 1052 00:44:22,236 --> 00:44:23,446 to change a couple of things. 1053 00:44:23,966 --> 00:44:25,836 The first thing we need to change is going 1054 00:44:25,836 --> 00:44:28,146 to be this action, so where it send to. 1055 00:44:28,146 --> 00:44:30,826 So no longer do we wanna send the data to login2.php, 1056 00:44:30,826 --> 00:44:33,146 because login2 is gonna login the user 1057 00:44:33,146 --> 00:44:35,456 and we're trying to register a user. 1058 00:44:36,366 --> 00:44:38,706 Instead, we wanna send it to some file 1059 00:44:38,706 --> 00:44:41,756 that we can call register2.php. 1060 00:44:41,756 --> 00:44:44,066 So after we change that attribute, we also need 1061 00:44:44,066 --> 00:44:45,736 to create a new password field. 1062 00:44:46,256 --> 00:44:48,946 So just like we saw those input name equals username you just 1063 00:44:48,946 --> 00:44:52,146 need to create a new one that has a name like password two 1064 00:44:52,146 --> 00:44:54,196 or confirmed password or something like that. 1065 00:44:54,656 --> 00:44:56,036 So that when the user enters data 1066 00:44:56,036 --> 00:45:00,236 into that it gets passed along to this register2.php file. 1067 00:45:00,736 --> 00:45:01,876 So that's pretty straightforward. 1068 00:45:01,876 --> 00:45:06,696 Any questions on the HTML part of this? 1069 00:45:06,886 --> 00:45:09,626 Okay. So now for the server side logic. 1070 00:45:10,246 --> 00:45:12,146 So the first that you need to do is make sure 1071 00:45:12,146 --> 00:45:14,326 that nothing is blank, because if the user typed 1072 00:45:14,326 --> 00:45:15,886 in something blank then we can't allow them 1073 00:45:15,886 --> 00:45:17,386 to register 'cause that's gonna be an error. 1074 00:45:18,126 --> 00:45:20,466 So assuming all these things are not blank, we now just need 1075 00:45:20,466 --> 00:45:21,756 to make sure that the password 1076 00:45:21,756 --> 00:45:23,336 and the confirmed password match. 1077 00:45:24,066 --> 00:45:26,776 In this-- And at this point, this might be your favorite part 1078 00:45:27,076 --> 00:45:32,066 of PHP because at long last you can just say if A equals B, 1079 00:45:32,066 --> 00:45:33,306 and A and B are strings, 1080 00:45:33,306 --> 00:45:35,996 this will actually work 'cause you no longer have to worry 1081 00:45:35,996 --> 00:45:37,726 about memory addresses and pointers 1082 00:45:37,726 --> 00:45:38,976 and whatever that was any way. 1083 00:45:39,486 --> 00:45:41,946 So the first time you type this you should just be so excited 1084 00:45:41,946 --> 00:45:43,136 that you can finally do this. 1085 00:45:43,806 --> 00:45:46,556 So we just need to compare password and password2. 1086 00:45:46,766 --> 00:45:48,236 If they're the same, we can keep going. 1087 00:45:48,236 --> 00:45:51,396 If they're not the same, then we can invoke this apologize 1088 00:45:51,396 --> 00:45:53,566 function that is especially written 1089 00:45:53,566 --> 00:45:54,926 to display some error message. 1090 00:45:54,926 --> 00:45:57,896 So we can just say, "apologize your passwords didn't match" 1091 00:45:57,896 --> 00:45:59,886 or whatever it is that [inaudible] solution says. 1092 00:46:01,096 --> 00:46:03,776 So questions on that bit? 1093 00:46:03,966 --> 00:46:06,606 So similarly, we wanna make sure 1094 00:46:06,606 --> 00:46:08,336 that what they've entered is a valid username. 1095 00:46:09,126 --> 00:46:12,746 So if you set your database up the way the pset suggests 1096 00:46:12,826 --> 00:46:16,256 with the unique key on username then SQL is gonna say, "Okay, 1097 00:46:16,486 --> 00:46:18,476 everything inside of this username column needs 1098 00:46:18,476 --> 00:46:19,076 to be unique. 1099 00:46:19,546 --> 00:46:21,296 So if you try to insert something 1100 00:46:21,296 --> 00:46:23,356 with the same username I'm going to fail. 1101 00:46:24,296 --> 00:46:26,876 So if the query fails, we know that, well, 1102 00:46:27,006 --> 00:46:29,176 mysql_query is gonna return null. 1103 00:46:29,766 --> 00:46:32,236 So in the event that this query fails that might mean 1104 00:46:32,236 --> 00:46:33,576 that they tried to do-- the user tried 1105 00:46:33,576 --> 00:46:36,956 to insert the same username as something that already existed. 1106 00:46:37,786 --> 00:46:40,386 So if this query fails for this reason or some other reason, 1107 00:46:40,646 --> 00:46:43,236 we just wanna apologize again saying there's some error 1108 00:46:43,236 --> 00:46:45,326 like maybe you typed in a duplicate username. 1109 00:46:46,456 --> 00:46:48,826 Make sense? 1110 00:46:49,026 --> 00:46:49,176 Yup? 1111 00:46:49,176 --> 00:46:50,306 [ Inaudible Remark ] 1112 00:46:50,306 --> 00:46:53,816 >> Sure. So I was saying here is 1113 00:46:53,816 --> 00:46:56,716 that mysql_query is gonna return null if you try 1114 00:46:56,716 --> 00:46:59,526 to insert a non-unique value into a column 1115 00:46:59,526 --> 00:47:01,606 that you've said this must be unique. 1116 00:47:02,296 --> 00:47:03,966 My SQL is smart enough to do that for you. 1117 00:47:04,466 --> 00:47:06,636 If you'd like you could also select it yourself and look 1118 00:47:06,636 --> 00:47:09,016 for the username, if you don't find it, then insert it. 1119 00:47:09,126 --> 00:47:13,636 But this unique key is kind of a nice shortcut way of doing that. 1120 00:47:15,106 --> 00:47:17,856 So now, that we've done all of our error checking, 1121 00:47:17,856 --> 00:47:20,696 we actually want to add our new user to the table. 1122 00:47:21,666 --> 00:47:24,506 So we have a new SQL query, a new verb, 1123 00:47:24,806 --> 00:47:26,286 and now we're going to say "insert." 1124 00:47:26,936 --> 00:47:28,486 So the insert statement is going 1125 00:47:28,486 --> 00:47:31,116 to create a new row inside of our database. 1126 00:47:31,556 --> 00:47:33,506 So insert into the user's table 1127 00:47:33,866 --> 00:47:36,656 and that user's table I wanna modify these columns. 1128 00:47:37,046 --> 00:47:40,246 So I wanna give this user a username on some hash 1129 00:47:40,246 --> 00:47:42,506 which is their password and some cash. 1130 00:47:42,926 --> 00:47:45,216 So we're starting off with some default value for cash. 1131 00:47:45,926 --> 00:47:47,476 So those are the columns I wanna modify. 1132 00:47:47,766 --> 00:47:50,566 What I wanna insert into those columns I wanna say "values," 1133 00:47:50,566 --> 00:47:52,976 and then this is a list of the values I wanna insert. 1134 00:47:53,326 --> 00:47:55,286 So this Tommy corresponds to the username. 1135 00:47:55,636 --> 00:47:57,646 This supersecret password corresponds 1136 00:47:57,696 --> 00:47:58,956 to the hash of my password. 1137 00:47:58,956 --> 00:48:02,176 And then finally the cash corresponds to that column. 1138 00:48:02,616 --> 00:48:04,326 So you notice that because these are-- 1139 00:48:04,326 --> 00:48:06,106 the first two values are strings, 1140 00:48:06,446 --> 00:48:07,536 I've enclosed them in quotes. 1141 00:48:07,846 --> 00:48:10,526 But this last value is equivalent of a float 1142 00:48:10,526 --> 00:48:12,546 or in SQL it's called the decimal, so I don't need 1143 00:48:12,546 --> 00:48:14,396 to use quotes because it's just a number. 1144 00:48:15,226 --> 00:48:18,096 So when I actually say "mysql_query" 1145 00:48:18,096 --> 00:48:21,896 and I add this it's going to go into the database and modify it. 1146 00:48:21,896 --> 00:48:24,806 So after you visit that PHP file from your browser 1147 00:48:25,126 --> 00:48:28,706 that makes this call and go back into PHP myadmin and refresh, 1148 00:48:28,706 --> 00:48:29,956 you're going to have a different table, 1149 00:48:30,206 --> 00:48:31,756 hopefully, than you did before. 1150 00:48:33,156 --> 00:48:33,636 Make sense? 1151 00:48:34,126 --> 00:48:40,976 Alright, so remember that we're using the hash of the password 1152 00:48:40,976 --> 00:48:42,966 and not the password itself. 1153 00:48:43,176 --> 00:48:45,156 So we don't just wanna insert password, 1154 00:48:45,306 --> 00:48:47,846 we wanna insert crypt of the password. 1155 00:48:48,366 --> 00:48:50,276 So this function crypt, remember, is what's going 1156 00:48:50,276 --> 00:48:53,116 to return the hash value, we want to insert that, 1157 00:48:53,716 --> 00:48:57,376 not the password itself because login is looking at the hash. 1158 00:48:57,466 --> 00:48:59,786 If you do insert the password itself then you're not gonna be 1159 00:48:59,786 --> 00:49:01,586 able to login even if it's the right password. 1160 00:49:02,376 --> 00:49:02,696 Make sense? 1161 00:49:03,006 --> 00:49:08,336 Okay. And so after the user registers, we wanna be able 1162 00:49:08,336 --> 00:49:09,296 for them to be logged in. 1163 00:49:09,296 --> 00:49:11,826 And so to log them in, remember, it's really simple. 1164 00:49:12,176 --> 00:49:14,146 Login the user, just corresponds 1165 00:49:14,176 --> 00:49:16,096 to changing this session super global. 1166 00:49:16,456 --> 00:49:18,766 So if we just change that variable that's equivalent 1167 00:49:18,766 --> 00:49:19,856 to logging the user in. 1168 00:49:20,966 --> 00:49:22,476 So any questions on registration? 1169 00:49:22,816 --> 00:49:29,676 Alright, so now we need to worry about these stock quotes. 1170 00:49:30,626 --> 00:49:33,286 So this stock information is coming from Yahoo Finance. 1171 00:49:34,036 --> 00:49:36,756 But luckily, we don't really need to worry about how 1172 00:49:36,756 --> 00:49:38,386 that data is actually being retrieved. 1173 00:49:38,386 --> 00:49:40,086 So the first thing you need 1174 00:49:40,086 --> 00:49:42,656 to do again is create some new HTML file 1175 00:49:42,656 --> 00:49:44,726 that contains a form that's gonna send data 1176 00:49:45,066 --> 00:49:45,656 to some other file. 1177 00:49:46,366 --> 00:49:48,036 So following the convention that David setup, 1178 00:49:48,036 --> 00:49:48,986 we're gonna say "quote. 1179 00:49:48,986 --> 00:49:52,136 php is gonna display the form and quote2.php is 1180 00:49:52,136 --> 00:49:53,496 where the data is going to be sent to." 1181 00:49:54,176 --> 00:49:55,086 So we know how to do that. 1182 00:49:55,586 --> 00:49:57,926 And our form this time only needs a single row. 1183 00:49:58,216 --> 00:50:00,976 We're just looking up a single stock symbol. 1184 00:50:01,046 --> 00:50:04,296 >> So we're just gonna send that data this time to quote2.php. 1185 00:50:04,296 --> 00:50:06,026 Same thing that we're used to, we know how to do that. 1186 00:50:07,286 --> 00:50:09,486 So now, one of these functions defined inside 1187 00:50:09,486 --> 00:50:12,046 of helpers is this function called "lookup." 1188 00:50:12,626 --> 00:50:13,946 And what this function is going to do 1189 00:50:14,086 --> 00:50:16,636 for you is hit the Yahoo Finance API, 1190 00:50:17,166 --> 00:50:18,946 it's gonna ask all the information 1191 00:50:19,256 --> 00:50:21,036 about whatever stock symbol you pass it. 1192 00:50:22,026 --> 00:50:25,276 So this data is going to be returned into a stock object. 1193 00:50:26,306 --> 00:50:29,526 So as far as PHP is concerned, we have things 1194 00:50:29,526 --> 00:50:32,066 that are a little more powerful than structs called objects. 1195 00:50:32,386 --> 00:50:34,716 But for this pset, this S thing, 1196 00:50:34,716 --> 00:50:36,956 the stock thing is really just a struct. 1197 00:50:37,526 --> 00:50:39,936 So remember a struct just contain multiple members 1198 00:50:39,936 --> 00:50:42,446 and member to be different types, whatever. 1199 00:50:42,746 --> 00:50:45,976 So just like in C we have some struct, we wanna get 1200 00:50:45,976 --> 00:50:48,176 at something inside of it we're gonna use this arrow notation. 1201 00:50:48,776 --> 00:50:50,286 So the thing-- some of the things we were concerned 1202 00:50:50,286 --> 00:50:55,186 about is the stock symbol, stock name, stock price. 1203 00:50:55,336 --> 00:50:57,856 So from that variable we just need 1204 00:50:57,856 --> 00:50:59,086 to display this information. 1205 00:50:59,086 --> 00:51:01,886 So we see this a little bit earlier but we have a lot 1206 00:51:01,886 --> 00:51:05,346 of options for displaying data 'cause again PHP is a function 1207 00:51:05,346 --> 00:51:05,776 for everything. 1208 00:51:06,176 --> 00:51:10,866 So what we can do is we can say something like prints, price, 1209 00:51:11,116 --> 00:51:13,316 and then you notice this dot is the string 1210 00:51:13,316 --> 00:51:14,376 concatenation operator. 1211 00:51:14,816 --> 00:51:17,276 So if I have a string on the left and a string on the right, 1212 00:51:17,726 --> 00:51:19,816 this is like saying add those two strings together, 1213 00:51:19,876 --> 00:51:21,386 combine them into a single string. 1214 00:51:21,866 --> 00:51:23,526 So if I print out the concatenation 1215 00:51:23,526 --> 00:51:26,626 of the string price and then whatever value s 1216 00:51:26,626 --> 00:51:28,876 that price is I'm just gonna get a single string that's 1217 00:51:28,876 --> 00:51:29,386 displayed out. 1218 00:51:30,056 --> 00:51:32,626 If you really like typing percent D then printf is still 1219 00:51:32,626 --> 00:51:33,306 available to you. 1220 00:51:33,306 --> 00:51:37,266 And finally, if you want to instead of concatenating 1221 00:51:37,446 --> 00:51:40,016 or create some string that PHP is gonna say, "Okay, 1222 00:51:40,136 --> 00:51:41,396 I'm gonna jump in to this string 1223 00:51:41,396 --> 00:51:43,856 and I'm gonna substitute whatever is inside 1224 00:51:43,856 --> 00:51:46,476 of these brackets for the code that's inside of it." 1225 00:51:46,476 --> 00:51:48,936 So this code here is actually going to be executed." 1226 00:51:48,936 --> 00:51:51,206 PHP is gonna say, I want you to look at S price 1227 00:51:51,206 --> 00:51:53,216 and this is going to effectively return 1228 00:51:53,216 --> 00:51:55,616 into the string whatever S price was. 1229 00:51:56,076 --> 00:51:57,886 So this notation is just a little bit cleaner 1230 00:51:57,886 --> 00:52:00,826 than using the dot but it just says, "Well, everything inside 1231 00:52:00,826 --> 00:52:03,786 of these two braces just actually run that code 1232 00:52:03,786 --> 00:52:04,896 and returned that value." 1233 00:52:06,046 --> 00:52:07,106 Make sense? 1234 00:52:08,416 --> 00:52:11,346 So questions on actually displaying the stock information 1235 00:52:11,346 --> 00:52:16,956 or how are we gonna get that information? 1236 00:52:17,356 --> 00:52:21,176 Alright. Next we're gonna worry about buying stocks. 1237 00:52:21,906 --> 00:52:24,206 So in order to buy stocks, we need to do a little bit 1238 00:52:24,206 --> 00:52:25,966 of change in the design of our application. 1239 00:52:26,606 --> 00:52:29,486 So right now we just have a single table called users. 1240 00:52:30,096 --> 00:52:32,276 So inside of that user's table, we have a username, 1241 00:52:32,276 --> 00:52:34,086 a password we have how much money they have. 1242 00:52:34,956 --> 00:52:38,296 So what we can't really do is have that table keep track 1243 00:52:38,376 --> 00:52:40,186 of what stocks you own, right. 1244 00:52:40,186 --> 00:52:42,616 Having another column that's like a comma separated list 1245 00:52:42,616 --> 00:52:45,256 of stocks is pretty inelegant 'cause we need to keep track 1246 00:52:45,256 --> 00:52:48,366 of how many stocks they have and that's just kind of lame. 1247 00:52:48,926 --> 00:52:50,026 So the right way to do this is 1248 00:52:50,026 --> 00:52:54,146 to create a new table that's dedicated just to portfolios. 1249 00:52:54,436 --> 00:52:58,066 So inside of that table, we probably wanna keep track 1250 00:52:58,066 --> 00:53:01,396 of some the ID of the user, we wanna keep track 1251 00:53:01,396 --> 00:53:04,426 of what stock they bought, so the symbol that corresponds 1252 00:53:04,426 --> 00:53:05,666 to it or maybe the name of the stock. 1253 00:53:06,146 --> 00:53:08,416 And finally how many shares that were purchased. 1254 00:53:09,136 --> 00:53:11,216 So if our first SQL table have those columns, 1255 00:53:11,496 --> 00:53:13,796 we're gonna create some new tables maybe called portfolio 1256 00:53:13,796 --> 00:53:15,276 or whatever it is you wanna call it 1257 00:53:15,276 --> 00:53:17,536 and these are gonna be the columns of that table. 1258 00:53:18,176 --> 00:53:20,156 So here's just a diagram of what this looks like. 1259 00:53:20,656 --> 00:53:24,396 So if I'm a user and I buy a new stock then I'm gonna create a 1260 00:53:24,396 --> 00:53:27,576 new-- maybe a new row inside of my portfolio's table. 1261 00:53:28,296 --> 00:53:33,436 Now the ID of this row can correspond to the ID of the user 1262 00:53:33,436 --> 00:53:34,466 that purchased the stock. 1263 00:53:35,226 --> 00:53:37,786 So in this case, this ID is not unique, right. 1264 00:53:37,786 --> 00:53:41,126 Because as one user I have an ID like seven and if I own 1265 00:53:41,126 --> 00:53:43,766 like 10 stocks I'm gonna have 10 rows inside 1266 00:53:43,766 --> 00:53:44,886 of this portfolio's table. 1267 00:53:45,616 --> 00:53:47,546 So that's how we're kind of connecting these two things. 1268 00:53:47,546 --> 00:53:51,076 We're associating a row in the portfolio with the user. 1269 00:53:51,076 --> 00:53:54,526 And the way we do that is just have some column that's gonna be 1270 00:53:54,526 --> 00:53:56,546 the same value in both of the tables. 1271 00:53:57,606 --> 00:53:59,886 So then we can just store the symbol as a string 1272 00:53:59,886 --> 00:54:05,256 and the number of shares that I bought as an integer. 1273 00:54:05,256 --> 00:54:09,746 Questions on the table structure? 1274 00:54:10,966 --> 00:54:14,286 Alright. So HTML forms are so fun 'cause we love making them. 1275 00:54:14,636 --> 00:54:18,176 So now again, we need a symbol, a form that's gonna ask you 1276 00:54:18,176 --> 00:54:19,236 for what symbol you wanna buy. 1277 00:54:20,146 --> 00:54:22,706 So if you look at the staff solution which is 1278 00:54:22,706 --> 00:54:30,766 at cs50.net/finance, I'm gonna login as-- yes. 1279 00:54:32,336 --> 00:54:37,416 So now, if we do something like Get Quote, so Get Quote, 1280 00:54:37,416 --> 00:54:42,396 and here's our form that's gonna go to quote2, we have this link 1281 00:54:42,396 --> 00:54:43,816 that say's perhaps you like to buy it. 1282 00:54:44,546 --> 00:54:46,756 Now if I click buy, you'll notice 1283 00:54:46,756 --> 00:54:50,466 that this AAPL was pre populated for me, right. 1284 00:54:50,466 --> 00:54:52,136 In the way that came from was I said well, 1285 00:54:52,136 --> 00:54:53,736 I wanna quote for apple. 1286 00:54:53,736 --> 00:54:54,816 And when I said buy, 1287 00:54:55,376 --> 00:54:58,556 our handy-dandy staff solution was smart enough to recognize 1288 00:54:58,646 --> 00:55:00,796 that you don't have to type in AAPL again, 1289 00:55:00,796 --> 00:55:02,196 I'm just gonna type it in for you. 1290 00:55:03,146 --> 00:55:05,596 So if you look at the URL of this page, you might notice 1291 00:55:06,146 --> 00:55:12,526 that I'm in the wrong tab-- that we're still at buy.php but after 1292 00:55:12,526 --> 00:55:15,116 that we're saying symbol equals AAPL. 1293 00:55:16,076 --> 00:55:17,186 So that looks kind of fishy. 1294 00:55:17,186 --> 00:55:20,386 So let's change the symbol to something like GOOG. 1295 00:55:20,386 --> 00:55:23,626 You'll notice that I've just 1296 00:55:23,626 --> 00:55:27,956 by changing the URL I've changed what's inside of this text box. 1297 00:55:28,306 --> 00:55:33,546 So this is using a different super global this time called 1298 00:55:33,546 --> 00:55:33,796 "GET." 1299 00:55:34,736 --> 00:55:39,076 So POST is populated from any form that has a method of POST. 1300 00:55:40,086 --> 00:55:42,896 So as a corollary to POST we also have this global 1301 00:55:42,896 --> 00:55:43,666 called GET. 1302 00:55:44,246 --> 00:55:47,076 So GET is gonna be populated from any form 1303 00:55:47,326 --> 00:55:51,076 that has a method equal to GET or from the URL. 1304 00:55:51,076 --> 00:55:54,996 So if you submit a form in which you've said method get, 1305 00:55:55,376 --> 00:55:57,436 that form is actually going to inside 1306 00:55:57,436 --> 00:56:00,686 of the URL whatever values you've typed in to the form. 1307 00:56:01,286 --> 00:56:05,116 So the way it's gonna parsed is by saying, 1308 00:56:05,116 --> 00:56:08,026 we're gonna have a list of key value pairs. 1309 00:56:08,346 --> 00:56:10,526 So I'm gonna say key1 is gonna be some value 1310 00:56:10,606 --> 00:56:13,536 but we're gonna have the ampersand that's gonna separate 1311 00:56:13,536 --> 00:56:15,776 this key value pairs then I can have another one, 1312 00:56:16,036 --> 00:56:17,216 and so I can go on and on and on. 1313 00:56:17,766 --> 00:56:21,506 So if I say get any one of these keys I can get the value 1314 00:56:21,696 --> 00:56:23,726 that was passed in from the URL. 1315 00:56:24,826 --> 00:56:25,926 Make sense? 1316 00:56:26,836 --> 00:56:31,886 So now how did we prepopulate this data? 1317 00:56:31,926 --> 00:56:38,516 Well, if we go back into our login, so there's an attribute 1318 00:56:39,236 --> 00:56:41,166 of this input element called value. 1319 00:56:42,066 --> 00:56:45,686 So if I say value equals Tommy and save this form. 1320 00:56:46,246 --> 00:56:52,196 So let's go back to the web browser this is 1321 00:56:52,406 --> 00:56:53,856 my implementation. 1322 00:56:54,036 --> 00:56:57,166 We're gonna go back to login.php pset7. 1323 00:56:58,436 --> 00:57:01,826 So now you'll notice that Tommy was prepopulated. 1324 00:57:02,936 --> 00:57:05,846 Now remember that we don't necessarily have to have all 1325 00:57:05,846 --> 00:57:08,026 of our PHP at the top of our page. 1326 00:57:08,836 --> 00:57:11,086 So let's-- instead of saying Tommy, let's say something 1327 00:57:11,086 --> 00:57:18,086 like equals-- no, let's say Tommy 'cause [inaudible]. 1328 00:57:18,086 --> 00:57:21,366 So now, we have some PHP code. 1329 00:57:21,536 --> 00:57:25,506 So you notice that this is definitely PHP 1330 00:57:25,506 --> 00:57:28,856 because we have inside of it some bracket question mark 1331 00:57:29,126 --> 00:57:31,396 and so now we're evaluating this variable. 1332 00:57:32,106 --> 00:57:36,366 So if I go back into my web browser, 1333 00:57:37,446 --> 00:57:38,556 this is gonna be the same thing. 1334 00:57:38,836 --> 00:57:42,746 Well, out of practice, killed me. 1335 00:57:43,526 --> 00:57:45,166 So it's gonna be the same thing. 1336 00:57:45,496 --> 00:57:49,556 So we've evaluated this PHP code and we've put it into our HTML. 1337 00:57:49,556 --> 00:57:52,266 So this construction looks a little weird, right, 1338 00:57:52,266 --> 00:57:55,206 because we're evaluating PHP in middle of the double quote 1339 00:57:55,416 --> 00:57:56,546 but that's totally okay. 1340 00:57:56,926 --> 00:57:59,706 Because as the server is evaluating this PHP file, 1341 00:57:59,966 --> 00:58:02,196 it's gonna look for everywhere it sees any 1342 00:58:02,196 --> 00:58:04,626 of these bracket question marks whether they be either HTML 1343 00:58:04,696 --> 00:58:07,436 or your JavaScript or anywhere, and it's going to evaluate them. 1344 00:58:08,096 --> 00:58:10,446 So after the server runs this PHP file, 1345 00:58:10,616 --> 00:58:14,096 it's gonna get some static HTML file where this PHP is going 1346 00:58:14,096 --> 00:58:18,156 to have been replaced by with whatever it evaluated to. 1347 00:58:18,836 --> 00:58:20,206 Make sense? 1348 00:58:22,256 --> 00:58:25,486 Yeah. Alright, so now we need to worry 1349 00:58:25,486 --> 00:58:27,076 about actually adding the stock 1350 00:58:27,076 --> 00:58:29,256 that we just bought to our portfolio. 1351 00:58:30,606 --> 00:58:32,356 So again, don't forget that we're checking, 1352 00:58:32,356 --> 00:58:34,556 make sure that we're buying, you know, some valid number 1353 00:58:34,556 --> 00:58:37,056 of stocks, make sure that we're actually buying a stock 1354 00:58:37,056 --> 00:58:37,616 that exists. 1355 00:58:37,616 --> 00:58:39,766 So don't forget about all of our checking. 1356 00:58:40,396 --> 00:58:44,526 So now if have some valid stock, we wanna make sure 1357 00:58:44,526 --> 00:58:45,616 that the user can afford it. 1358 00:58:46,506 --> 00:58:49,706 And so that the user affording it means that the amount of cash 1359 00:58:49,876 --> 00:58:53,286 that they currently have is more than the cost of buying 1360 00:58:53,286 --> 00:58:54,486 that many shares of stock. 1361 00:58:55,636 --> 00:58:57,616 So the way we could do that, we can get the amount 1362 00:58:57,616 --> 00:58:59,266 of cash the user has, we can say, "Well, 1363 00:58:59,266 --> 00:59:01,736 I wanna select just the cash, I don't really care 1364 00:59:01,736 --> 00:59:03,906 about my password from the user's table 1365 00:59:03,906 --> 00:59:07,086 where this ID is equal to whatever the ID 1366 00:59:07,086 --> 00:59:09,066 of the currently logged in user is." 1367 00:59:09,446 --> 00:59:11,186 So remember that's just stored in our session. 1368 00:59:11,376 --> 00:59:12,866 And so we wanna look at session 1369 00:59:13,126 --> 00:59:16,566 to determine what value we wanna use for our ID in our query. 1370 00:59:17,826 --> 00:59:20,476 So now what if I'm a user and I buy Apple and I decided, "Well, 1371 00:59:20,476 --> 00:59:21,466 I wanna buy Apple again." 1372 00:59:22,336 --> 00:59:23,656 There're a couple of things I can do. 1373 00:59:24,216 --> 00:59:26,756 So the first is I can say, "Well, 1374 00:59:26,756 --> 00:59:28,686 if I buy Apple twice then I'm gonna have two rows 1375 00:59:28,686 --> 00:59:30,696 in my portfolio table that say Apple." 1376 00:59:30,696 --> 00:59:33,556 And when you display a portfolio you just wanna make sure 1377 00:59:33,556 --> 00:59:34,856 that you combine those two rows. 1378 00:59:34,856 --> 00:59:37,446 So inside of my portfolio I don't see Apple twice. 1379 00:59:37,906 --> 00:59:39,646 I see the sum of all my Apple quotes. 1380 00:59:40,606 --> 00:59:44,136 Or we can use this other SQL verb called update. 1381 00:59:45,136 --> 00:59:46,816 So update, unlike insert, 1382 00:59:47,036 --> 00:59:49,366 is going to only operate on an existing row. 1383 00:59:50,146 --> 00:59:52,386 So we're gonna say update the user's table 1384 00:59:52,786 --> 00:59:58,366 and I wanna set the column username equal to n00b wherever, 1385 00:59:58,746 --> 01:00:00,226 inside of the same row, 1386 01:00:00,466 --> 01:00:03,196 the username column already has a value Malan. 1387 01:00:04,046 --> 01:00:06,326 >> So what this says is throw out my table inside of a row, 1388 01:00:06,326 --> 01:00:07,856 every row that used to have a username 1389 01:00:07,856 --> 01:00:09,936 of Malan now has a username of n00b. 1390 01:00:10,396 --> 01:00:12,896 So these two column names don't necessarily have to match. 1391 01:00:13,186 --> 01:00:16,996 I could change Malan's cash by saying, "Set cash equals 0 1392 01:00:16,996 --> 01:00:18,326 where username equals Malan." 1393 01:00:18,886 --> 01:00:23,026 So after that, that's one way of inserting-- 1394 01:00:23,026 --> 01:00:25,126 of updating the amount of stocks you have. 1395 01:00:25,836 --> 01:00:29,176 So, the pset mentions it even fancier way that says, "insert" 1396 01:00:29,176 --> 01:00:33,576 and then "on duplicate key" or something like, "update values." 1397 01:00:33,676 --> 01:00:37,056 And so that's just a way of invoking this update verb 1398 01:00:37,056 --> 01:00:39,506 in the event that the stock already exists. 1399 01:00:40,036 --> 01:00:42,556 So all three of those approaches are totally valid, 1400 01:00:42,696 --> 01:00:44,656 some a little more straightforward than others. 1401 01:00:45,706 --> 01:00:48,766 Questions on SQL updates? 1402 01:00:49,916 --> 01:00:50,026 Yup> 1403 01:00:50,026 --> 01:00:50,286 [ Inaudible Remark ] 1404 01:00:50,286 --> 01:00:50,456 >> Yeah. 1405 01:00:51,516 --> 01:00:55,736 [ Inaudible Remark ] 1406 01:00:56,236 --> 01:00:57,506 >> So how would you actually type it? 1407 01:00:58,296 --> 01:01:00,046 So this is going to be a string 1408 01:01:00,046 --> 01:01:02,986 that we're gonna wanna pass to mysql_query. 1409 01:01:04,056 --> 01:01:07,126 So inside of our PHP file, we wanna have some string 1410 01:01:07,436 --> 01:01:10,006 that looks like this, except you wanna substitute 1411 01:01:10,006 --> 01:01:12,876 into that string probably some-- 1412 01:01:12,876 --> 01:01:16,456 the current username or whatever it is we're changing. 1413 01:01:16,456 --> 01:01:20,016 So we can substitute the ID to whatever our current logged 1414 01:01:20,016 --> 01:01:22,406 in ID is or whatever it is we're doing with our query. 1415 01:01:22,406 --> 01:01:25,576 We don't necessarily have to hard code in those values. 1416 01:01:26,106 --> 01:01:28,576 So from that string, you just wanna call the function 1417 01:01:28,776 --> 01:01:30,966 mysql_query on that string 1418 01:01:30,966 --> 01:01:32,886 and that's how this is gonna gets executed. 1419 01:01:34,416 --> 01:01:35,426 Other questions? 1420 01:01:35,956 --> 01:01:43,196 Okay. So finally, we just want to subtract the amount of cash. 1421 01:01:43,376 --> 01:01:46,686 So if I just bought a bunch of stocks and that price total 1422 01:01:46,686 --> 01:01:48,716 to a hundred dollars, then we wanna make sure 1423 01:01:48,716 --> 01:01:51,526 that I now subtract a hundred dollars from the amount 1424 01:01:51,526 --> 01:01:52,946 of money that that user has. 1425 01:01:54,136 --> 01:01:56,686 So now unlike-- so our cash is not stored 1426 01:01:56,686 --> 01:01:58,746 in the portfolio table anymore but we're back 1427 01:01:58,746 --> 01:01:59,796 into the user's table. 1428 01:02:00,456 --> 01:02:02,296 And so again, we wanna use an update statement. 1429 01:02:02,836 --> 01:02:04,516 Now, what's cool is we can actually say, 1430 01:02:04,516 --> 01:02:06,356 "We don't need two separate queries to say, 1431 01:02:06,356 --> 01:02:08,076 select the amount of cash, get that value, 1432 01:02:08,076 --> 01:02:09,626 and then update it and use that value." 1433 01:02:09,626 --> 01:02:12,896 You can actually just say, "Set cash equals cash minus" 1434 01:02:12,896 --> 01:02:14,696 and then however much the stocks cost. 1435 01:02:15,576 --> 01:02:18,066 So this is just a handy way of not having to query twice, 1436 01:02:18,066 --> 01:02:18,956 we can just say "cash." 1437 01:02:19,276 --> 01:02:21,966 That's gonna be the current value of the cash column 1438 01:02:22,096 --> 01:02:24,456 for the row in which user name equals Malan. 1439 01:02:25,496 --> 01:02:28,286 So remember that the price of the stock which we need 1440 01:02:28,286 --> 01:02:30,196 to calculate the number of shares times the price 1441 01:02:30,196 --> 01:02:32,876 of one share, that's coming from that lookup function. 1442 01:02:33,386 --> 01:02:35,936 So before you buy stock, we're gonna call Lookup on the symbol. 1443 01:02:36,216 --> 01:02:37,836 If we get back a valid stock object, 1444 01:02:37,936 --> 01:02:40,396 then we can determine how much it cost based 1445 01:02:40,396 --> 01:02:42,636 on the price attribute of that object. 1446 01:02:43,786 --> 01:02:44,886 Make sense? 1447 01:02:45,876 --> 01:02:50,136 So finally, selling stocks is gonna be very similar 1448 01:02:50,136 --> 01:02:52,876 to buying stocks 'cause again, we just need to operate 1449 01:02:52,966 --> 01:02:55,586 on a portfolio and then corresponding row 1450 01:02:55,586 --> 01:02:56,536 in the user's table. 1451 01:02:57,466 --> 01:03:01,096 So, in order to allow the user to remove stocks, 1452 01:03:01,196 --> 01:03:05,056 we need to display some list of what stocks they currently own 1453 01:03:05,436 --> 01:03:07,586 so they can select a stock to delete. 1454 01:03:08,206 --> 01:03:10,376 So in the staff solution, this is kind of a dropdown menu. 1455 01:03:10,746 --> 01:03:13,336 And how we got that was we wanna say, "Select star" 1456 01:03:13,776 --> 01:03:15,986 from portfolio where user name equals Malan. 1457 01:03:15,986 --> 01:03:18,156 So when you say, "I wanna get every stock 1458 01:03:18,506 --> 01:03:19,856 that this one user owns." 1459 01:03:20,436 --> 01:03:23,356 So from those stocks, I can choose to delete all 1460 01:03:23,356 --> 01:03:27,336 of the stocks that that user owns or sell them. 1461 01:03:27,336 --> 01:03:29,386 So to remove from the portfolio, 1462 01:03:30,026 --> 01:03:33,196 we could just say something like-- delete, a new SQL verb-- 1463 01:03:33,366 --> 01:03:36,266 "Delete from portfolio where username equals Malan 1464 01:03:36,266 --> 01:03:37,216 and symbol equals Apple." 1465 01:03:37,956 --> 01:03:40,066 So now this is saying every Apple stock 1466 01:03:40,286 --> 01:03:42,176 that Malan has is now deleted. 1467 01:03:43,396 --> 01:03:44,926 Pretty straightforward, any questions? 1468 01:03:45,366 --> 01:03:50,136 Alright. So after we've removed the stock from the portfolio, 1469 01:03:50,736 --> 01:03:55,246 we need to update the amount of cash that that user has. 1470 01:03:55,246 --> 01:03:57,196 So one thing that I really don't understand about this pset 1471 01:03:57,196 --> 01:03:59,096 when I did it is that when you sell the stock, 1472 01:03:59,336 --> 01:04:01,136 it sells for the current price of the stock, 1473 01:04:01,466 --> 01:04:03,096 not for the price it was when you bought it 1474 01:04:03,096 --> 01:04:05,166 or else you wouldn't actually ever make any money. 1475 01:04:05,326 --> 01:04:07,086 So I totally do not understand the stock market 1476 01:04:07,086 --> 01:04:07,546 when I took this. 1477 01:04:08,216 --> 01:04:11,076 So when you sell the cash-- I mean when you sell stocks, 1478 01:04:11,516 --> 01:04:14,166 this new cash value is going to come from the current price 1479 01:04:14,166 --> 01:04:17,016 of the stock which you can get from the lookup function, 1480 01:04:17,326 --> 01:04:18,546 and just like before, we said 1481 01:04:18,546 --> 01:04:20,326 "cash minus something" we can just say, 1482 01:04:20,326 --> 01:04:21,806 "cash equals cash plus something." 1483 01:04:22,336 --> 01:04:25,136 We just need to give that user back the amount of money 1484 01:04:25,136 --> 01:04:26,246 that the stock sold for. 1485 01:04:27,716 --> 01:04:28,806 Make sense? 1486 01:04:31,736 --> 01:04:33,596 So that's it for selling stocks. 1487 01:04:34,506 --> 01:04:37,316 And so finally, the pset mentions that we need 1488 01:04:37,316 --> 01:04:39,596 to keep track of our transaction history. 1489 01:04:40,546 --> 01:04:42,786 And so, if you look at the staff implementation, 1490 01:04:43,176 --> 01:04:46,576 you can see the time at which you bought the stock. 1491 01:04:47,166 --> 01:04:50,816 So if I come over here back to portfolio to history, 1492 01:04:51,826 --> 01:04:54,976 you can see my entire history and you can see both the date 1493 01:04:54,976 --> 01:04:57,426 and the time at which I performed each action. 1494 01:04:58,456 --> 01:05:01,436 So you notice here that I bought 12 shares of A 1495 01:05:01,436 --> 01:05:03,626 and how much that symbol went for. 1496 01:05:04,076 --> 01:05:05,056 So I bought 12 shares of A 1497 01:05:05,056 --> 01:05:07,646 and then I sold and bought some INTC. 1498 01:05:07,646 --> 01:05:11,506 So if I go back to my portfolio, I only have this A. 1499 01:05:11,506 --> 01:05:15,206 But the history still needs to keep track. 1500 01:05:15,876 --> 01:05:18,696 So even if we delete this from the portfolio like it's gone now 1501 01:05:18,696 --> 01:05:22,266 from that table, the history needs to remember that you had 1502 01:05:22,266 --> 01:05:23,426 that stock at one point. 1503 01:05:24,096 --> 01:05:26,306 So one way of doing that is to create another table 1504 01:05:26,826 --> 01:05:28,696 and call this "Table History." 1505 01:05:29,086 --> 01:05:31,606 And anytime you do anything whether it'd be buy 1506 01:05:31,606 --> 01:05:33,566 or sell a stock, that's gonna correspond 1507 01:05:33,566 --> 01:05:35,276 to a new row inside of that table. 1508 01:05:36,046 --> 01:05:38,476 So when you sell a stock, you're never deleting any rows. 1509 01:05:38,706 --> 01:05:41,046 You're gonna create a new row that says, "You sold the stock." 1510 01:05:41,046 --> 01:05:43,716 So we're never actually losing any information 1511 01:05:43,716 --> 01:05:46,416 but we have another table that's dedicated 1512 01:05:46,416 --> 01:05:48,186 to only remembering the information-- 1513 01:05:48,186 --> 01:05:49,556 to only remembering information. 1514 01:05:50,596 --> 01:05:52,836 Where the portfolio is gonna have rows coming and going 1515 01:05:52,836 --> 01:05:53,836 as you buy and sell stocks. 1516 01:05:54,176 --> 01:05:56,286 The history is just going to be a big log, 1517 01:05:56,286 --> 01:05:57,526 you're only adding rows. 1518 01:05:58,286 --> 01:06:00,476 So another approach could be, well, I have inside 1519 01:06:00,476 --> 01:06:02,216 of my portfolio, I'm gonna add another column 1520 01:06:02,216 --> 01:06:04,626 and that column is either true or false depending upon 1521 01:06:04,626 --> 01:06:05,786 if I still own that stock. 1522 01:06:06,386 --> 01:06:08,986 So if I sold all my Apple stocks instead of deleting them, 1523 01:06:08,986 --> 01:06:10,696 I'm just gonna set all those rows to false. 1524 01:06:11,326 --> 01:06:13,516 So when I look at my portfolio, I'm gonna get every row 1525 01:06:13,516 --> 01:06:15,716 that has a value of true, and when I look at my history, 1526 01:06:15,716 --> 01:06:17,786 I'm gonna get every row that a value of true or false 1527 01:06:17,786 --> 01:06:21,206 and display bought or sold based on what that column is. 1528 01:06:21,376 --> 01:06:22,936 So, just two different approaches, there are bunch 1529 01:06:22,936 --> 01:06:23,976 of other ways you can do this. 1530 01:06:23,976 --> 01:06:27,236 These are just two ways that make sense to me. 1531 01:06:27,236 --> 01:06:31,136 And so additionally, in order to keep track of the timestamp 1532 01:06:31,136 --> 01:06:32,306 at which the action occurred, 1533 01:06:32,536 --> 01:06:35,376 SQL has a function NOW that's going 1534 01:06:35,376 --> 01:06:36,756 to return the current time stamp. 1535 01:06:37,136 --> 01:06:39,696 So if you could say something like insert into history, 1536 01:06:39,956 --> 01:06:43,166 timestamp, and then just now. 1537 01:06:43,166 --> 01:06:45,636 You can also set a default value for the column 1538 01:06:45,966 --> 01:06:48,086 so you can say whenever a new row is inserted, 1539 01:06:48,086 --> 01:06:49,916 I want this column to have a default value 1540 01:06:49,916 --> 01:06:51,346 of CURRENT_TIMESTAMP. 1541 01:06:52,056 --> 01:06:53,846 Then, you don't have to worry at all 1542 01:06:54,396 --> 01:06:56,386 about actually setting the timestamp yourself. 1543 01:06:56,586 --> 01:06:57,996 SQL is just gonna say, "Okay, well, 1544 01:06:57,996 --> 01:07:00,166 because this has a default value of the current time stamp 1545 01:07:00,416 --> 01:07:02,086 and you didn't tell me what this column should be, 1546 01:07:02,246 --> 01:07:03,476 I'm just gonna make it the current time." 1547 01:07:04,436 --> 01:07:06,806 So finally, one more option is PHP's date function 1548 01:07:07,116 --> 01:07:08,306 which is really, really handy. 1549 01:07:08,306 --> 01:07:10,206 You can just pass in some generated string 1550 01:07:10,446 --> 01:07:11,276 of the current date. 1551 01:07:12,616 --> 01:07:14,756 Any questions on keeping track of history? 1552 01:07:15,306 --> 01:07:20,866 So finally, just some extra features, you need to pick one 1553 01:07:20,866 --> 01:07:22,846 of these features and implement it. 1554 01:07:22,906 --> 01:07:24,716 Allow the users to change their passwords, 1555 01:07:25,126 --> 01:07:26,736 email receipts of stocks. 1556 01:07:26,736 --> 01:07:28,906 Every time I buy something I get an email sent to me, 1557 01:07:29,306 --> 01:07:31,416 deposit additional money so allow the user 1558 01:07:31,416 --> 01:07:33,826 to increment their cash without selling stocks. 1559 01:07:34,186 --> 01:07:36,156 And then another one that was just added was allow the user 1560 01:07:36,156 --> 01:07:37,276 to reset their password. 1561 01:07:38,016 --> 01:07:40,066 So that last one being kind of difficult 1562 01:07:40,306 --> 01:07:42,996 because it's an interesting security challenge whereas 1563 01:07:42,996 --> 01:07:44,846 something like allowing the user change their password, 1564 01:07:44,846 --> 01:07:47,366 emailing receipts is a little bit on the simpler side. 1565 01:07:47,366 --> 01:07:50,626 So you're certainly free to implement all of them as long 1566 01:07:50,626 --> 01:07:52,806 as you implement at least one of them. 1567 01:07:53,946 --> 01:07:56,566 So any questions on pset7 at all? 1568 01:07:57,366 --> 01:08:04,236 Yup? So what's the difference between changing your password 1569 01:08:04,236 --> 01:08:05,856 and resetting your password? 1570 01:08:05,856 --> 01:08:07,556 >> Sure. So what's the difference 1571 01:08:07,556 --> 01:08:11,866 between changing your password and resetting your password? 1572 01:08:11,866 --> 01:08:15,906 So this is a clarification that was literally just made 1573 01:08:15,906 --> 01:08:20,176 on the spec. But changing your password is for I'm a user 1574 01:08:20,176 --> 01:08:23,416 and I'm currently logged in and I wanna be able 1575 01:08:23,416 --> 01:08:24,976 to change my password. 1576 01:08:24,976 --> 01:08:26,886 Where resetting is like I'm logged out 1577 01:08:26,886 --> 01:08:28,376 and I forgot what my password is so you need 1578 01:08:28,376 --> 01:08:31,296 to devise some secure mechanism of allowing user 1579 01:08:31,296 --> 01:08:33,296 to like click some link and be taken to a page 1580 01:08:33,296 --> 01:08:35,686 where their password can be reset. 1581 01:08:35,686 --> 01:08:37,336 So that's definitely the hardest one 1582 01:08:37,366 --> 01:08:38,506 of these four 'cause it's an interesting challenge. 1583 01:08:38,536 --> 01:08:40,066 Well, how do I give a user a link that I find someone else 1584 01:08:40,096 --> 01:08:40,876 and I can't just guess a link 1585 01:08:40,906 --> 01:08:41,746 and change someone else's password? 1586 01:08:41,776 --> 01:08:42,136 Other questions? 1587 01:08:42,166 --> 01:08:42,976 If not, then good luck on pset7. 1588 01:08:43,516 --> 01:08:48,340 [ Noise ]