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