>> To begin to bridge what might be your only experience
with web programming, what I thought I'd do is steal a couple
of examples that you may have seen in 50
if you took it the past year or two or may not have
if you took it a few years ago
that are baby steps toward a pyridine know as MBC,
Model View Controller, and what does this mean?
This is we'll see again perhaps is just a way of starting
to clean up the design of some web-based piece of software,
or it could be client side based as well, but we'll use it
in the context of PHP, so that we can begin
to make more complex projects and sort
of separate different types of code within the application;
particularly so that when we have multiple people working
on a project it's a lot easier to draw lines.
So first let's take a look at a suboptimal way
of implementing something.
Suppose I wanted to make a super simple course website for 50
or any other class, and that class has things
like lectures and a syllabus.
I could do something like an h1 tag at the top of my page
and an unordered list with li list items in order
to just have a bulleted list of menu options, so super simple.
So how might we do this?
Well, let me go into my terminal window here,
and notice that I've got a read me and we'll link to this code
on the course's website in a bit,
and notice that I've got index dot htm-- index dot php.
So let me go ahead and open that, and sure enough it's kind
of silly that this even called php
because all I have is a php comment
and then everything else is just raw html code.
But again this is version zero,
so a step towards something more interesting,
but notice I've hard coded CS50 as the title, CS50 in the h1,
and now I have the lectures link,
now I have the syllabus link.
All right, so that doesn't seem all that unreasonable
until you follow a link like lectures, and you realize
that all right it's different content but it's kind
of the same thing; it's a title of the page and unordered list.
I click week zero from last year, and it's kind
of the same thing, an h1 tag and an unordered list
and then finally I click this, and I get to some leaf,
which is the slides from that particular lecture.
So something tells me I'm about to cringe.
If I open up lectures dot php notice
that it's pretty much copy and paste from the previous file;
I just changed the title to h1, and what these links are.
Worse yet, if I go into week zero dot php,
it's the same copy paste job
with just a bit of content tweaked.
So surely there's an opportunity here to improve,
and surely this should be a good rule of thumb;
anytime you feel yourself copying
and pasting something more than maybe once,
red flags should hopefully start to go off.
But how do we go about improving this?
Well, there's a few ways, and the techniques you can use
in php have evolved over time, but let's try this one.
Let me go into Version one, so the next iteration of this,
and let me try to clean it up a bit.
Right, one of php's simplest mechanisms
for solving this problem is the old school require function,
which pretty much does a copy and paste of the contents
of some file right here, like c is sharp include,
and other languages have very similar constructs.
So it looks a little strange now,
it's definitely not a complete looking web page,
but presumably what's inside of header dot php.
All of the other stuff, right, the html tag, the head tag,
the title tag, all the stuff that was above the main essence
of the page, which is arguably just the unordered list,
and in the footer is probably like the closed body tag,
the closed html's tag; pretty uninteresting
but duplicative stuff.
All right, and sure enough if I go
into header dot php it's just kind of the orphan fragment
from the top, and if I go into footer dot php,
it's the orphaned fragment from the bottom,
and I'm using those same fragments in my other files,
like lectures dot php.
All right, so what's better about this would you say?
Yeah?
>> Simplicity.
>> Simplicity?
I don't know this kind of looks a lot scarier to me now, right?
>> If I wanted to change your header, you wouldn't have
to change it in all the previous like files.
You just change it in your header.
>> Exactly, so maybe in that sense it's simpler,
maybe I'd frame it as it's just it's easier to update it.
It's maybe a little cleaner
because you update it in just one place.
So that's pretty compelling; what's a downside
of this approach or what problem remains
that we haven't really solved?
Yeah?
[ Off Mic Comment ]
Yeah, exactly, I mean, I'm still copying and pasting;
it's a little less, but I only pulled up two of these files,
and they pretty much still looked identical.
There was a require at the top, a require at the bottom,
and an unordered list in the middle
which itself was still structurally the same.
Moreover, notice this, if I actually view this example,
let me go to Version One now,
and notice I've got CS50 Lecture Syllabus.
Uh oh, CS50 Week Zero Week One and CS50 Wednesday Friday,
I've kind of cut a corner.
What was-- what were those titles previously?
[ Off Mic Comment ]
They were like lectures in Week Zero, like it was kind
of sexier, and it actually had some dynamism to it,
and this is kind of-- I'm just kind of punting now
and just assuming that the whole website is CS50
and okay it works, but it's certainly not as elegant
or as sort of straight forward as it once was,
but that makes sense, because if you look at index dot php
and lectures dot php and week zero dot php,
they're all including the same file,
so how can we improve this?
What's the next iteration of this code probably going to do?
[ Off Mic Comment ]
Yeah, exactly, so if-- and let me summarize
with we essentially want to parameterize that header
so that yes there's still a hard coded h1 tag, but the stuff
in between, the open and the close tag,
is presumably dynamic, and coming from something else.
Maybe the "get string" or the thing after the question mark
in the URL were somewhere else, so let's take a look.
So if I go into Version Two,
now notice that I've got an additional file,
it looks like helpers dot php.
I don't really know where to begin so I'm going to start just
at index like as always, and now notice it's a little different,
so I've got a require line
at the top requiring helpers dot php,
but I can call it whatever I want,
but now notice line three there is a function call
to render header, which is interesting only in so far
as what's being passed in apparently, the custom title
for this particular page.
Meanwhile there's render footer at the bottom,
and I don't need any parameterization there it's just
a footer, but now there seems
to be a step toward a better solution, render header takes,
and what do the square brackets indicate for those
who haven't seen php ever or in a while?
[ Off Mic Comment ]
Yeah, it's an array.
It's an associative array or a hash that associates keys
with values; it's like Java Scripts, objection notation,
or other languages, similar syntaxs.
All right, so what is in helpers dot php?
In helpers dot php it's just a couple of functions,
render header and render footer.
So a couple of details if less familiar,
so first of all the fact
that render header takes a data argument that's apparently
assigned the empty array there means what?
What does it mean to do equals open bracket closed bracket
as a parameter in php?
It's the default value.
So if I don't pass in array or any argument whatsoever
to the render header or the render footer function,
I can at least trust as the author of those functions
that data will minimally be an empty array;
it won't be undefined or false, or something like that,
it will be exactly what I gave it as a default.
Now this is a bit of a sort of a hackish way of loading symbols
into your name space so to speak,
but it works pretty well toward this end
of implementing our own sort of poor man's templating engine.
All right, there's a lot of tools out there for Python Ruby
and php that give you templating capabilities
and that's exactly what we want.
We want a template that has an h1 open tag, an h1 closed tag,
and sort of a place holder in the middle,
and we want to fill those place holders by way of this function,
so this function extract just so happens
to give you the following capabilities.
If you've got an associative of array with key value pairs
like foo equals bar, extract will create a local variable
called effectively dollar sign foo and give it a value of bar
so it explodes your associative array from key value pairs
into new variables with the corresponding values.
And then require dot header dot php is the same as before,
so what are we probably going to see inside of header dot php?
It's probably got that h1 tag and the close tag; what's going
to be inside of it probably in between it?
[ Off Mic Comment ]
Exactly, there's probably some mention of dollar sign title
and sure enough if I zoom in on this there's my title tag,
there's my h1 tag, and inside of it is a dynamic insertion
of dollar sign title, but just for good measure,
I'm doing this html special charge atrociously named
function, but it's useful; what does it do
or what does it protect against?
This is actually a solution to a threat you are hinting;
you would have led us to.
[ Off Mic Comment ]
Exactly, so if a malicious user or an unsuspecting victim
of a phishing attack clicked on a link
that in self had a question mark and something like foo equals,
and then the value of foo was actually
like open bracket script, closed bracket,
and then some JavaScript code;
if you didn't call this long main function,
you would actually be infecting raw html into your web page,
the result of which is that you might be tricked.
You might be tricking the user into executing JavaScript code
that he or she did not actually intend.
And even though usually you're only hurting yourself,
like only you know an idiot is going to type
in open bracket script, closed bracket, and say alert
or something like that and do him or herself
in with some weird outcome, if you do get tricked
into clicking a link that has raw JavaScript embedded in it
as the value of that attribute,
you can among other things steal someone's cookies
because there's a property called document dot cookie
in JavaScript that allows you to grab a user's session cookie,
and if you recall what a session hijacking attack is,
long story short, that's one way of actually tricking someone
into giving you that virtual hand stamp and then taking
over their Facebook account or some other type of account.
All right, so this is a little long,
but it's just using raw html code.
This is the equivalent of calling echo
or print effectively, and we're essentially inserting
that dynamically.
So what more remains here?
Well, let me go into Version Three here,
and we'll see a somewhat different--
same exact file layout but notice
that this time we're going to generalize the header and footer
as templates, so what do I mean by that?
What's the one thing that's different here?
What has changed since the last version?
Subtle, but it's arguably just a better cleaner design.
Yeah?
[ Off Mic Comment ]
Yeah, there's just one standard render function;
I didn't special case render header or render footer,
both of which if you recall from helpers dot php,
we're pretty much identical except for their names
and the templates they included.
Why not just parameterize the render function
and take one argument, that's the name of the template,
and a second optional argument that are the key value pairs
that you want to plug in.
So if I now look at helpers dot php notice
that I'm being a little fancier now.
I'm actually checking does the file exist and if so go ahead
and require it; just in case the user accidentally types
in some bogus template name you don't want to throw an error
in the program so we can minimally do them this
favor here.
All right, but can we take this a step further?
In this version here notice the following.
I've just typed ls, and what immediately jumps
out is somewhat different.
So there's two directories, right,
and so this is now a step toward what will eventually be a more
proper framework.
This is kind of sloppy of me to be throwing all
of my content inside of a publically accessible directory
that literally is called public.
And even though unfortunately, a lot of frameworks,
older ones especially, and even some web posts,
Dream Host among them, forces you to put all of your files
in the equivalent of a public directory even
if your files might include database passwords
and user names or other such credentials,
that's not at all good design.
Much better is only put
in the public directory what absolutely has
to be user accessible, and everything else
that you're including like helpers dot php,
there's no reason that that should be web accessible via a
browser with a url.
It might be completely innocuous if the user wants to see maybe
who pairs, but it's just the principle of it,
and god forbid it actually does have a user name or password;
you don't want the user accidentally
or intentionally being able to access it.
So we're not quite at a perfect approach here,
but notice the following now.
In index dot php, notice that I'm still requiring helpers,
but I'm doing it in such a way that I'm sort of organizing all
of the files that will be included
into a subdirectory called conventionally includes,
and then I call render for header and footer as before.
So the only thing I've done is sort
of reorganize my directories to be a little more anal
about the file structure.
But if we now go to this fifth example,
notice here that we now have a trio of folders,
and this is a bit misleading at the moment
because for simplicity for the sake of class,
I've just thrown everything
into John Harvard's Public Directory just
so we can navigate it via a browser, but notice--
ignore this part for just a moment,
the fact that I'm in there.
Notice that I have three subdirectories: public,
templates, and includes.
The idea now is that in a properly configured web server I
would tell Apache that this website has publicly accessible
files here, and nowhere else.
So what file do you think I'm going to see inside
of public if I type ls?
What's at least one file that's probably in there?
[ Off Mic Comment ]
Okay index dot php, and what file is obviously not
in there among others?
Like helpers dot php, header dot php, footer dot php;
all of the fragments, all of the functionality
that doesn't really need to be publicly accessible,
it needs to be usable by the files
that are publicly accessible, but they themselves,
no user needs to see or quire a URL for helpers dot php.
Notice that instead if I go
into includes there's helpers dot php,
and if I go into templates,
there's footer and header dot php.
Frankly, I could have put them in the same directory,
but I'm trying to be even more anal about keeping files
that are just sort of static templates different
from functional files like helpers dot php,
and I'm just adhering to some fairly common conventions
calling the directories includes and templates.
So the only thing that changed then is again the path.
If we go up here notice that I now just have
to include a relative directory,
dot dot slash includes helpers dot php,
or I can be a little more proper and actually do something
like this, php and a lot
of languages have these special symbols
that represent the current file's directory,
so underscore underscore dir underscore underscore represents
whatever directory is of this file,
and so if you just concatenate with the dot operator, that,
that would achieve the same result,
and tends to be a little more robust because you can get
into situations with relative directories were just saying dot
or dot dot can actually bring you to the wrong place,
so this tends to be a little more robust.
All right, so what though remains?
What do you still not like about this?
What could be improved and you commented on it earlier I think
that there's still some issues?
[ Off Mic Comment ]
Right, surely we don't have to start writing like sites
that look like this, right?
This doesn't feel all that much better,
there's still copy paste.
I still have the require line at the top.
I still have render header render footer.
There's a lot of duplication.
Yeah?
[ Off Mic Comment ]
Yeah, exactly, so we've taken a step towards sort of splitting
up the "c" from the "v," so MVC is Model View Controller;
controller is sort of the brains of the application.
Model tends to be the data or some shared functionality,
and view tends to be the aesthetics, the template,
so we have taken a step towards separating the "c" from the "v"
because we now at least have this template's directory,
but even there we essentially have one controller per file.
It doesn't look like there's much logic going on here,
but index dot php is effectively a controller.
When you visit a URL and ending in index dot php,
all of the logic that implements that page is right
in index dot php, and same for lectures dot php.
The same for week zero dot php.
So we've kind of strone our logic all over the place,
and it feels like this isn't going
to scale very well once we have not four but forty pages
if every page starts with me copying an older version
of the file and just tweaking some
of the content inside of it.
So we've only taken a step toward this,
and one of the tools we'll introduce
on Wednesday is a framer called "Laravel"
and this is very popular php framework,
other ones include "Fuelphp."
There's an older one called "Codeigniter."
There's one called "Cake."
There's one called "Symphony."
I mean if you Google php frameworks,
there's an atrocious number of like frameworks
that people that implemented.
Laravel is one of the more up and comers;
it's one of the cleaner ones, and you'll find
that ultimately it helps save you quite a bit
of time even though there is a bit of a learning curve,
but that we will guide you over on Wednesday.
Moreover, we'll introduce what's called an "ORM."
In this case, we'll use something that comes
with this framework called Laravel.
It's called "Eloquent" and this is just a layer of code
that allows you to among other things talk to databases.
And here too, let me steal an example that is either recent
or a throwback for some of you from 50.
If you did take 50, and you did "CS50 Finance,"
you might recall files that you write or rewrote that look
like this, this was login dot php, and at the time,
especially since we didn't spend much time
on php fundamentals early on,
this might itself have been fairly challenging,
and so we did, in fact, try to simplify the design.
We didn't really separate "M" from "V" from "C" all that much
for problems that "Seven CS50 Finance,"
but notice the one thing that should hopefully start
to soon rub you the wrong way, is something like this.
I mean, not only was this log in dot php a controller.
It was also talking directly
to a database specifically using sequel, which isn't going
to scale very well when you start to work with one
or two or three partners.
For instance, if one of the partners is responsible
for creating your database tables and coming
up with your indexes and figuring
out what the key should be, the primary keys, the foreign keys,
and all of that, deciding on the table names and all of that.
Now you the other person in the group needs to know all
of the design decisions he or she has made, and you now need
to hard code those decisions into your file, so now he
or she is pretty much constrained
to never again change those table names.
Never again to change those filed names
without informing you.
Moreover, you can't really easily work on the same file
without colliding with each other if he
or she is constantly changing names,
and you have the old versions and so forth,
so this is just inviting lots and lots of headaches.
Moreover, as we'll see before long,
even though you didn't need
to do particularly sophisticated queries here,
once you start having multiple tables, two tables, three, five,
ten tables in a MySql or generally a relational database,
you have to join those tables often if familiar, and you have
to combine data from one with the other,
and frankly your sequel queries start to get longer, and longer,
and longer, and more complex, and it just starts
to get a lot easier to make mistakes
and a lot harder to get things right.
And so tools like Eloquent and ORM is going
to help us model our data and it's also effectively going
to generate the code that we need to start querying databases
in more sophisticated ways.
So if you've got a primary key over here and a foreign key
over here, all you need to do is teach that ORM,
Object Relation Mapper, what that relationship is
and it will figure out what queries to execute for you.
And only in rare cases do you need
to necessarily write sequel code yourself.
If you really want to fine tune something,
but for the most part, you can just start treating entities
in your databases as true objects and not these flat rows
that you somehow need to reconstruct and de normalize.