<?php
require("../includes/config.php");
$currentTime = strftime("%D %T");
?>
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 Model—View—Controller, 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 controller—e.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 frameworks—code packages intended to help software developers build MVC applications—views 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 code—that 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 data—this 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 database—the model—then 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 principles—most of the "thinking" should be performed by the controller.
[1] render accomplishes this using PHP's extract function
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)?
Notice (8): Undefined index: default_code [APP/View/Elements/problem.ctp, line 38]Code ContextTry out some pseudocode here!
</div>
<pre contenteditable class='pseudocodeEditor'><?php if ($problemInfo["components"]["default_code"] !== FALSE): ?><?= $problemInfo["components"]["default_code"] ?><?php endif?></pre>
$viewFile = '/srv/www/study.cs50.net/app/View/Elements/problem.ctp' $dataForView = array( 'topics' => array( 'C Basics' => array( (int) 0 => array( [maximum depth reached] ), (int) 1 => array( [maximum depth reached] ), (int) 2 => array( [maximum depth reached] ), (int) 3 => array( [maximum depth reached] ), (int) 4 => array( [maximum depth reached] ), (int) 5 => array( [maximum depth reached] ), (int) 6 => array( [maximum depth reached] ), (int) 7 => array( [maximum depth reached] ), (int) 8 => array( [maximum depth reached] ) ), 'Searching and Sorting' => array( (int) 0 => array( [maximum depth reached] ), (int) 1 => array( [maximum depth reached] ), (int) 2 => array( [maximum depth reached] ), (int) 3 => array( [maximum depth reached] ), (int) 4 => array( [maximum depth reached] ) ), 'Memory Management' => array( (int) 0 => array( [maximum depth reached] ), (int) 1 => array( [maximum depth reached] ) ), 'Data Structures' => array( (int) 0 => array( [maximum depth reached] ), (int) 1 => array( [maximum depth reached] ), (int) 2 => array( [maximum depth reached] ), (int) 3 => array( [maximum depth reached] ), (int) 4 => array( [maximum depth reached] ), (int) 5 => array( [maximum depth reached] ), (int) 6 => array( [maximum depth reached] ) ), 'Data Compression' => array( (int) 0 => array( [maximum depth reached] ) ), 'Web Programming' => array( (int) 0 => array( [maximum depth reached] ), (int) 1 => array( [maximum depth reached] ), (int) 2 => array( [maximum depth reached] ) ) ), 'pageInfo' => array( 'title' => 'MVC', 'path' => 'mvc', 'widgets' => array( (int) 0 => array( [maximum depth reached] ), (int) 1 => array( [maximum depth reached] ), (int) 2 => array( [maximum depth reached] ) ) ), 'problems' => array( (int) 0 => array( 'title' => 'Time for Templates', 'type' => 'distro', 'difficulty' => 'easy', 'language' => 'php', 'components' => array( [maximum depth reached] ), 'src' => 'time_for_templates' ) ) ) $topics = array( 'C Basics' => array( (int) 0 => array( 'title' => 'ASCII', 'path' => 'ascii' ), (int) 1 => array( 'title' => 'Binary', 'path' => 'binary' ), (int) 2 => array( 'title' => 'Command-Line Arguments', 'path' => 'argv' ), (int) 3 => array( 'title' => 'Conditions', 'path' => 'conditions' ), (int) 4 => array( 'title' => 'Functions', 'path' => 'functions' ), (int) 5 => array( 'title' => 'Loops', 'path' => 'loops' ), (int) 6 => array( 'title' => 'Math', 'path' => 'math' ), (int) 7 => array( 'title' => 'Recursion', 'path' => 'recursion' ), (int) 8 => array( 'title' => 'File I/O', 'path' => 'io' ) ), 'Searching and Sorting' => array( (int) 0 => array( 'title' => 'Binary Search', 'path' => 'binary_search' ), (int) 1 => array( 'title' => 'Bubble Sort', 'path' => 'bubble_sort' ), (int) 2 => array( 'title' => 'Insertion Sort', 'path' => 'insertion_sort' ), (int) 3 => array( 'title' => 'Merge Sort', 'path' => 'merge_sort' ), (int) 4 => array( 'title' => 'Selection Sort', 'path' => 'selection_sort' ) ), 'Memory Management' => array( (int) 0 => array( 'title' => 'Dynamic Memory Allocation', 'path' => 'malloc' ), (int) 1 => array( 'title' => 'Pointers', 'path' => 'pointers' ) ), 'Data Structures' => array( (int) 0 => array( 'title' => 'Arrays', 'path' => 'arrays' ), (int) 1 => array( 'title' => 'Hash Tables', 'path' => 'hashtables' ), (int) 2 => array( 'title' => 'Linked Lists', 'path' => 'linked_lists' ), (int) 3 => array( 'title' => 'Queues', 'path' => 'queues' ), (int) 4 => array( 'title' => 'Stacks', 'path' => 'stacks' ), (int) 5 => array( 'title' => 'Trees', 'path' => 'trees' ), (int) 6 => array( 'title' => 'Tries', 'path' => 'tries' ) ), 'Data Compression' => array( (int) 0 => array( 'title' => 'Huffman Coding', 'path' => 'huffman' ) ), 'Web Programming' => array( (int) 0 => array( 'title' => 'HTTP', 'path' => 'http' ), (int) 1 => array( 'title' => 'JavaScript', 'path' => 'javascript' ), (int) 2 => array( 'title' => 'MVC', 'path' => 'mvc' ) ) ) $pageInfo = array( 'title' => 'MVC', 'path' => 'mvc', 'widgets' => array( (int) 0 => array( 'type' => 'Slideshow', 'data' => array( [maximum depth reached] ) ), (int) 1 => array( 'type' => 'Problems', 'data' => array( [maximum depth reached] ) ), (int) 2 => array( 'type' => 'Videos', 'data' => array( [maximum depth reached] ) ) ) ) $problems = array( (int) 0 => array( 'title' => 'Time for Templates', 'type' => 'distro', 'difficulty' => 'easy', 'language' => 'php', 'components' => array( 'problem' => '<div class="paragraph"> <p>In this exercise, we will add new functionality to the C$50 Finance web application.</p> </div> <div class="paragraph"> <p>Be sure to download the distribution code and set it up on your version of the Appliance, as per the Problem Set 7 spec.</p> </div> <div class="paragraph"> <p>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.</p> </div> <div class="ulist"> <ul> <li> <p>Start by creating a new file called <code>time.php</code> inside of the <code>html/</code> directory. This file will serve as the controller. All of the controllers will reside in this directory.</p> </li> <li> <p>Then, add the following content to this file:</p> </li> </ul> </div> <div class="listingblock"> <div class="content"> <pre class="CodeRay"><code class="php language-php"><span class="inline-delimiter"><?php</span> <span class="predefined">require</span>(<span class="string"><span class="delimiter">"</span><span class="content">../includes/config.php</span><span class="delimiter">"</span></span>); <span class="local-variable">$currentTime</span> = <span class="predefined">strftime</span>(<span class="string"><span class="delimiter">"</span><span class="content">%D %T</span><span class="delimiter">"</span></span>); <span class="inline-delimiter">?></span></code></pre> </div> </div> <div class="paragraph"> <p>The function call to <code>require</code> in the above source code gives us access to some helpful functionality, including the <code>render</code> function.</p> </div> <div class="paragraph"> <p>Also, note that variable <code>$currentTime</code> stores a string representing the current time.</p> </div> <div class="ulist"> <ul> <li> <p>Now, create a file called <code>time_template.php</code> inside of the <code>templates/</code> directory. Add the following content to this file:</p> </li> </ul> </div> <div class="listingblock"> <div class="content"> <pre class="CodeRay"><code class="php language-php"> <span class="tag"><h1></span><span class="inline-delimiter"><?</span>= <span class="local-variable">$time</span> <span class="inline-delimiter">?></span><span class="tag"></h1></span></code></pre> </div> </div> <div class="ulist"> <ul> <li> <p>Be sure to set the permissions of these files appropriately, using <code>chmod</code>.</p> </li> <li> <p>Fill in the missing pieces! How can you make the controller you created, <code>time.php</code>, display this template (with the time)?</p> </li> </ul> </div> ' ), 'src' => 'time_for_templates' ) ) $problemInfo = array( 'title' => 'Time for Templates', 'type' => 'distro', 'difficulty' => 'easy', 'language' => 'php', 'components' => array( 'problem' => '<div class="paragraph"> <p>In this exercise, we will add new functionality to the C$50 Finance web application.</p> </div> <div class="paragraph"> <p>Be sure to download the distribution code and set it up on your version of the Appliance, as per the Problem Set 7 spec.</p> </div> <div class="paragraph"> <p>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.</p> </div> <div class="ulist"> <ul> <li> <p>Start by creating a new file called <code>time.php</code> inside of the <code>html/</code> directory. This file will serve as the controller. All of the controllers will reside in this directory.</p> </li> <li> <p>Then, add the following content to this file:</p> </li> </ul> </div> <div class="listingblock"> <div class="content"> <pre class="CodeRay"><code class="php language-php"><span class="inline-delimiter"><?php</span> <span class="predefined">require</span>(<span class="string"><span class="delimiter">"</span><span class="content">../includes/config.php</span><span class="delimiter">"</span></span>); <span class="local-variable">$currentTime</span> = <span class="predefined">strftime</span>(<span class="string"><span class="delimiter">"</span><span class="content">%D %T</span><span class="delimiter">"</span></span>); <span class="inline-delimiter">?></span></code></pre> </div> </div> <div class="paragraph"> <p>The function call to <code>require</code> in the above source code gives us access to some helpful functionality, including the <code>render</code> function.</p> </div> <div class="paragraph"> <p>Also, note that variable <code>$currentTime</code> stores a string representing the current time.</p> </div> <div class="ulist"> <ul> <li> <p>Now, create a file called <code>time_template.php</code> inside of the <code>templates/</code> directory. Add the following content to this file:</p> </li> </ul> </div> <div class="listingblock"> <div class="content"> <pre class="CodeRay"><code class="php language-php"> <span class="tag"><h1></span><span class="inline-delimiter"><?</span>= <span class="local-variable">$time</span> <span class="inline-delimiter">?></span><span class="tag"></h1></span></code></pre> </div> </div> <div class="ulist"> <ul> <li> <p>Be sure to set the permissions of these files appropriately, using <code>chmod</code>.</p> </li> <li> <p>Fill in the missing pieces! How can you make the controller you created, <code>time.php</code>, display this template (with the time)?</p> </li> </ul> </div> ' ), 'src' => 'time_for_templates' ) $k = (int) 0include - APP/View/Elements/problem.ctp, line 38 View::_evaluate() - CORE/Cake/View/View.php, line 923 View::_render() - CORE/Cake/View/View.php, line 886 View::element() - CORE/Cake/View/View.php, line 422 include - APP/View/Pages/view.ctp, line 58 View::_evaluate() - CORE/Cake/View/View.php, line 923 View::_render() - CORE/Cake/View/View.php, line 886 View::render() - CORE/Cake/View/View.php, line 476 Controller::render() - CORE/Cake/Controller/Controller.php, line 956 Dispatcher::_invoke() - CORE/Cake/Routing/Dispatcher.php, line 193 Dispatcher::dispatch() - CORE/Cake/Routing/Dispatcher.php, line 161 [main] - APP/webroot/index.php, line 92Notice (8): Undefined index: default_code [APP/View/Elements/problem.ctp, line 38]Code ContextTry out some pseudocode here!
</div>
<pre contenteditable class='pseudocodeEditor'><?php if ($problemInfo["components"]["default_code"] !== FALSE): ?><?= $problemInfo["components"]["default_code"] ?><?php endif?></pre>
$viewFile = '/srv/www/study.cs50.net/app/View/Elements/problem.ctp' $dataForView = array( 'topics' => array( 'C Basics' => array( (int) 0 => array( [maximum depth reached] ), (int) 1 => array( [maximum depth reached] ), (int) 2 => array( [maximum depth reached] ), (int) 3 => array( [maximum depth reached] ), (int) 4 => array( [maximum depth reached] ), (int) 5 => array( [maximum depth reached] ), (int) 6 => array( [maximum depth reached] ), (int) 7 => array( [maximum depth reached] ), (int) 8 => array( [maximum depth reached] ) ), 'Searching and Sorting' => array( (int) 0 => array( [maximum depth reached] ), (int) 1 => array( [maximum depth reached] ), (int) 2 => array( [maximum depth reached] ), (int) 3 => array( [maximum depth reached] ), (int) 4 => array( [maximum depth reached] ) ), 'Memory Management' => array( (int) 0 => array( [maximum depth reached] ), (int) 1 => array( [maximum depth reached] ) ), 'Data Structures' => array( (int) 0 => array( [maximum depth reached] ), (int) 1 => array( [maximum depth reached] ), (int) 2 => array( [maximum depth reached] ), (int) 3 => array( [maximum depth reached] ), (int) 4 => array( [maximum depth reached] ), (int) 5 => array( [maximum depth reached] ), (int) 6 => array( [maximum depth reached] ) ), 'Data Compression' => array( (int) 0 => array( [maximum depth reached] ) ), 'Web Programming' => array( (int) 0 => array( [maximum depth reached] ), (int) 1 => array( [maximum depth reached] ), (int) 2 => array( [maximum depth reached] ) ) ), 'pageInfo' => array( 'title' => 'MVC', 'path' => 'mvc', 'widgets' => array( (int) 0 => array( [maximum depth reached] ), (int) 1 => array( [maximum depth reached] ), (int) 2 => array( [maximum depth reached] ) ) ), 'problems' => array( (int) 0 => array( 'title' => 'Time for Templates', 'type' => 'distro', 'difficulty' => 'easy', 'language' => 'php', 'components' => array( [maximum depth reached] ), 'src' => 'time_for_templates' ) ) ) $topics = array( 'C Basics' => array( (int) 0 => array( 'title' => 'ASCII', 'path' => 'ascii' ), (int) 1 => array( 'title' => 'Binary', 'path' => 'binary' ), (int) 2 => array( 'title' => 'Command-Line Arguments', 'path' => 'argv' ), (int) 3 => array( 'title' => 'Conditions', 'path' => 'conditions' ), (int) 4 => array( 'title' => 'Functions', 'path' => 'functions' ), (int) 5 => array( 'title' => 'Loops', 'path' => 'loops' ), (int) 6 => array( 'title' => 'Math', 'path' => 'math' ), (int) 7 => array( 'title' => 'Recursion', 'path' => 'recursion' ), (int) 8 => array( 'title' => 'File I/O', 'path' => 'io' ) ), 'Searching and Sorting' => array( (int) 0 => array( 'title' => 'Binary Search', 'path' => 'binary_search' ), (int) 1 => array( 'title' => 'Bubble Sort', 'path' => 'bubble_sort' ), (int) 2 => array( 'title' => 'Insertion Sort', 'path' => 'insertion_sort' ), (int) 3 => array( 'title' => 'Merge Sort', 'path' => 'merge_sort' ), (int) 4 => array( 'title' => 'Selection Sort', 'path' => 'selection_sort' ) ), 'Memory Management' => array( (int) 0 => array( 'title' => 'Dynamic Memory Allocation', 'path' => 'malloc' ), (int) 1 => array( 'title' => 'Pointers', 'path' => 'pointers' ) ), 'Data Structures' => array( (int) 0 => array( 'title' => 'Arrays', 'path' => 'arrays' ), (int) 1 => array( 'title' => 'Hash Tables', 'path' => 'hashtables' ), (int) 2 => array( 'title' => 'Linked Lists', 'path' => 'linked_lists' ), (int) 3 => array( 'title' => 'Queues', 'path' => 'queues' ), (int) 4 => array( 'title' => 'Stacks', 'path' => 'stacks' ), (int) 5 => array( 'title' => 'Trees', 'path' => 'trees' ), (int) 6 => array( 'title' => 'Tries', 'path' => 'tries' ) ), 'Data Compression' => array( (int) 0 => array( 'title' => 'Huffman Coding', 'path' => 'huffman' ) ), 'Web Programming' => array( (int) 0 => array( 'title' => 'HTTP', 'path' => 'http' ), (int) 1 => array( 'title' => 'JavaScript', 'path' => 'javascript' ), (int) 2 => array( 'title' => 'MVC', 'path' => 'mvc' ) ) ) $pageInfo = array( 'title' => 'MVC', 'path' => 'mvc', 'widgets' => array( (int) 0 => array( 'type' => 'Slideshow', 'data' => array( [maximum depth reached] ) ), (int) 1 => array( 'type' => 'Problems', 'data' => array( [maximum depth reached] ) ), (int) 2 => array( 'type' => 'Videos', 'data' => array( [maximum depth reached] ) ) ) ) $problems = array( (int) 0 => array( 'title' => 'Time for Templates', 'type' => 'distro', 'difficulty' => 'easy', 'language' => 'php', 'components' => array( 'problem' => '<div class="paragraph"> <p>In this exercise, we will add new functionality to the C$50 Finance web application.</p> </div> <div class="paragraph"> <p>Be sure to download the distribution code and set it up on your version of the Appliance, as per the Problem Set 7 spec.</p> </div> <div class="paragraph"> <p>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.</p> </div> <div class="ulist"> <ul> <li> <p>Start by creating a new file called <code>time.php</code> inside of the <code>html/</code> directory. This file will serve as the controller. All of the controllers will reside in this directory.</p> </li> <li> <p>Then, add the following content to this file:</p> </li> </ul> </div> <div class="listingblock"> <div class="content"> <pre class="CodeRay"><code class="php language-php"><span class="inline-delimiter"><?php</span> <span class="predefined">require</span>(<span class="string"><span class="delimiter">"</span><span class="content">../includes/config.php</span><span class="delimiter">"</span></span>); <span class="local-variable">$currentTime</span> = <span class="predefined">strftime</span>(<span class="string"><span class="delimiter">"</span><span class="content">%D %T</span><span class="delimiter">"</span></span>); <span class="inline-delimiter">?></span></code></pre> </div> </div> <div class="paragraph"> <p>The function call to <code>require</code> in the above source code gives us access to some helpful functionality, including the <code>render</code> function.</p> </div> <div class="paragraph"> <p>Also, note that variable <code>$currentTime</code> stores a string representing the current time.</p> </div> <div class="ulist"> <ul> <li> <p>Now, create a file called <code>time_template.php</code> inside of the <code>templates/</code> directory. Add the following content to this file:</p> </li> </ul> </div> <div class="listingblock"> <div class="content"> <pre class="CodeRay"><code class="php language-php"> <span class="tag"><h1></span><span class="inline-delimiter"><?</span>= <span class="local-variable">$time</span> <span class="inline-delimiter">?></span><span class="tag"></h1></span></code></pre> </div> </div> <div class="ulist"> <ul> <li> <p>Be sure to set the permissions of these files appropriately, using <code>chmod</code>.</p> </li> <li> <p>Fill in the missing pieces! How can you make the controller you created, <code>time.php</code>, display this template (with the time)?</p> </li> </ul> </div> ' ), 'src' => 'time_for_templates' ) ) $problemInfo = array( 'title' => 'Time for Templates', 'type' => 'distro', 'difficulty' => 'easy', 'language' => 'php', 'components' => array( 'problem' => '<div class="paragraph"> <p>In this exercise, we will add new functionality to the C$50 Finance web application.</p> </div> <div class="paragraph"> <p>Be sure to download the distribution code and set it up on your version of the Appliance, as per the Problem Set 7 spec.</p> </div> <div class="paragraph"> <p>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.</p> </div> <div class="ulist"> <ul> <li> <p>Start by creating a new file called <code>time.php</code> inside of the <code>html/</code> directory. This file will serve as the controller. All of the controllers will reside in this directory.</p> </li> <li> <p>Then, add the following content to this file:</p> </li> </ul> </div> <div class="listingblock"> <div class="content"> <pre class="CodeRay"><code class="php language-php"><span class="inline-delimiter"><?php</span> <span class="predefined">require</span>(<span class="string"><span class="delimiter">"</span><span class="content">../includes/config.php</span><span class="delimiter">"</span></span>); <span class="local-variable">$currentTime</span> = <span class="predefined">strftime</span>(<span class="string"><span class="delimiter">"</span><span class="content">%D %T</span><span class="delimiter">"</span></span>); <span class="inline-delimiter">?></span></code></pre> </div> </div> <div class="paragraph"> <p>The function call to <code>require</code> in the above source code gives us access to some helpful functionality, including the <code>render</code> function.</p> </div> <div class="paragraph"> <p>Also, note that variable <code>$currentTime</code> stores a string representing the current time.</p> </div> <div class="ulist"> <ul> <li> <p>Now, create a file called <code>time_template.php</code> inside of the <code>templates/</code> directory. Add the following content to this file:</p> </li> </ul> </div> <div class="listingblock"> <div class="content"> <pre class="CodeRay"><code class="php language-php"> <span class="tag"><h1></span><span class="inline-delimiter"><?</span>= <span class="local-variable">$time</span> <span class="inline-delimiter">?></span><span class="tag"></h1></span></code></pre> </div> </div> <div class="ulist"> <ul> <li> <p>Be sure to set the permissions of these files appropriately, using <code>chmod</code>.</p> </li> <li> <p>Fill in the missing pieces! How can you make the controller you created, <code>time.php</code>, display this template (with the time)?</p> </li> </ul> </div> ' ), 'src' => 'time_for_templates' ) $k = (int) 0include - APP/View/Elements/problem.ctp, line 38 View::_evaluate() - CORE/Cake/View/View.php, line 923 View::_render() - CORE/Cake/View/View.php, line 886 View::element() - CORE/Cake/View/View.php, line 422 include - APP/View/Pages/view.ctp, line 58 View::_evaluate() - CORE/Cake/View/View.php, line 923 View::_render() - CORE/Cake/View/View.php, line 886 View::render() - CORE/Cake/View/View.php, line 476 Controller::render() - CORE/Cake/Controller/Controller.php, line 956 Dispatcher::_invoke() - CORE/Cake/Routing/Dispatcher.php, line 193 Dispatcher::dispatch() - CORE/Cake/Routing/Dispatcher.php, line 161 [main] - APP/webroot/index.php, line 92