MVC

Notes

As software applications, like the kinds of websites we've been working on, become more complex, it can be hard to keep code organized, maintainable, and workable. Just imagine that you were working with up to three people on a web-based final project for an introductory computer science course! ;-) Lacking any kind of structured approach to writing PHP makes it difficult to split up the application into nice, modular components that would make it easier to build in pieces: you'd have to edit code in similar files, and collaboration would be a hassle. Clearly, there's a need for some kind of separation of these pieces, and that's just what MVC is for.

MVC, which stands for ModelViewController, is a design paradigm for creating software applications. Put more simply, it's a way of organizing and thinking about code. In this presentation, we'll discuss MVC in the context of web applications, but do note that MVC can apply to software development in general.

[1] MVC diagram adopted from http://symfony.com/legacy/doc/jobeet/1_2/en/04?orm=Propel

Within the MVC design paradigm, we can divide a web application into three major components: the model, the view, and the controller.

When an HTTP request is sent to a web server, the controller is invoked first. The controller will interpret the user's request (Did they want this file? Did they want this page? Do they want to register for a new account on this website? Do they want to update something?). You'll typically see code that validates user input inside of a controllere.g., checking if a field for an email address actually contains a valid email address.

And so the controller interprets the user's request. In some cases, the user may be submitting a form, or visiting a page on the website, that requires communication with the database. For instance, when you log in to Facebook and go to the News Feed, Facebook's servers know to pull some information out of the database. In the context of MVC, this is an example of a controller communicating with a model, which allows for persistent storage of information. And so, it's reasonable for a controller to talk to a model, usually to get information.

Whether it communicates with a model or not, the controller will typically end up presenting the user who requested a page with some information. This presentation is part of a view. In many MVC frameworkscode packages intended to help software developers build MVC applicationsviews are often associated with one or more templates. We'll see some examples of templates later. In the context of web applications, the view is just some HTML that's dynamically prepared by a web server.

The C$50 Finance assignment involves creating a PHP web application that is structured according to the MVC design paradigm. Let's look at each component of MVC, and discuss how it is reflected in this assignment.

Within the C$50 Finance assignment, a MySQL database serves as the model. You can send queries to this database using the provided PHP function called query.

You can also manipulate the database tables using software installed on the CS50 Appliance called phpMyAdmin.

Controllers for the C$50 Finance consist of server-side PHP codethat is, code executed by the Apache web server installed in the CS50 Appliance.

In the above example, the controller first calls the query function, passing a query string. Here is an example of the controller communicating with the model, the MySQL database discussed earlier. Then, the controller may perform some operations on the datathis is appropriate; you can think of the controller as performing "business logic."

Also, take note of how the controller code above ends - either in a call to the render function or to the apologize function. These functions, provided along with the distribution code for the problem set, allow you to display a view. As the name suggests, apologize can be used to apologize to the user when something went wrong. You'll likely use this function in circumstances where errors occur, and you're unable to continue. Or when a user provides an invalid input, like a mismatching password, or something like that.

render is used to display a view. It accepts up to two arguments: the first, required, is the name of a template to display. In the code above, we are invoking a template called some_template. The second, an optional argument, is an associative array with some data that we aim to pass to the template. This may be slightly unclear now, but let's look at an example of a template: namely some_template, so we can see how these two components connect.

The view component of the C$50 Finance application consists of templates, which are PHP files that display some data to the user.

In the file above, called some_template.php, a loop is used to iterate over the items in an array called $data. This may seem odd at first glance. Where did this variable come from? Recall that in our controller, we invoked this template with the following line of source code:

render("some_template", array("data" => $result));

The render function will take its second argument, which should be an associative array, and create variables for every key in the array, setting the initial value of these variables to be the value corresponding to the key in the array. That is, we now have a variable called $data whose value is $result. Cool! [1]

And so we have a way to pass data and information to a template. Notice the flow of information here: first, it started at the databasethe modelthen it was processed by the controller, and then it was passed to a template. Also, notice that the PHP code inside of the template did little "thinking"it merely printed out the data that was passed to it. This complies with MVC design principlesmost of the "thinking" should be performed by the controller.

[1] render accomplishes this using PHP's extract function

Slides ( / )

study50 slide
study50 slide
study50 slide
study50 slide
study50 slide

Time for Templates

In this exercise, we will add new functionality to the C$50 Finance web application.

Be sure to download the distribution code and set it up on your version of the Appliance, as per the Problem Set 7 spec.

Our goal is to add a page to the website that displays the current time. To accomplish this, we need to create a new controller and a view.

  • Start by creating a new file called time.php inside of the html/ directory. This file will serve as the controller. All of the controllers will reside in this directory.

  • Then, add the following content to this file:

<?php

        require("../includes/config.php");

        $currentTime = strftime("%D %T");

?>

The function call to require in the above source code gives us access to some helpful functionality, including the render function.

Also, note that variable $currentTime stores a string representing the current time.

  • Now, create a file called time_template.php inside of the templates/ directory. Add the following content to this file:

        <h1><?= $time ?></h1>
  • Be sure to set the permissions of these files appropriately, using chmod.

  • Fill in the missing pieces! How can you make the controller you created, time.php, display this template (with the time)?

Try out some pseudocode here!
Notice (8): Undefined index: default_code [APP/View/Elements/problem.ctp, line 38]
Notice (8): Undefined index: default_code [APP/View/Elements/problem.ctp, line 38]
To complete this problem, please download the distribution code.

Videos

study50 video thumbnail

Week 8, Friday