1 00:00:00,000 --> 00:00:02,610 [Section 8 - More Comfortable] 2 00:00:02,610 --> 00:00:04,910 [Rob Bowden - Harvard University] 3 00:00:04,910 --> 00:00:07,070 [This is CS50. - CS50.TV] 4 00:00:11,520 --> 00:00:14,160 >> These week section notes are going to be pretty short, 5 00:00:14,160 --> 00:00:19,070 so I'm just going to keep talking, you guys are going to keep asking questions, 6 00:00:19,070 --> 00:00:22,720 and we'll try to fill up as much time as possible. 7 00:00:22,720 --> 00:00:31,950 A lot of people think that this pset isn't necessarily difficult, but it's very long. 8 00:00:31,950 --> 00:00:37,070 The pset spec itself takes an hour to read. 9 00:00:40,530 --> 00:00:45,730 We give you a lot of the SQL you could possibly need to use. 10 00:00:45,730 --> 00:00:50,520 We walk you through a lot of it, so it shouldn't be too bad. 11 00:00:50,520 --> 00:00:54,560 Has anyone started or finished? 12 00:00:55,380 --> 00:00:59,710 It's the last pset. Oh, my God. 13 00:00:59,710 --> 00:01:05,400 Usually there's a JavaScript one after this, but calendar change things 14 00:01:05,400 --> 00:01:09,560 makes everything 1 week shorter, and we no longer have a JavaScript pset. 15 00:01:09,560 --> 00:01:12,310 I don't know how that affects whether JavaScript is going to appear on the exam 16 00:01:12,310 --> 00:01:15,510 or Quiz 1. 17 00:01:15,510 --> 00:01:22,260 I imagine it will be something like you need to know high-level things about JavaScript, 18 00:01:22,260 --> 00:01:26,460 but I doubt we'd just give you straight JavaScript code 19 00:01:26,460 --> 00:01:28,720 since you haven't had a pset in it. 20 00:01:28,720 --> 00:01:33,000 But that will be stuff for quiz review next week. 21 00:01:33,000 --> 00:01:36,320 >> Section of questions. 22 00:01:36,320 --> 00:01:43,870 A lot of this stuff is somewhat poorly worded, but we'll discuss why. 23 00:01:43,870 --> 00:01:50,220 Unlike C, PHP is a "dynamically-typed" language. What does this mean, you ask? 24 00:01:50,220 --> 00:01:53,830 Well, say goodbye to all of those char, float, int, and other keywords you need to use 25 00:01:53,830 --> 00:01:56,190 when declaring variables and functions in C. 26 00:01:56,190 --> 00:02:00,420 In PHP, a variable's type is determined by the value that it's currently holding. 27 00:02:00,420 --> 00:02:04,990 So before we type this code into a file called dynamic.php, 28 00:02:04,990 --> 00:02:12,670 PHP is dynamically typed. That is true. 29 00:02:12,670 --> 00:02:17,590 I disagree with the fact that that means we're saying goodbye to char, float, int, 30 00:02:17,590 --> 00:02:20,620 and other keywords. 31 00:02:20,620 --> 00:02:25,510 The exact difference between dynamically typed and the alternative, 32 00:02:25,510 --> 00:02:32,010 which is statically typed, is that dynamically typed, all of your type checking and stuff 33 00:02:32,010 --> 00:02:37,350 happens at run time, whereas statically typed it happens at compile time. 34 00:02:37,350 --> 00:02:43,030 The word static in general seems to mean compile time things. 35 00:02:43,030 --> 00:02:48,170 I guess there are other uses for it, but in C when you declare a static variable, 36 00:02:48,170 --> 00:02:52,650 its storage is allocated at compile time. 37 00:02:52,650 --> 00:02:59,260 Here, dynamically typed just means that-- 38 00:02:59,260 --> 00:03:04,350 In C if you try to add a string and an integer, when you compile it, 39 00:03:04,350 --> 00:03:11,000 it's going to complain because it's going to say that you can't add an int and a pointer. 40 00:03:11,000 --> 00:03:14,710 It's just not a valid operation. 41 00:03:14,710 --> 00:03:21,170 That is another thing that we'll get to in a second. 42 00:03:21,170 --> 00:03:24,860 But that sort of checking, the fact that it complains at compile time, 43 00:03:24,860 --> 00:03:29,220 is static type checking. 44 00:03:29,220 --> 00:03:35,220 There are languages where you don't need to say char, float, int, and all of those things, 45 00:03:35,220 --> 00:03:40,940 but the language can tell from the context of the thing what type it's supposed to be, 46 00:03:40,940 --> 00:03:43,980 but it's still statically typed. 47 00:03:43,980 --> 00:03:49,000 So if you take 51, OCaml, you never need to use any of these types, 48 00:03:49,000 --> 00:03:58,700 but it still will at compile time say you can't do this because you're mixing an int and a string. 49 00:03:58,700 --> 00:04:05,650 Dynamically typed just means that sometime during run time you're going to get a complaint. 50 00:04:05,650 --> 00:04:13,430 If you have also used Java before, in general, almost any C-type language 51 00:04:13,430 --> 00:04:20,070 is going to be statically typed, so C, C++, Java, all of those are generally statically typed. 52 00:04:20,070 --> 00:04:22,910 In Java when you compile something and you're saying 53 00:04:22,910 --> 00:04:26,670 string s equals new something that isn't a string, 54 00:04:26,670 --> 00:04:28,950 that's going to complain because those types just don't match up. 55 00:04:28,950 --> 00:04:31,180 That's going to complain at compile time. 56 00:04:31,180 --> 00:04:36,750 But it also has some dynamic time things like if you try to cast something 57 00:04:36,750 --> 00:04:40,500 to a type that's more specific than its current type, 58 00:04:40,500 --> 00:04:45,610 there's nothing it can do at compile time to check whether that cast is going to succeed. 59 00:04:45,610 --> 00:04:51,130 Java also has some dynamic type checking that as soon as it gets to that line of code 60 00:04:51,130 --> 00:04:54,130 when it's actually executing, it's going to do the cast, 61 00:04:54,130 --> 00:04:56,260 check if that cast was valid in the first place, 62 00:04:56,260 --> 00:04:59,890 and if it wasn't, then it's going to complain that you have an invalid type. 63 00:04:59,890 --> 00:05:03,200 Dynamic type checking. 64 00:05:03,200 --> 00:05:07,010 Type this into a file called dynamic.php. 65 00:05:10,130 --> 00:05:12,380 Dynamic.php. 66 00:05:14,580 --> 00:05:17,190 I'll unzip that formatting. 67 00:05:18,750 --> 00:05:21,880 We have a variable, we set it to the integer 7, 68 00:05:21,880 --> 00:05:27,930 then we're going to print it and %s-- 69 00:05:27,930 --> 00:05:32,830 Oh, we're printing the type of it, so gettype is going to return the type of the variable. 70 00:05:32,830 --> 00:05:35,720 We're just printing the type over and over again. 71 00:05:35,720 --> 00:05:39,440 We just php.dynamic.php. 72 00:05:39,440 --> 00:05:45,920 We'll see that it changes from integer to string to Boolean as we go through. 73 00:05:45,920 --> 00:05:54,590 In C there is no Boolean data type, there is no string data type. 74 00:05:54,590 --> 00:06:00,500 There's char * and Boolean just tends to be int or char or something. 75 00:06:00,500 --> 00:06:05,690 In PHP these types do exist, and that's one of the big advantages of PHP over C-- 76 00:06:05,690 --> 00:06:13,290 that string operations are infinitely easier in PHP than C. They just work. 77 00:06:13,290 --> 00:06:18,290 >> So we come back here. 78 00:06:18,290 --> 00:06:21,260 We ran dynamic.php. 79 00:06:21,260 --> 00:06:26,710 This tells the PHP interpreter, called php, to run the PHP code in dynamic.php. 80 00:06:26,710 --> 00:06:30,250 If you have any errors in the file, the interpreter will tell you! 81 00:06:30,250 --> 00:06:39,110 The interpreter, this is another big difference between PHP and C. 82 00:06:39,110 --> 00:06:48,200 In C you have to compile something and then you run that compiled file. 83 00:06:48,200 --> 00:06:50,490 In PHP you never compile anything. 84 00:06:50,490 --> 00:06:57,200 So the PHP interpreter is basically just reading this line by line. 85 00:06:57,200 --> 00:07:02,900 It hits var = 7 then it hits printf then it hits var then it hits printf and so on. 86 00:07:02,900 --> 00:07:10,910 There is a bit of compiling it does, and it caches the results 87 00:07:10,910 --> 00:07:15,510 so if you run the script later you can do some, 88 00:07:15,510 --> 00:07:19,280 but basically it's a line by line sort of thing. 89 00:07:19,280 --> 00:07:25,280 That means that a lot of the optimizations that we get in C, 90 00:07:25,280 --> 00:07:31,920 like compiling, it's just generally the compiler can do a lot of tricks for you. 91 00:07:31,920 --> 00:07:36,110 It can take out unused variables, it can do all of these sorts of things, 92 00:07:36,110 --> 00:07:38,660 it can do tail recursion. 93 00:07:38,660 --> 00:07:42,550 In PHP you're not going to get that advantage 94 00:07:42,550 --> 00:07:45,690 because it's just going to start executing line by line by line, 95 00:07:45,690 --> 00:07:49,950 and it doesn't really recognize these things as easily 96 00:07:49,950 --> 00:07:54,440 since it's not 1 big compilation pass over the thing and then execution; 97 00:07:54,440 --> 00:07:56,860 it's just line by line. 98 00:08:00,730 --> 00:08:02,750 So that's the interpreter. 99 00:08:02,750 --> 00:08:06,840 >> Back to our dynamic typing: pretty cool, eh? 100 00:08:06,840 --> 00:08:08,640 You definitely couldn't do that in C! 101 00:08:08,640 --> 00:08:11,860 Now, see if you can figure out the type of each of the following values. 102 00:08:11,860 --> 00:08:14,760 See this for reference. 103 00:08:14,760 --> 00:08:19,420 So 3.50. What type do you think that's going to be? 104 00:08:24,480 --> 00:08:26,370 Here are the types we have. 105 00:08:26,370 --> 00:08:30,430 We have bools, integers, floating points, strings, arrays, objects, 106 00:08:30,430 --> 00:08:38,370 and then resources, which is kind of vague. 107 00:08:38,370 --> 00:08:41,010 I think there's actually an example here. 108 00:08:41,010 --> 00:08:43,740 Then there's NULL. NULL is a special type. 109 00:08:43,740 --> 00:08:47,140 Unlike C where NULL is just a pointer with address 0, 110 00:08:47,140 --> 00:08:54,930 in PHP, NULL is its own type where the only valid thing of that type is NULL. 111 00:08:57,560 --> 00:09:00,670 This is much more useful for error checking. 112 00:09:00,670 --> 00:09:04,310 In C where we had this issue where if you return NULL, 113 00:09:04,310 --> 00:09:08,660 does that mean you're returning a NULL pointer or using NULL to signify error 114 00:09:08,660 --> 00:09:12,380 or all of that confusion we had at one point. 115 00:09:12,380 --> 00:09:18,440 Here, returning NULL generally means error. 116 00:09:20,860 --> 00:09:27,300 A lot of things also return false for error. 117 00:09:27,300 --> 00:09:33,140 But the point is the NULL type, the only thing of the NULL type is NULL. 118 00:09:33,140 --> 00:09:40,090 Then callback is like you can define some anonymous functions. 119 00:09:40,090 --> 00:09:46,420 You don't have to give the function a name, but you won't have to deal with that here. 120 00:09:46,420 --> 00:09:53,940 Looking at the types that they do expect us to know, 121 00:09:53,940 --> 00:09:59,000 what do you think the type of 3.50 is? >>[student] Float. 122 00:09:59,000 --> 00:10:00,370 Yeah. 123 00:10:00,370 --> 00:10:06,290 So then here, what do you think the type of this is? >>[student] Array. 124 00:10:06,290 --> 00:10:09,890 Yeah. The first one was float, the second one is an array. 125 00:10:09,890 --> 00:10:14,500 Notice that this array is not like a C array 126 00:10:14,500 --> 00:10:19,610 where you have index 0 has some value, index 1 has some value. 127 00:10:19,610 --> 00:10:26,320 Here the indices are a, b, and c and the values are 1, 2, and 3. 128 00:10:26,320 --> 00:10:33,980 In PHP there is no difference between an associative array and just a regular array 129 00:10:33,980 --> 00:10:36,740 as you would think of it in C. 130 00:10:36,740 --> 00:10:43,040 There is just this, and underneath the hood a regular array is just an associative array 131 00:10:43,040 --> 00:10:50,000 where 0 maps to some value the same way a maps to some value. 132 00:10:50,000 --> 00:11:00,410 For this reason, PHP can be pretty bad for really fast code/benchmarking things 133 00:11:00,410 --> 00:11:07,930 since in C when you're using an array you know that accessing a member is constant time. 134 00:11:07,930 --> 00:11:11,860 In PHP accessing a member is who knows how much time? 135 00:11:11,860 --> 00:11:18,970 It's probably constant if it hashes correctly. 136 00:11:18,970 --> 00:11:21,620 Who knows what it's really doing underneath the hood? 137 00:11:21,620 --> 00:11:25,600 You really need to look at the implementation to see how it's going to deal with that. 138 00:11:25,600 --> 00:11:28,550 So then fopen. 139 00:11:28,550 --> 00:11:36,420 I think here let's just PHP manual fopen to look at the return type. 140 00:11:36,420 --> 00:11:41,260 We see here you can look up pretty much any function in the PHP manual 141 00:11:41,260 --> 00:11:47,540 and this is sort of the man page of PHP. 142 00:11:47,540 --> 00:11:51,060 The return type is going to be resource. 143 00:11:51,060 --> 00:11:56,050 That's why I looked it up, because we didn't really define resource. 144 00:11:56,050 --> 00:12:04,110 The idea of resource, in C you kind of got a FILE* or whatever; 145 00:12:04,110 --> 00:12:07,200 in PHP the resource is your FILE*. 146 00:12:07,200 --> 00:12:10,360 It's what you're going to be reading from, it's what you're going to be writing to. 147 00:12:10,360 --> 00:12:20,710 It's usually external, so it's a resource you can pull things from and throw things to. 148 00:12:20,710 --> 00:12:26,520 And finally, what is the type of NULL? >>[student] NULL. 149 00:12:26,520 --> 00:12:30,650 Yeah. So the only thing that is NULL is NULL. 150 00:12:30,650 --> 00:12:33,480 NULL is NULL. 151 00:12:35,490 --> 00:12:41,170 >> One feature of PHP's type system (for better or for worse) is its ability to juggle types. 152 00:12:41,170 --> 00:12:44,390 When you write a line of PHP code that combines values of different types, 153 00:12:44,390 --> 00:12:46,670 PHP will try to do the sensible thing. 154 00:12:46,670 --> 00:12:48,920 Try out each of the following lines of PHP code. What's printed out? 155 00:12:48,920 --> 00:12:51,000 Is it what you expected? Why or why not? 156 00:12:51,000 --> 00:12:58,600 This fact about PHP is what makes it what we call weakly typed. 157 00:12:58,600 --> 00:13:04,610 Weakly typed and strongly typed, 158 00:13:04,610 --> 00:13:06,840 there are different uses for those terms, 159 00:13:06,840 --> 00:13:12,020 but most people use weakly typed and strongly typed to mean this sort of thing 160 00:13:12,020 --> 00:13:15,920 where ("1" + 2); that works. 161 00:13:15,920 --> 00:13:18,290 In C that would not work. 162 00:13:18,290 --> 00:13:22,490 You can imagine this not working. 163 00:13:22,490 --> 00:13:29,200 A lot of people mix up dynamic typing and weak typing and static typing and strong typing. 164 00:13:29,200 --> 00:13:34,050 Python is another example of a language that's dynamically typed. 165 00:13:34,050 --> 00:13:41,770 You can throw around types in variables and it's going to determine at run time 166 00:13:41,770 --> 00:13:44,680 any error checkings. 167 00:13:44,680 --> 00:13:50,740 In Python it's going to execute this and it will see ("1" + 2); 168 00:13:50,740 --> 00:13:55,920 and this will fail because it says you can't add a string and an integer. 169 00:13:55,920 --> 00:14:00,860 In PHP, which is just as dynamically typed, this will not fail. 170 00:14:00,860 --> 00:14:04,220 Weak typing has to do with the fact that it does things with types 171 00:14:04,220 --> 00:14:07,800 that don't really make sense necessarily. 172 00:14:07,800 --> 00:14:17,420 So ("1" + 2); I can imagine that being the string 12, I can imagine it being the string 3, 173 00:14:17,420 --> 00:14:20,710 I can imagine it being the integer 3. 174 00:14:20,710 --> 00:14:24,530 It's not necessarily well defined, and we're probably going to see here 175 00:14:24,530 --> 00:14:29,140 that when we print ("1" + 2); it's probably going to end up being different 176 00:14:29,140 --> 00:14:32,320 than printing (1 + "2"). 177 00:14:32,320 --> 00:14:39,700 And this tends to be, in my opinion, for the worse. 178 00:14:39,700 --> 00:14:44,240 Here we can try these. 179 00:14:44,240 --> 00:14:48,740 Another little trick about PHP is you don't need to actually write the file. 180 00:14:48,740 --> 00:14:52,790 It does have run this command mode. 181 00:14:52,790 --> 00:14:57,710 So php -r, then we can throw in the command here: 182 00:14:57,710 --> 00:15:06,610 "print('1' + 2);" and I'll throw a new line. 183 00:15:19,550 --> 00:15:23,970 This printed 3. 184 00:15:31,100 --> 00:15:35,330 It looks like it prints 3 and it's the integer 3. 185 00:15:35,330 --> 00:15:38,420 So now let's try the other way around: 186 00:15:38,420 --> 00:15:42,970 "print(1 + '2'); 187 00:15:45,560 --> 00:15:50,490 We get 3, and is it also going to be integer 3? I honestly have no idea. 188 00:15:50,490 --> 00:15:54,030 It looks like that is consistent. 189 00:15:54,030 --> 00:15:59,550 There is never any chance of it being the string 12 or anything like that 190 00:15:59,550 --> 00:16:08,080 because PHP, unlike JavaScript and Java too, 191 00:16:08,080 --> 00:16:11,670 has a separate operator for concatenation. 192 00:16:11,670 --> 00:16:14,930 Concatenation in PHP is dot. 193 00:16:14,930 --> 00:16:22,950 So printing (1 . '2'); is going to give us 12. 194 00:16:25,790 --> 00:16:32,420 This tends to lead to confusion where people try to do something like str += 195 00:16:32,420 --> 00:16:37,840 some other thing that they want to add on to the end of their string, and that's going to fail. 196 00:16:37,840 --> 00:16:40,770 You need to do str .= 197 00:16:42,000 --> 00:16:46,240 So don't forget concatenation in PHP is a dot. 198 00:16:46,240 --> 00:16:52,100 Other things to try: print("CS" + 50); 199 00:16:55,750 --> 00:17:03,610 I've told you that there is no hope of this resulting in CS50 200 00:17:03,610 --> 00:17:06,119 since concatenation is not +. 201 00:17:06,119 --> 00:17:08,440 What do you think this is going to end up being? 202 00:17:10,359 --> 00:17:13,460 I honestly have absolutely no idea. 203 00:17:14,250 --> 00:17:16,460 It looks like it's just 50. 204 00:17:16,460 --> 00:17:21,490 It sees the string, and I bet if we put 123CS-- 205 00:17:21,490 --> 00:17:29,640 It sees the first string, it tries to read an integer from it or a number from it. 206 00:17:29,640 --> 00:17:31,710 In this case it sees 123CS. 207 00:17:31,710 --> 00:17:35,190 "That doesn't make sense as an integer, so I'm just going to think of 123." 208 00:17:35,190 --> 00:17:38,580 So 123 + 50 is going to be 173. 209 00:17:38,580 --> 00:17:40,740 And here it starts reading this as an integer. 210 00:17:40,740 --> 00:17:45,690 It doesn't see anything, so it just treats it as 0. So 0 + 50 is going to be 50. 211 00:17:45,690 --> 00:17:51,600 This I'm assuming is going to do something similar. 212 00:17:51,600 --> 00:17:54,310 I'm thinking 99. 213 00:17:54,310 --> 00:17:57,580 Yeah, because it's going to take the first-- 214 00:18:12,880 --> 00:18:15,730 So 99. 215 00:18:15,730 --> 00:18:21,970 Here (10 / 7), if this were C, what would that return? 216 00:18:23,700 --> 00:18:29,630 [student] 1. >>Yeah, it would be 1 because 10 / 7 is dividing 2 integers. 217 00:18:29,630 --> 00:18:32,910 An integer divided by an integer is going to return an integer. 218 00:18:32,910 --> 00:18:37,750 It can't return 1 point whatever that would be, so it's just going to return 1. 219 00:18:37,750 --> 00:18:46,120 Here printing (10 / 7); it's going to actually interpret that. 220 00:18:46,120 --> 00:18:53,760 And this means that if you actually want to do integer rounding and stuff like that, 221 00:18:53,760 --> 00:18:59,950 you need to do print(floor(10 / 7)); 222 00:18:59,950 --> 00:19:08,460 In C it's probably weird that you can rely on integer truncation regularly, 223 00:19:08,460 --> 00:19:12,260 but in PHP you can't because it will automatically turn it into a float. 224 00:19:13,430 --> 00:19:17,610 And then (7 + true); what do you think that's going to be? 225 00:19:18,550 --> 00:19:23,640 I'm guessing 8 if it's going to interpret true as 1. 226 00:19:23,640 --> 00:19:25,740 It looks like it's 8. 227 00:19:25,740 --> 00:19:31,710 >> So anything we've done in the past 10 minutes you should absolutely never do. 228 00:19:31,710 --> 00:19:39,870 You will see code that does this. 229 00:19:39,870 --> 00:19:42,700 It doesn't have to be as straightforward as this. 230 00:19:42,700 --> 00:19:47,240 You could have 2 variables, and 1 variable happens to be a string 231 00:19:47,240 --> 00:19:51,310 and the other variable happens to be an int, and then you add these variables together. 232 00:19:51,310 --> 00:20:00,120 Since PHP is dynamically typed and it won't do any type checking for you 233 00:20:00,120 --> 00:20:03,640 and since it's weakly typed and since it will just automatically throw these things together 234 00:20:03,640 --> 00:20:11,490 and everything will just work, it's difficult to even know that this variable must be a string now, 235 00:20:11,490 --> 00:20:14,930 so I shouldn't add it to this variable, which is an integer. 236 00:20:18,780 --> 00:20:24,560 Best practice is if a variable is a string, keep it as a string forever. 237 00:20:24,560 --> 00:20:26,980 If a variable is an int, keep it as an int forever. 238 00:20:26,980 --> 00:20:30,770 If you want to deal with integers and strings, 239 00:20:30,770 --> 00:20:36,970 you can use varsint--that's JavaScript. 240 00:20:36,970 --> 00:20:42,520 Intval. I do this all the time. PHP and JavaScript I mix up everything. 241 00:20:42,520 --> 00:20:47,600 So intval is going to return the integer value of a variable. 242 00:20:47,600 --> 00:20:56,550 If we pass in "print(intval('123')); you get 123. 243 00:21:06,820 --> 00:21:15,850 Intval itself is not going to do the check for us that it's exclusively an integer. 244 00:21:15,850 --> 00:21:20,460 The PHP manual, there are just so many functions available, 245 00:21:20,460 --> 00:21:26,560 so here I think what I would use is is_numeric first. 246 00:21:26,560 --> 00:21:32,590 I'm guessing that returned false. 247 00:21:32,590 --> 00:21:35,780 That's another thing we have to go over is ===. 248 00:21:37,850 --> 00:21:44,020 So is_numeric('123df'), you would not think of that as is_numeric. 249 00:21:44,020 --> 00:21:46,720 In C you would have to iterate over all characters 250 00:21:46,720 --> 00:21:50,410 and check to see if each character is digit or whatever. 251 00:21:50,410 --> 00:21:53,850 Here is_numeric is going to do that for us, 252 00:21:53,850 --> 00:21:56,520 and it's returning false. 253 00:21:56,520 --> 00:22:02,120 So when I printed that, it printed nothing, so here I am comparing it to see, 254 00:22:02,120 --> 00:22:05,490 did you happen to be false? And so now it's printing 1. 255 00:22:05,490 --> 00:22:10,060 Apparently it prints 1 as true instead of printing true as true. 256 00:22:10,060 --> 00:22:15,790 I wonder if I do print_r. No, it still does 1. 257 00:22:15,790 --> 00:22:26,760 >> Going back to ===, == still exists, 258 00:22:26,760 --> 00:22:32,260 and if you talk to Tommy he'll say == is perfectly fine. 259 00:22:32,260 --> 00:22:37,700 I'm going to say that == is terrible and you should never use ==. 260 00:22:37,700 --> 00:22:44,870 The difference is that == compares things 261 00:22:44,870 --> 00:22:48,450 where it can be true even if they're not the same type, 262 00:22:48,450 --> 00:22:53,810 whereas === compares things and first it checks are they the same type? 263 00:22:53,810 --> 00:22:58,010 Yes. Okay, now I'm going to see if they actually compare to be equal. 264 00:22:58,010 --> 00:23:08,890 You get weird things like 10 equals--let's see what that says. 265 00:23:08,890 --> 00:23:15,570 So ('10' == '1e1'); 266 00:23:15,570 --> 00:23:17,980 This returns true. 267 00:23:17,980 --> 00:23:21,420 Does anyone have any guesses why this returns true? 268 00:23:25,180 --> 00:23:27,120 It isn't just about that. Maybe this is a hint. 269 00:23:27,120 --> 00:23:33,170 But if I change that to an f--darn it! I keep using double quotes. 270 00:23:33,170 --> 00:23:38,780 The reason the double quotes are yelling at me is because I've put this in double quotes. 271 00:23:38,780 --> 00:23:43,850 So I could escape the double quotes in here, but single quotes make it easier. 272 00:23:43,850 --> 00:23:49,120 So ('10' == '1f1'); does not print true. ('10' =='1e1'); prints true. 273 00:23:49,120 --> 00:23:56,330 [student] Is it hex? >>It's not hex, but it's close that it's like-- 274 00:23:56,330 --> 00:24:01,060 1e1, scientific notation. 275 00:24:01,060 --> 00:24:07,950 It recognizes 1e1 as 1 * 10^1 or whatever. 276 00:24:07,950 --> 00:24:11,510 Those are equal integers. 277 00:24:11,510 --> 00:24:15,930 If we do === then it's going to be false. 278 00:24:15,930 --> 00:24:28,490 I actually have no idea if we do == what about (10 and '10abc');? All right. So that's true. 279 00:24:28,490 --> 00:24:35,940 So just like when you did (10 + '10abc'); and it would be 20, 280 00:24:35,940 --> 00:24:38,800 here (10 == '10abc'); is true. 281 00:24:38,800 --> 00:24:45,350 Even worse are things like (false == NULL); is true 282 00:24:45,350 --> 00:24:52,210 or (false == 0); is true, (false == []); 283 00:24:52,210 --> 00:25:00,970 There are weird cases of-- That's one of those weird cases. 284 00:25:00,970 --> 00:25:08,110 Notice that (false == []); is true. 285 00:25:08,110 --> 00:25:11,950 ('0' == false); is true. 286 00:25:11,950 --> 00:25:16,090 ('0' == []); is false. 287 00:25:16,090 --> 00:25:19,090 So == is in no way transitive. 288 00:25:19,090 --> 00:25:26,830 a can be equal to b and a can be equal to c, 289 00:25:26,830 --> 00:25:29,340 but b might not be equal to c. 290 00:25:29,340 --> 00:25:35,580 That's an abomination to me, and you should always use ===. 291 00:25:35,580 --> 00:25:38,590 [student] Can we do !== as well? >>[Bowden] Yes. 292 00:25:38,590 --> 00:25:44,600 The equivalent would be != and !==. 293 00:25:44,600 --> 00:25:48,230 This is actually brought up in the pset spec 294 00:25:48,230 --> 00:25:52,000 where a lot of functions return-- 295 00:25:52,000 --> 00:25:53,890 The PHP manual is good about this. 296 00:25:53,890 --> 00:25:59,140 It puts in a big red box, "This will return false if there's an error." 297 00:25:59,140 --> 00:26:03,940 But returning 0 is a perfectly reasonable thing to return. 298 00:26:03,940 --> 00:26:08,250 Think about any function which is expected to return an integer. 299 00:26:11,250 --> 00:26:17,880 Let's say this function is supposed to count the number of lines in a file or something. 300 00:26:17,880 --> 00:26:23,490 Under normal circumstances, you pass this function a file 301 00:26:23,490 --> 00:26:27,120 and it's going to return an integer which represents the number of lines. 302 00:26:27,120 --> 00:26:30,820 So 0 is a perfectly reasonable number if the file is just empty. 303 00:26:30,820 --> 00:26:36,810 But what if you pass it an invalid file and the function happens to return false 304 00:26:36,810 --> 00:26:38,860 if you pass it an invalid file? 305 00:26:38,860 --> 00:26:46,500 If you just do == you're not differentiating the case between invalid file and empty file. 306 00:26:48,870 --> 00:26:51,350 Always use ===. 307 00:26:55,690 --> 00:26:58,000 That's all of those. 308 00:26:58,000 --> 00:27:01,660 >> In PHP, the array type is different from what you're used to in C. 309 00:27:01,660 --> 00:27:06,650 Indeed, you may have already noticed this above when you saw that this is of type array. 310 00:27:06,650 --> 00:27:15,640 The bracket syntax is new as of PHP 5.4, which is the newest version of PHP. 311 00:27:15,640 --> 00:27:36,960 Before this you always had to write array( 'a' -> 1, 'b' -> 2. 312 00:27:36,960 --> 00:27:41,160 That was the constructor for an array. 313 00:27:41,160 --> 00:27:45,950 Now PHP has finally come around to the nice syntax of just square brackets, 314 00:27:45,950 --> 00:27:50,900 which is just so much better than array. 315 00:27:50,900 --> 00:27:54,480 But considering PHP 5.4 is the newest version, 316 00:27:54,480 --> 00:27:59,090 you may encounter places that don't even have PHP 5.3. 317 00:27:59,090 --> 00:28:08,220 Over the summer we ran into this issue where PHP 5.3 was what we had on the appliance, 318 00:28:08,220 --> 00:28:14,480 but the server that we deployed all our grade book and submit and all that stuff to 319 00:28:14,480 --> 00:28:16,750 was PHP 5.4. 320 00:28:16,750 --> 00:28:23,060 Not knowing this, we developed in 5.3, pushed to 5.4, 321 00:28:23,060 --> 00:28:25,660 and now all of a sudden none of our code works 322 00:28:25,660 --> 00:28:28,680 because there happened to have been changes between 5.3 and 5.4 323 00:28:28,680 --> 00:28:31,030 which are not backwards compatible, 324 00:28:31,030 --> 00:28:35,770 and we have to go and fix all of our things that don't work for PHP 5.4. 325 00:28:39,210 --> 00:28:42,320 For this class, since the appliance does have PHP 5.4, 326 00:28:42,320 --> 00:28:45,490 it's perfectly fine to use square brackets. 327 00:28:47,240 --> 00:28:50,440 But if you're looking up things around the Internet, 328 00:28:50,440 --> 00:28:54,880 if you're looking up some kind of array stuff, most likely you're going to see 329 00:28:54,880 --> 00:29:02,020 the spell out array constructor syntax since that's been around since PHP was born 330 00:29:02,020 --> 00:29:07,340 and square bracket syntax has been around for the past couple months 331 00:29:07,340 --> 00:29:10,020 or whenever 5.4 came around. 332 00:29:10,020 --> 00:29:12,710 This is how you index. 333 00:29:12,710 --> 00:29:30,610 Just like in C how you would index by square brackets like $array[0], $array[1], $array[2], 334 00:29:30,610 --> 00:29:36,320 you index the same way if you happen to have your indices being strings. 335 00:29:36,320 --> 00:29:40,440 So $array['a'] and $array['b']. 336 00:29:40,440 --> 00:29:47,410 $array[b]. Why would this be wrong? 337 00:29:52,490 --> 00:29:59,870 It will probably generate a warning but still work. PHP tends to do that. 338 00:29:59,870 --> 00:30:04,890 It tends to just, "I'm going to warn you about this, but I'm just going to keep going 339 00:30:04,890 --> 00:30:07,550 "and do whatever I can." 340 00:30:07,550 --> 00:30:11,500 It will probably translate this to a string, 341 00:30:11,500 --> 00:30:15,000 but it is possible that at some point in the past someone said 342 00:30:15,000 --> 00:30:20,180 define b to be 'HELLO WORLD'. 343 00:30:20,180 --> 00:30:28,740 So now b could be a constant and $array[b] will actually be doing 'HELLO WORLD'. 344 00:30:28,740 --> 00:30:32,380 I think at this point, or at least our PHP settings, 345 00:30:32,380 --> 00:30:37,870 if you try to index into an array and that key doesn't exist, it will fail. 346 00:30:37,870 --> 00:30:40,150 I don't think it will just warn you. 347 00:30:40,150 --> 00:30:44,560 Or at least you can set it so that it doesn't just warn you, it just straight up fails. 348 00:30:44,560 --> 00:30:49,290 >> The way you check to see if there actually is such an index is isset. 349 00:30:49,290 --> 00:30:54,690 So isset($array['HELLO WORLD']) will return false. 350 00:30:54,690 --> 00:30:59,160 isset($array['b']) will return true. 351 00:31:06,830 --> 00:31:09,880 You can mix these syntaxes. 352 00:31:15,060 --> 00:31:22,440 I'm pretty sure what this array would end up being is-- We can test it out. 353 00:31:43,290 --> 00:31:45,700 Oh, I need PHPWord. 354 00:31:53,960 --> 00:32:00,260 This is mixing the syntax where you specify what the key is 355 00:32:00,260 --> 00:32:03,330 and you don't specify what the key is. 356 00:32:03,330 --> 00:32:05,520 So 3 right here is a value. 357 00:32:05,520 --> 00:32:08,080 You haven't explicitly said what its key is going to be. 358 00:32:08,080 --> 00:32:11,670 What do you think its key is going to be? 359 00:32:11,670 --> 00:32:21,410 [student] 0. >>I'm guessing 0 only because it's the first one we haven't specified. 360 00:32:21,410 --> 00:32:23,500 We can actually do a couple of these cases. 361 00:32:23,500 --> 00:32:28,030 So print_r is print recursive. It will print the entire array. 362 00:32:28,030 --> 00:32:32,700 It would print subarrays of the array if there were any. 363 00:32:32,700 --> 00:32:36,630 So print_r ($array); php.test.php. 364 00:32:36,630 --> 00:32:38,810 It does look like it gave it 0. 365 00:32:38,810 --> 00:32:43,530 There's actually something to keep in mind here, but we'll get back to it in a second. 366 00:32:43,530 --> 00:32:45,850 But what if I happen to make this index 1? 367 00:32:45,850 --> 00:32:51,170 PHP does not differentiate between string indices and integer indices, 368 00:32:51,170 --> 00:33:00,280 so at this point I've just defined an index 1 and I can do both $array[1] and $array['1'] 369 00:33:00,280 --> 00:33:06,250 and it will be the same index and the same key. 370 00:33:06,250 --> 00:33:13,000 So now what do you think 3 is going to be? >>[student] 2. >>[Bowden] I'm guessing 2. 371 00:33:16,000 --> 00:33:18,690 Yeah. It's 2. 372 00:33:18,690 --> 00:33:24,790 What if we did this is 10, this is 4? What do you think the index of 3 is going to be? 373 00:33:27,360 --> 00:33:29,110 I'm thinking 11. 374 00:33:29,110 --> 00:33:33,060 My guess as to what PHP does--and I think I've seen this before-- 375 00:33:33,060 --> 00:33:39,760 is it just keeps track of what the highest numeric index it's used so far is. 376 00:33:39,760 --> 00:33:44,230 It's never going to assign a string index to 3. It will always be a numeric index. 377 00:33:44,230 --> 00:33:47,690 So it keeps track of the highest one it's assigned so far, which happens to be 10, 378 00:33:47,690 --> 00:33:52,540 and it's going to give 11 to 3. 379 00:33:52,540 --> 00:34:02,110 What I said before, notice the way it is printing this array. 380 00:34:02,110 --> 00:34:06,850 It prints key 10, key 4, key 11, key d. 381 00:34:06,850 --> 00:34:09,790 Or even let's do-- 382 00:34:15,760 --> 00:34:22,489 I guess I didn't put a 0, but it's printing 1, 2, 3, 4. 383 00:34:22,489 --> 00:34:29,330 What if I switch here? Or let's actually switch these 2. 384 00:34:29,330 --> 00:34:31,940 Now it prints 2, 1, 3, 4. 385 00:34:31,940 --> 00:34:41,270 PHP's arrays aren't just like your regular hash table. 386 00:34:41,270 --> 00:34:45,570 It's perfectly reasonable to think of them as hash tables 99% of the time. 387 00:34:45,570 --> 00:34:53,790 But in your hash tables there's no sense of the order in which things were inserted. 388 00:34:53,790 --> 00:34:56,639 So as soon as you insert it into your hash table, 389 00:34:56,639 --> 00:35:00,590 assume there's no linked list and you could judge within a linked list 390 00:35:00,590 --> 00:35:03,980 which was inserted first. 391 00:35:03,980 --> 00:35:10,060 But here we inserted 2 first and it knows when it's printing out this array that 2 comes first. 392 00:35:10,060 --> 00:35:13,090 It does not print it out in just any order. 393 00:35:13,090 --> 00:35:17,550 The technical data structure that it's using is an ordered map, 394 00:35:17,550 --> 00:35:24,690 so it maps keys to values and it remembers the order in which those keys were inserted. 395 00:35:24,690 --> 00:35:31,600 Basically it's to some complications where it's annoying to actually-- 396 00:35:31,600 --> 00:35:34,510 Let's say you have an array 0, 1, 2, 3, 4, 5 397 00:35:34,510 --> 00:35:37,700 and you want to take out index 2. 398 00:35:37,700 --> 00:35:47,750 One way of doing it, let's see what that looks like. 399 00:35:47,750 --> 00:35:50,410 0, 2, 1, 3, 4. 400 00:35:50,410 --> 00:35:54,880 Unset happens to unset both variables and array indices. 401 00:35:54,880 --> 00:35:58,630 So unset($array[2]); 402 00:35:58,630 --> 00:36:03,430 Now what's this going to look like? 2 is just gone, so that's perfectly fine. 403 00:36:03,430 --> 00:36:11,670 More annoying is if you want things to actually be like an array. 404 00:36:11,670 --> 00:36:14,910 I'll put random numbers. 405 00:36:14,910 --> 00:36:20,400 Now notice my indices. 406 00:36:20,400 --> 00:36:26,860 I want it to just be like a C array where it goes from 0 to length - 1 407 00:36:26,860 --> 00:36:30,810 and I can iterate over it as such. 408 00:36:30,810 --> 00:36:38,520 But as soon as I unset the second index, what was in index 3 doesn't now become index 2. 409 00:36:38,520 --> 00:36:44,790 Instead it just removes that index and now you go 0, 1, 3, 4. 410 00:36:44,790 --> 00:36:48,740 This is perfectly reasonable. 411 00:36:48,740 --> 00:36:53,950 It's just annoying and you have to do things like array splice. Yeah. 412 00:36:53,950 --> 00:36:57,200 >> [student] What would happen if you had a for loop 413 00:36:57,200 --> 00:36:59,630 and you wanted to go over all the elements? 414 00:36:59,630 --> 00:37:02,290 When it hit 2, would it yield ever? 415 00:37:02,290 --> 00:37:10,150 Iterating over an array. There are 2 ways you can do it. 416 00:37:10,150 --> 00:37:12,770 You can use a regular for loop. 417 00:37:12,770 --> 00:37:22,000 This is another intricacy of PHP. 418 00:37:22,000 --> 00:37:27,420 Most languages, I would say, have some sort of length or len or something 419 00:37:27,420 --> 00:37:30,470 indicating the length of an array. 420 00:37:30,470 --> 00:37:32,820 In PHP it's count. 421 00:37:32,820 --> 00:37:36,160 So count($array); $i++) 422 00:37:36,160 --> 00:37:42,950 Let's just print($array[$i]); 423 00:37:45,920 --> 00:37:48,820 Notice: Undefined offset: 2. 424 00:37:48,820 --> 00:37:51,610 It's just going to fail. 425 00:37:51,610 --> 00:38:03,020 This is the reason that, for the most part, you never need to iterate over an array like this. 426 00:38:03,020 --> 00:38:07,110 It might be an exaggeration, but you never need to iterate over an array like this 427 00:38:07,110 --> 00:38:19,410 because PHP provides its foreach syntax where foreach($array as $item). 428 00:38:19,410 --> 00:38:31,830 Now if we print($item);--we'll discuss it in a second--that works perfectly fine. 429 00:38:31,830 --> 00:38:38,960 The way that foreach is working is the first argument is the array that you're iterating over. 430 00:38:38,960 --> 00:38:44,060 And the second argument, item, through each pass of the for loop 431 00:38:44,060 --> 00:38:52,690 it's going to take on the next thing in the array. So remember the array has an order. 432 00:38:52,690 --> 00:38:55,690 The first time through the for loop, item is going to be 123 433 00:38:55,690 --> 00:38:59,540 then it will be 12 then it will be 13 then it will be 23 then it will be 213. 434 00:38:59,540 --> 00:39:04,670 Things get really weird when you do something like foreach. 435 00:39:04,670 --> 00:39:07,480 Let's see what happens because you should never do this. 436 00:39:07,480 --> 00:39:13,320 What if we unset($array[1]); 437 00:39:20,410 --> 00:39:26,030 That was probably expected. 438 00:39:26,030 --> 00:39:30,950 You're iterating over this array, and each time you're unsetting the first index. 439 00:39:30,950 --> 00:39:39,720 So for index 0, the first thing, item takes on value 0, so it's going to be 123. 440 00:39:39,720 --> 00:39:44,630 But inside of the for loop we unset index 1, so that means 12 is gone. 441 00:39:44,630 --> 00:39:57,480 So print . PHP_EOL. 442 00:39:57,480 --> 00:40:03,580 PHP_EOL is just newline, but it's technically more portable 443 00:40:03,580 --> 00:40:08,890 since newlines in Windows is different from newlines on Mac and UNIX. 444 00:40:08,890 --> 00:40:18,040 On Windows newline is \r\n, whereas everywhere else it tends just to be \n. 445 00:40:18,040 --> 00:40:25,150 PHP_EOL is configured so that it uses whatever the newline of your system is. 446 00:40:25,150 --> 00:40:29,310 So print that. Let's not print_r($array) at the end. 447 00:40:32,830 --> 00:40:37,390 I had no idea that that would be the behavior. 448 00:40:41,740 --> 00:40:48,960 Item still takes on the value 12 even though we unset 12 before we ever got to it from the array. 449 00:40:52,770 --> 00:40:58,840 Don't take my word on this, but it looks like foreach creates a copy of the array 450 00:40:58,840 --> 00:41:02,160 and then item takes on all values of that copy. 451 00:41:02,160 --> 00:41:07,760 So even if you modify the array inside the for loop, 452 00:41:07,760 --> 00:41:17,240 it won't care. Item will take on the original values. 453 00:41:17,240 --> 00:41:19,240 Let's try unsetting it. 454 00:41:19,240 --> 00:41:24,460 What if this is $array[1] = "hello"; 455 00:41:24,460 --> 00:41:31,770 Even though we put "hello" into the array, item never takes on that value. 456 00:41:31,770 --> 00:41:37,430 There's another syntax to foreach loops 457 00:41:37,430 --> 00:41:45,900 where you put 2 variables separated by an arrow. 458 00:41:45,900 --> 00:41:49,680 This first variable is going to be the key of that value, 459 00:41:49,680 --> 00:41:53,050 and this second variable is going to be the same exact item. 460 00:41:53,050 --> 00:42:01,610 This is uninteresting here, but if we go back to our original case of 'a' -> 1, 461 00:42:01,610 --> 00:42:06,090 'b' -> 1, 462 00:42:06,090 --> 00:42:14,470 here if we just iterate for each array as item, item is going to be 1 every single time. 463 00:42:14,470 --> 00:42:18,170 But if we also want to know the key associated with that item 464 00:42:18,170 --> 00:42:25,230 then we do as $key -> $item. 465 00:42:25,230 --> 00:42:31,980 So now we can do print($key . ': ' . 466 00:42:31,980 --> 00:42:39,380 Now it's iterating over and printing each key and its associated value. 467 00:42:39,380 --> 00:42:47,030 >> An additional thing we can do in foreach loops is you might see this syntax. 468 00:42:47,030 --> 00:42:54,770 Ampersands before variable names tend to be how PHP does references. 469 00:42:54,770 --> 00:43:00,460 Where references are very similar to pointers, 470 00:43:00,460 --> 00:43:04,820 you do not have pointers, so you never deal with memory directly. 471 00:43:04,820 --> 00:43:12,620 But you do have references where 1 variable refers to the same thing as another variable. 472 00:43:12,620 --> 00:43:21,450 Inside of here let's do $item. Let's go back to 1, 10. 473 00:43:21,450 --> 00:43:28,800 Let's do $item++; That still exists in PHP. You can still do ++. 474 00:43:28,800 --> 00:43:38,260 php.test.php. I have to print it. print_r($array); 475 00:43:38,260 --> 00:43:42,730 We print 2, 11. 476 00:43:42,730 --> 00:43:49,560 If I had just done foreach($array as $item) then item will be the value 1 477 00:43:49,560 --> 00:43:54,190 the first time through the loop. It will increment 1 to 2 and then we're done. 478 00:43:54,190 --> 00:43:57,260 So then it will go through the second pass of the loop and that item is 10. 479 00:43:57,260 --> 00:44:01,570 It increments item to 11, and then that's just thrown away. 480 00:44:01,570 --> 00:44:06,670 Then we print_r($array); and let's see that this is just 1, 10. 481 00:44:06,670 --> 00:44:09,070 So the increment we did was lost. 482 00:44:09,070 --> 00:44:13,410 But foreach($array as &$item) 483 00:44:13,410 --> 00:44:21,910 now this item is the same item as this right here. It's the same thing. 484 00:44:21,910 --> 00:44:26,820 So $item++ is modifying array 0. 485 00:44:29,330 --> 00:44:41,850 Basically, you can also do $k -> $item and you can do $array[$k]++; 486 00:44:41,850 --> 00:44:48,650 >> So another way of doing that, we are free to modify item, 487 00:44:48,650 --> 00:44:54,070 but that will not modify our original array. 488 00:44:54,070 --> 00:44:59,720 But if we use k, which is our key, then we can just index into our array using that key 489 00:44:59,720 --> 00:45:01,530 and increment that. 490 00:45:01,530 --> 00:45:05,410 This more directly modifies our original array. 491 00:45:05,410 --> 00:45:10,690 You can even do that if for some reason you wanted the ability to modify-- 492 00:45:10,690 --> 00:45:13,510 Actually, this is perfectly reasonable. 493 00:45:13,510 --> 00:45:16,020 You didn't want to have to write $array[$k]++, 494 00:45:16,020 --> 00:45:27,890 you just wanted to write $item++ but you still wanted to say if($k === 'a') 495 00:45:27,890 --> 00:45:30,620 then increment item and then print our array. 496 00:45:30,620 --> 00:45:36,290 So now what do we expect print_r to do? What values should be printed? 497 00:45:36,290 --> 00:45:43,770 [student] 2 and 10. >>[Bowden] Only if the key was 'a' do we actually print that. 498 00:45:51,940 --> 00:45:55,670 >> You probably very rarely, if ever, will need to define functions in PHP, 499 00:45:55,670 --> 00:46:03,370 but you might see something similar where you define a function like function whatever. 500 00:46:03,370 --> 00:46:09,900 Usually you would say ($foo, $bar) and then define it to be whatever. 501 00:46:09,900 --> 00:46:17,580 But if I do this, then that means that whatever calls whatever, 502 00:46:17,580 --> 00:46:25,110 whatever calls baz, so the first argument passed to baz can be changed. 503 00:46:25,110 --> 00:46:38,100 Let's do $foo++; 504 00:46:38,100 --> 00:46:48,020 and inside of here let's do baz($item); 505 00:46:48,020 --> 00:46:52,250 Now we are calling a function. 506 00:46:52,250 --> 00:46:56,780 The argument is taken by reference, which means that if we modify it 507 00:46:56,780 --> 00:47:00,390 we're modifying the thing that was passed in. 508 00:47:00,390 --> 00:47:04,420 And printing this we expect--unless I messed up syntax--we got 2, 11, 509 00:47:04,420 --> 00:47:06,300 so it was actually incremented. 510 00:47:06,300 --> 00:47:08,790 Notice we need references in 2 places. 511 00:47:08,790 --> 00:47:13,050 What if I did this? What does this mean? 512 00:47:13,050 --> 00:47:15,810 [student] It will change. >>Yeah. 513 00:47:15,810 --> 00:47:18,290 Item is just a copy of the value in the array. 514 00:47:18,290 --> 00:47:26,670 So item will change to 2, but the array['a'] will still be 1. 515 00:47:26,670 --> 00:47:32,560 Or what if I do this? 516 00:47:32,560 --> 00:47:39,260 Now item is sent as a copy to baz. 517 00:47:39,260 --> 00:47:46,330 So the copy of the argument will be incremented to 2, 518 00:47:46,330 --> 00:47:49,240 but item itself was never incremented to 2. 519 00:47:49,240 --> 00:47:52,880 And item is the same thing as array bracket whatever, 520 00:47:52,880 --> 00:47:55,380 so that array was never incremented. 521 00:47:55,380 --> 00:47:57,960 So both those places need it. 522 00:47:57,960 --> 00:48:03,830 >> PHP is usually pretty smart about this. 523 00:48:03,830 --> 00:48:06,570 You might think I want to pass by reference-- 524 00:48:06,570 --> 00:48:09,560 This was actually a question on one of the psets. 525 00:48:09,560 --> 00:48:14,480 It was a questions.txt thing where it said, 526 00:48:14,480 --> 00:48:19,280 Why might you want to pass this struct by reference? 527 00:48:19,280 --> 00:48:21,250 What was the answer to that? 528 00:48:21,250 --> 00:48:25,100 [student] So you don't have to copy something big. >>Yeah. 529 00:48:25,100 --> 00:48:32,920 A struct can be arbitrarily large, and when you pass the struct in as an argument 530 00:48:32,920 --> 00:48:36,800 it needs to copy that entire struct to pass it to the function, 531 00:48:36,800 --> 00:48:40,410 whereas if you just pass the struct by reference 532 00:48:40,410 --> 00:48:46,530 then it just needs to copy a 4-byte address as the argument to the function. 533 00:48:48,520 --> 00:48:52,320 PHP is a little bit smarter than that. 534 00:48:52,320 --> 00:49:00,650 If I have some function and I pass to it an array of 1,000 things, 535 00:49:00,650 --> 00:49:03,990 does that mean it's going to have to copy all 1,000 of those things 536 00:49:03,990 --> 00:49:10,450 to pass it into the function? It doesn't have to do that immediately. 537 00:49:10,450 --> 00:49:15,940 If inside of this function it never actually modifies foo, 538 00:49:15,940 --> 00:49:22,660 so if($foo === 'hello') return true.; 539 00:49:22,660 --> 00:49:26,460 Notice we never actually modified the argument inside of this function, 540 00:49:26,460 --> 00:49:30,010 which means that whatever was passed in as foo never needs to be copied 541 00:49:30,010 --> 00:49:32,100 because it's not modifying it. 542 00:49:32,100 --> 00:49:39,240 So the way PHP works is the arguments are always passed by reference 543 00:49:39,240 --> 00:49:42,170 until you actually try to modify it. 544 00:49:42,170 --> 00:49:51,160 Now if I say $foo++; it will now make a copy of the original foo and modify the copy. 545 00:49:51,160 --> 00:49:53,090 This saves some time. 546 00:49:53,090 --> 00:49:58,210 If you're never touching this massive array, you never actually modify it, 547 00:49:58,210 --> 00:50:02,360 it doesn't need to make the copy, 548 00:50:02,360 --> 00:50:06,640 whereas if we just put this ampersand that means it doesn't even copy it 549 00:50:06,640 --> 00:50:08,640 even if you do modify it. 550 00:50:08,640 --> 00:50:10,680 This behavior is called copy-on-write. 551 00:50:10,680 --> 00:50:17,380 You'll see it in other places, especially if you take an operating system course. 552 00:50:17,380 --> 00:50:23,880 Copy-on-write is a pretty usual pattern where you don't need to make a copy of something 553 00:50:23,880 --> 00:50:26,650 unless it's actually changing. Yeah. 554 00:50:26,650 --> 00:50:29,520 [student] What if you had the increment inside the test, 555 00:50:29,520 --> 00:50:33,700 so only 1 element out of 1,000 would need to be changed? 556 00:50:33,700 --> 00:50:38,770 I'm not sure. 557 00:50:38,770 --> 00:50:51,250 I think it would copy the entire thing, but it's possible it's smart enough that-- 558 00:50:51,250 --> 00:51:00,020 Actually, what I'm thinking is imagine we had an array that looks like this: $array2 = [ 559 00:51:00,020 --> 00:51:11,000 Then index 'a' is an array of [1 2 3 4], and index 'b' is an array of whatever. 560 00:51:11,000 --> 00:51:15,380 I need commas between all of those. Imagine there are commas. 561 00:51:15,380 --> 00:51:21,210 Then 'c' is the value 3. 562 00:51:24,210 --> 00:51:26,290 Okay. 563 00:51:26,290 --> 00:51:33,440 Now let's say we do $baz($array2); 564 00:51:33,440 --> 00:51:36,540 where baz does not take this by reference. 565 00:51:43,510 --> 00:51:47,370 So $foo['c']++; 566 00:51:47,370 --> 00:51:52,340 This is such an example where we are passing array2 as an argument 567 00:51:52,340 --> 00:51:57,010 and then it is modifying a specific index of the array by incrementing it. 568 00:51:57,010 --> 00:52:01,090 I honestly have no idea what PHP is going to do. 569 00:52:01,090 --> 00:52:07,200 It can easily make a copy of the entire thing, but if it's smart, 570 00:52:07,200 --> 00:52:15,030 it will make a copy of these keys where this will have its distinct value 571 00:52:15,030 --> 00:52:20,620 but this can still point to the same array 1,2,3,4 572 00:52:20,620 --> 00:52:22,320 and this can still point to the same array. 573 00:52:22,320 --> 00:52:24,170 I'll iPad it. 574 00:52:28,900 --> 00:52:45,950 We pass in this array where this guy points to 3, this guy points to [1,2,3,4], 575 00:52:45,950 --> 00:52:51,350 this guy points to [34,...] 576 00:52:51,350 --> 00:52:58,590 Now that we're passing it in to baz, we are modifying this. 577 00:52:58,590 --> 00:53:03,550 If PHP is smart, it can just do-- 578 00:53:11,850 --> 00:53:18,230 We still had to copy some memory, but if there were these huge nested subarrays 579 00:53:18,230 --> 00:53:21,560 we didn't need to copy those. 580 00:53:21,560 --> 00:53:27,530 I don't know if that's what it does, but I can imagine it doing that. 581 00:53:29,050 --> 00:53:36,690 This is also a pretty big advantage of C over PHP. 582 00:53:36,690 --> 00:53:40,320 >> PHP makes life so much easier for a lot of things, 583 00:53:40,320 --> 00:53:45,060 but you kind of have absolutely no idea how well it will perform 584 00:53:45,060 --> 00:53:52,530 because I have no idea underneath the hood when it's making these copies of things, 585 00:53:52,530 --> 00:53:55,170 oh, is that going to be a constant time copy, 586 00:53:55,170 --> 00:54:01,140 is it just going to change 1 pointer, is it going to be a ridiculously difficult linear copy? 587 00:54:01,140 --> 00:54:03,000 What if it can't find space? 588 00:54:03,000 --> 00:54:06,760 Does it then need to run garbage collection to get some more space? 589 00:54:06,760 --> 00:54:11,210 And garbage collection can take arbitrarily long. 590 00:54:11,210 --> 00:54:13,600 In C you don't have to worry about these things. 591 00:54:13,600 --> 00:54:19,780 Every single line you write you can pretty much reason about how it's going to perform. 592 00:54:26,800 --> 00:54:29,150 >> Let's look back at these. 593 00:54:35,400 --> 00:54:37,520 How nice is it that you don't have to deal with hash functions, 594 00:54:37,520 --> 00:54:39,010 linked lists, or anything like that? 595 00:54:39,010 --> 00:54:41,980 Since working with hash tables is so easy now, here's a fun puzzle to work on. 596 00:54:41,980 --> 00:54:45,920 Open up a file called unique.php and in it write a PHP program 597 00:54:45,920 --> 00:54:48,330 (also known as a "script"). 598 00:54:48,330 --> 00:54:55,700 We tend to call them scripts if they're short things that you run at the command line. 599 00:54:55,700 --> 00:55:02,950 Basically, any language that you don't compile but you're going to run the executable 600 00:55:02,950 --> 00:55:05,920 at the command line, you can call that executable script. 601 00:55:05,920 --> 00:55:08,510 I could just as well write a C program that does this, 602 00:55:08,510 --> 00:55:12,300 but I don't call it a script since I first compile it and then run the binary. 603 00:55:12,300 --> 00:55:15,480 But this PHP program we're going to call a script. 604 00:55:15,480 --> 00:55:23,830 Or if we wrote it in Python or Perl or Node.js or any of those things, 605 00:55:23,830 --> 00:55:26,500 we'd call them all scripts because you run them at the command line 606 00:55:26,500 --> 00:55:30,040 but we don't compile them. 607 00:55:30,860 --> 00:55:33,400 We could do this pretty quickly. 608 00:55:36,960 --> 00:55:41,480 We aren't going to use argv. Let's just blow through this. 609 00:55:41,480 --> 00:55:45,730 Call it unique, write a program. 610 00:55:45,730 --> 00:55:49,400 You can assume that the input will contain one word per line. 611 00:55:49,400 --> 00:55:52,020 Actually, argv will be pretty trivial to use. 612 00:56:03,730 --> 00:56:06,720 unique.php. 613 00:56:08,550 --> 00:56:13,750 First thing first, we want to check if we have been passed 1 command-line argument. 614 00:56:13,750 --> 00:56:20,900 Just as you would expect argc and argv in C, we still have those in PHP. 615 00:56:20,900 --> 00:56:33,900 So if($argc !== 2) then I won't deal with printing a message or anything. 616 00:56:33,900 --> 00:56:37,340 I'll just exit, error code of 1. 617 00:56:37,340 --> 00:56:41,340 I could also return 1. 618 00:56:41,340 --> 00:56:53,180 Rarely in PHP are you at this state where we're at-- 619 00:56:53,180 --> 00:56:57,820 Usually you're in a function called by a function called by a function called by a function. 620 00:56:57,820 --> 00:57:02,070 And if something goes wrong and you just want to exit everything entirely, 621 00:57:02,070 --> 00:57:05,680 exit just ends the program. 622 00:57:05,680 --> 00:57:08,160 This also exists in C. 623 00:57:08,160 --> 00:57:10,700 If you're in a function in a function in a function in a function 624 00:57:10,700 --> 00:57:17,540 and you want to just kill the program, you can call exit and it will just exit. 625 00:57:17,540 --> 00:57:23,120 But in PHP it's even more rare that we are at this top level. 626 00:57:23,120 --> 00:57:26,090 Usually we're inside some sort of function, so we call exit 627 00:57:26,090 --> 00:57:29,650 so that we don't have to return up 1 thing which then realizes there's an error 628 00:57:29,650 --> 00:57:32,270 so that returns up if that recognizes there was an error. 629 00:57:32,270 --> 00:57:35,270 We don't want to deal with that, so exit(1); 630 00:57:35,270 --> 00:57:38,240 return(1); in this case would be equivalent. 631 00:57:38,240 --> 00:57:44,000 >> Then what we want to open we want to fopen. 632 00:57:44,000 --> 00:57:46,760 The arguments are going to look pretty similar. 633 00:57:46,760 --> 00:57:51,600 We want to fopen($argv[1], and we want to open it for reading. 634 00:57:51,600 --> 00:57:55,720 That returns a resource which we're going to call f. 635 00:57:55,720 --> 00:58:02,180 This looks pretty similar to how C does it except we don't have to say FILE*. 636 00:58:02,180 --> 00:58:06,170 Instead we just say $f. Okay. 637 00:58:06,170 --> 00:58:17,190 Actually, I think this even gives us a hint as to PHP function called file. PHP File. 638 00:58:17,190 --> 00:58:23,990 What this is going to do is read an entire file into an array. 639 00:58:23,990 --> 00:58:29,770 You don't even need to fopen it. It's going to do that for you. 640 00:58:37,450 --> 00:58:43,700 So $lines = file($argv[1]); 641 00:58:43,700 --> 00:58:49,680 Now all of the lines of the file are in lines. Now we want to sort the lines. 642 00:58:49,680 --> 00:58:52,180 How can we sort the lines? 643 00:58:52,180 --> 00:58:54,920 We sort the lines. 644 00:58:54,920 --> 00:58:58,080 And now we can print them or whatever. 645 00:58:58,080 --> 00:59:05,580 Probably the easiest way is foreach($lines as $line) echo $line; 646 00:59:05,580 --> 00:59:10,960 [student] Wouldn't we even cross lines by referencing something into sort? 647 00:59:10,960 --> 00:59:28,850 This is where sort would be defined as function sort(&$array). 648 00:59:28,850 --> 00:59:32,650 When you call the function you don't pass it by reference. 649 00:59:32,650 --> 00:59:36,900 It's the function that defines it as taking it as reference. 650 00:59:36,900 --> 00:59:40,900 This is actually exactly what went wrong 651 00:59:40,900 --> 00:59:46,220 when we put everything to our servers when we went from 5.3 to 5.4. 652 00:59:46,220 --> 00:59:53,800 Up until 5.4, this was perfectly reasonable. 653 00:59:53,800 --> 00:59:58,740 A function doesn't expect to take it as reference, but you can pass it as reference 654 00:59:58,740 --> 01:00:02,860 so if the function does happen to modify it, it's still modified. 655 01:00:02,860 --> 01:00:05,850 As of 5.4, you're not supposed to do this. 656 01:00:05,850 --> 01:00:11,740 So now the only way you pass by reference is if the function explicitly does it. 657 01:00:11,740 --> 01:00:19,840 If you don't want it to modify it, then you need to do $copy = $lines and pass copy. 658 01:00:19,840 --> 01:00:24,820 So now lines will be preserved and copy will be changed. 659 01:00:27,670 --> 01:00:31,460 php.unique.php. I might have messed something up. 660 01:00:31,460 --> 01:00:33,190 Unexpected 'sort'. 661 01:00:38,320 --> 01:00:43,850 There's going to be something that does this for us. 662 01:00:43,850 --> 01:00:45,820 It's not even there. 663 01:00:45,820 --> 01:00:52,140 Notice when you read the manual that the first argument is expected to be an array 664 01:00:52,140 --> 01:00:56,490 and it's taken by reference. 665 01:00:58,160 --> 01:01:03,540 Why is this complaining to me? Because I have this function sort still in here that I don't want. 666 01:01:03,540 --> 01:01:09,210 Okay, php.unique.php. I didn't pass it an argument because I don't have a file. 667 01:01:09,210 --> 01:01:13,560 It's php.unique.php on test.php. 668 01:01:13,560 --> 01:01:19,080 Here is test.php all printed out in a nice sorted order. 669 01:01:19,080 --> 01:01:24,600 Notice that sorted order is kind of weird for a code file 670 01:01:24,600 --> 01:01:27,460 because all of our blank lines are going to come first 671 01:01:27,460 --> 01:01:30,190 then are going to come all of our 1 level indentations 672 01:01:30,190 --> 01:01:33,360 then come all of our no indentations. 673 01:01:33,360 --> 01:01:38,620 Yeah. >>[student] So for the source code it wasn't passed by reference? 674 01:01:38,620 --> 01:01:42,240 Is that generally passed by value? 675 01:01:42,240 --> 01:01:50,240 [Bowden] When you call a function, it never determines whether it was passed by reference. 676 01:01:50,240 --> 01:01:53,960 It's the function definition which determines whether it was passed by reference. 677 01:01:53,960 --> 01:01:59,450 And looking at the function definition of sort or just looking at this, 678 01:01:59,450 --> 01:02:02,820 it takes the argument by reference. 679 01:02:02,820 --> 01:02:07,160 So regardless of whether you want it to take it by reference, it does take it by reference. 680 01:02:07,160 --> 01:02:10,200 It modifies the array in place. 681 01:02:10,200 --> 01:02:17,400 This is just not allowed. You're not allowed to do this. >>[student] Oh, okay. 682 01:02:17,400 --> 01:02:22,410 [Bowden] This, sort is going to take lines by reference and modify it. 683 01:02:22,410 --> 01:02:26,850 And again, if you didn't want it to do that, you could make a copy of sort. 684 01:02:26,850 --> 01:02:35,850 Even in this case, copy isn't actually a copy of lines. 685 01:02:35,850 --> 01:02:40,620 It just points to the same thing until it first gets modified, 686 01:02:40,620 --> 01:02:44,430 where it's first going to get modified in the sort function, 687 01:02:44,430 --> 01:02:50,940 where, because it's copy-on-write, now a copy of copy is going to be made. 688 01:02:57,500 --> 01:03:04,250 You can also do this. That's the other place you can see ampersand. 689 01:03:04,250 --> 01:03:07,190 You see it in foreach loops, you see it in function declarations, 690 01:03:07,190 --> 01:03:10,040 and you see it when just assigning variables. 691 01:03:10,040 --> 01:03:12,350 Now we have accomplished nothing by doing this 692 01:03:12,350 --> 01:03:15,600 because copy and lines are literally the same thing. 693 01:03:15,600 --> 01:03:19,940 You can use lines and copy interchangeably. 694 01:03:19,940 --> 01:03:25,430 You can do unset($copy); and that doesn't unset lines, 695 01:03:25,430 --> 01:03:29,120 you just lose your reference to the same thing. 696 01:03:29,120 --> 01:03:33,440 So as of this point, now lines is the only way you can access lines. 697 01:03:36,450 --> 01:03:38,770 >> Questions? 698 01:03:41,000 --> 01:03:42,460 Yeah. 699 01:03:42,460 --> 01:03:45,880 [student] Completely off topic, but you don't have to close PHP with the-- >>You do not. 700 01:03:45,880 --> 01:03:47,730 Okay. 701 01:03:47,730 --> 01:03:53,790 [Bowden] I would go as far as to say it's bad practice to close them. 702 01:03:53,790 --> 01:03:57,580 That's probably an exaggeration, especially in a script, 703 01:03:57,580 --> 01:04:03,740 but let's see what happens if I do this. 704 01:04:03,740 --> 01:04:08,890 That did nothing. What if I wanted-- [sighs] 705 01:04:13,870 --> 01:04:16,960 I need to pass an argument. 706 01:04:19,000 --> 01:04:22,050 Shoot. I called it wrong. 707 01:04:24,340 --> 01:04:28,310 So php.unique.php with an argument. 708 01:04:28,310 --> 01:04:30,980 Now I don't even need this. 709 01:04:34,520 --> 01:04:37,740 I'll pass it a valid argument. 710 01:04:37,740 --> 01:04:42,050 This printed whatever it's printing. 711 01:04:45,260 --> 01:04:50,080 I'm printing copy and copy doesn't exist. So lines. 712 01:04:53,650 --> 01:04:58,270 It printed everything, and then notice all this junk down here, 713 01:04:58,270 --> 01:05:06,690 because in PHP anything that is outside of PHP tags 714 01:05:06,690 --> 01:05:09,520 is just going to be printed literally. 715 01:05:09,520 --> 01:05:18,050 That's why HTML, it's so nice that I can do div blah, blah, blah class or whatever, 716 01:05:18,050 --> 01:05:25,140 blah, blah, blah and then do some PHP code and then do end div. 717 01:05:25,140 --> 01:05:36,460 And now printing this I get my nice div up top, everything that PHP printed, div at bottom. 718 01:05:36,460 --> 01:05:43,510 Disastrous when something like this happens, which is pretty common, 719 01:05:43,510 --> 01:05:47,930 just a stray newline at the bottom of file. 720 01:05:47,930 --> 01:05:50,940 You wouldn't think it would be that big of a deal 721 01:05:50,940 --> 01:05:58,660 until you consider the fact that with browsers-- 722 01:05:58,660 --> 01:06:03,880 >> How redirects work or basically any headers work, 723 01:06:03,880 --> 01:06:07,980 when you make your connection to a website and it sends back all these headers and things 724 01:06:07,980 --> 01:06:12,020 like response 200 or response redirect or whatever, 725 01:06:12,020 --> 01:06:18,230 headers are only valid until the first byte of data is sent. 726 01:06:18,230 --> 01:06:23,140 You can redirect thousands of times, but as soon as the first byte of data is sent 727 01:06:23,140 --> 01:06:26,120 you're not supposed to redirect again. 728 01:06:26,120 --> 01:06:31,860 >> If you have a stray newline at the bottom of a file 729 01:06:31,860 --> 01:06:37,260 and let's say that you use this function and then you want to-- 730 01:06:41,580 --> 01:06:52,870 Let's say it's another file that's index.php and you require_once something-- 731 01:06:52,870 --> 01:06:56,920 I can't think of a good example of it. 732 01:06:56,920 --> 01:07:04,740 The issue happens when this line at the bottom gets echoed. 733 01:07:04,740 --> 01:07:08,660 You don't want anything to have been echoed yet. 734 01:07:10,820 --> 01:07:15,700 Even though you didn't intend on anything getting echoed, something did get echoed 735 01:07:15,700 --> 01:07:17,990 and so now you're not supposed to send any more headers 736 01:07:17,990 --> 01:07:20,030 and you're going to get complaints. 737 01:07:22,170 --> 01:07:24,420 You just don't need those closing tags. 738 01:07:24,420 --> 01:07:27,420 If you plan on doing something with HTML-- 739 01:07:27,420 --> 01:07:30,490 and it's perfectly reasonable to do down here div whatever 740 01:07:30,490 --> 01:07:39,450 and then at this point you can or you cannot include them. 741 01:07:39,450 --> 01:07:41,590 It doesn't really matter. 742 01:07:41,590 --> 01:07:45,450 But in PHP scripts it's rare to close it. 743 01:07:45,450 --> 01:07:50,400 When everything is PHP, absolutely everything, 744 01:07:50,400 --> 01:07:55,460 you don't really need to close it/you shouldn't close it. 745 01:08:02,030 --> 01:08:05,720 >> Dealing with strings is much nicer than in C. 746 01:08:05,720 --> 01:08:09,470 In PHP you can specify a string with single or double quotes. 747 01:08:09,470 --> 01:08:12,820 With single quotes you can't use "escape" sequences. 748 01:08:12,820 --> 01:08:17,640 Constantly escape, blah, blah, blah. 749 01:08:19,920 --> 01:08:24,010 So printf is very rare in PHP. 750 01:08:24,010 --> 01:08:32,290 I guess I would use printf if I wanted to do a sort of thing--in pset 5 you used sprintf or whatever. 751 01:08:32,290 --> 01:08:36,060 But you want to do 001.jpg and 002.jpg. 752 01:08:36,060 --> 01:08:40,300 So for that sort of thing where I actually want to format the text I would use printf. 753 01:08:40,300 --> 01:08:44,689 But otherwise I would just use string concatenation. 754 01:08:44,689 --> 01:08:47,000 I never really use printf. 755 01:08:49,229 --> 01:09:00,170 We're just differentiating the details between single quotes and double quotes. 756 01:09:00,170 --> 01:09:07,490 The biggest difference is that single quotes, it will be printed literally. 757 01:09:07,490 --> 01:09:15,390 There is no char data type in PHP, unlike C, so this is equivalent to this. 758 01:09:15,390 --> 01:09:17,970 They're both strings. 759 01:09:17,970 --> 01:09:29,180 And the nice thing about single quote strings is I could say 'hello world!' blah, blah, blah, 760 01:09:29,180 --> 01:09:33,340 $$wooo. 761 01:09:33,340 --> 01:09:38,260 What happens when I print this is it will print it literally. 762 01:09:38,260 --> 01:09:40,680 Let's get rid of all of our stuff. 763 01:09:40,680 --> 01:09:44,700 So echo $str1; 764 01:09:48,569 --> 01:09:56,570 It literally printed all of those things: dollar signs, 765 01:09:56,570 --> 01:09:58,770 backslash n, which you would think would be newlines-- 766 01:09:58,770 --> 01:10:01,500 all of those things it prints literally. 767 01:10:01,500 --> 01:10:05,650 The only thing you need to escape are single quotes 768 01:10:05,650 --> 01:10:09,470 because otherwise it would think it's closing the single quotes. 769 01:10:09,470 --> 01:10:15,050 Double quotes, completely different. 770 01:10:20,300 --> 01:10:25,870 We already see the syntax highlighting is cluing us on to what's about to go terribly wrong. 771 01:10:25,870 --> 01:10:36,190 php.unique. Undefined variable: wooo because this is interpreted as a variable called wooo. 772 01:10:36,190 --> 01:10:42,400 Double quotes let you insert variables into-- 773 01:10:42,400 --> 01:10:52,730 Let's say $name = "Rob"; 774 01:10:52,730 --> 01:10:58,020 So echo "Hi, my name is $name!!"; 775 01:10:58,020 --> 01:11:09,260 It recognizes this as a variable. 776 01:11:09,260 --> 01:11:21,210 When I run that--and I will insert a newline--Hi, my name is Rob!! and hello world!! 777 01:11:21,210 --> 01:11:24,910 This is because I never removed the printing of wooo above. 778 01:11:24,910 --> 01:11:30,020 There is 1 further step you can do. 779 01:11:30,020 --> 01:11:39,250 $array = [1, 2, 3]; 780 01:11:39,250 --> 01:11:43,270 What if I want to print the first index of array? 781 01:11:43,270 --> 01:11:45,150 You do $array[0]. 782 01:11:45,150 --> 01:11:49,280 The syntax highlighting is a clue. What is this going to do? 783 01:11:52,320 --> 01:11:54,510 php.unique. 784 01:11:54,510 --> 01:11:59,860 Hi, my name is 1!! which is not what I wanted. 785 01:11:59,860 --> 01:12:05,050 Syntax highlighting lied to me. 786 01:12:05,050 --> 01:12:13,020 Let's try 'a' -> 1, 'b' -> 2. 787 01:12:18,450 --> 01:12:21,440 That's how I would have to write it. 788 01:12:26,350 --> 01:12:32,160 Unexpected single quote (T_ENCAPSED blah, blah, blah, blah, blah). 789 01:12:32,160 --> 01:12:41,780 The idea is that it's not recognizing this as part of the array. 790 01:12:41,780 --> 01:12:46,620 It's not recognizing this as array indexed by letter a. 791 01:12:46,620 --> 01:12:49,870 You want to do that surrounded by curly braces, 792 01:12:49,870 --> 01:12:54,730 and now whatever is in this curly brace will be interpolated, 793 01:12:54,730 --> 01:13:00,340 which is the word we use for magically inserting these variables into the right places. 794 01:13:00,340 --> 01:13:04,280 Now doing this, php.unique, and Hi, my name is 1!! as expected 795 01:13:04,280 --> 01:13:07,720 or Hi, my name is Rob!! 796 01:13:14,110 --> 01:13:23,130 One thing that's kind of nice about single quotes is that-- 797 01:13:23,130 --> 01:13:28,480 There's some cost to interpolating. 798 01:13:30,520 --> 01:13:35,100 If you use double quotes, the interpreter has to go over this string, 799 01:13:35,100 --> 01:13:41,500 making sure that, "Oh, here's a variable. Now I need to go get that variable and insert it here." 800 01:13:41,500 --> 01:13:48,930 Even if you don't use any variables, 801 01:13:48,930 --> 01:13:52,220 nothing inside of these double quotes needs to be interpolated, 802 01:13:52,220 --> 01:13:56,800 but it will still be slower because it needs to go over the double quotes 803 01:13:56,800 --> 01:14:00,130 looking for things that need to be interpolated. 804 01:14:00,130 --> 01:14:05,360 So single quotes can be a bit faster if nothing needs to be interpolated, 805 01:14:05,360 --> 01:14:15,650 and I tend to even use single quotes for, 'Hi, my name is ' . $array['a'] anyway. 806 01:14:15,650 --> 01:14:20,430 That's going to be equivalent to what we had before. 807 01:14:24,840 --> 01:14:28,440 But it's a matter of preference. 808 01:14:28,440 --> 01:14:34,750 If you're using PHP, you probably don't care about the speed difference. 809 01:14:34,750 --> 01:14:39,480 There isn't enough to reason them out to begin with. 810 01:14:39,480 --> 01:14:43,030 >> Any final questions? 811 01:14:47,430 --> 01:14:51,710 >> We actually didn't even get through all of it, but this stuff was boring. 812 01:14:51,710 --> 01:14:59,080 The last thing that's kind of nice in PHP is when you're dealing with HTML, 813 01:14:59,080 --> 01:15:06,450 you'll use it a bit, so the nice shortcut syntax for printing a variable. 814 01:15:32,400 --> 01:15:36,730 Without putting PHP here, this is called short tags. 815 01:15:36,730 --> 01:15:44,330 Officially as of PHP 5.4, this is deprecated. 816 01:15:44,330 --> 01:15:48,640 You are recommended to put php. 817 01:15:48,640 --> 01:15:55,770 This is still supported, so short tags with the 01:16:02,480 It is by default supported, so you can use these as you wish, and they're pretty convenient. 819 01:16:02,480 --> 01:16:05,700 >> Any questions? 820 01:16:07,780 --> 01:16:09,270 All right. 821 01:16:10,840 --> 01:16:13,800 >> Stay classy, San Diego. 822 01:16:13,800 --> 01:16:16,070 [chuckles] 823 01:16:18,620 --> 01:16:22,660 Bye. [laughs] 824 01:16:24,350 --> 01:16:28,470 [applause] [laughs] 825 01:22:46,460 --> 01:22:49,460 >> [CS50.TV]