So create the new application directory temp just under the same document root where you just installed Smarty.. Inside the temp directory, create another one called smarty to house the
Trang 1Smarty.class.php
Smarty_Compiler.class.php
That gets Smarty installed, but you also need to create four subdirectories for every
application that uses it So create the new application directory temp just under the
same document root where you just installed Smarty This will hold the files for a temporary application that we’ll write to test Smarty
Inside the temp directory, create another one called smarty to house the folders
con-taining the template files Finally, create the following subdirectories within the new
smarty directory: cache, config, templates, and templates_c Your directory structure is
now:
temp
smarty
cache
config
templates
templates_c
Creating Scripts
You are now ready to create some Smarty scripts Type in the code in Example 12-1
and save it as smarty.php.
Example 12-1 The smarty.php program
<?php // smarty.php
$path = $_SERVER['DOCUMENT_ROOT'];
require "$path/Smarty/Smarty.class.php";
$smarty = new Smarty();
$smarty->template_dir = "$path/temp/smarty/templates";
$smarty->compile_dir = "$path/temp/smarty/templates_c";
$smarty->cache_dir = "$path/temp/smarty/cache";
$smarty->config_dir = "$path/temp/smarty/configs";
$smarty->assign('title', 'Test Web Page');
$smarty->display("$path/temp/index.tpl");
?>
This program tells Smarty where it can find the Smarty.class.php file, and where your Smarty templates are located Because we will be using both php and tpl template files
in this chapter, I have included everything you need in each file
Example 12-1 looks up the document root and sets the variable $path to that value It then uses $path as a prefix for fetching the Smarty class files and the template files from
the temp folder This saves you the maintenance hassle of hard-wiring full path names
into the code
Trang 2Note the penultimate $smarty->assign command This creates a Smarty variable called title and assigns it the string value “Test Web Page” You’ll see why shortly
Once you have typed the program in, save it using the filename smarty.php into the temp directory you created earlier.
Creating Templates
Now you need to write a simple Smarty template file to test whether everything is working, so type in Example 12-2 and save it in a file named index.tpl in the temp/ smarty/templates directory you created earlier.
Example 12-2 The index.tpl template file
<html>
<head>
<title>{$title}</title>
</head>
<body>
This is a Smarty Test
</body>
</html>
As you can see, this is simply an HTML file with a tpl file extension But note the use
of the Smarty variable {$title} on the third line This is the same variable that was defined in Example 12-1 Smarty will substitute the value of the variable instead of the text in Example 12-2, because of the surrounding curly braces {} (see Figure 12-1)
Figure 12-1 The output from index.tpl in Example 12-2
A Practical Example
Let’s take the program sqltest.php from Example 10-8 in Chapter 10 and rewrite it to use Smarty This will be a two-part process: one part for the program code and one for the Smarty presentation layer Example 12-3 is the revised program Once you have
typed it in, save it into the temp directory that you created earlier using the filename smartytest.php.
Trang 3Example 12-3 The sqltest.php program rewritten for Smarty as smartytest.php
<?php // smartytest.php
$path = $_SERVER['DOCUMENT_ROOT'];
require "$path/Smarty/Smarty.class.php";
$smarty = new Smarty();
$smarty->template_dir = "$path/temp/smarty/templates";
$smarty->compile_dir = "$path/temp/smarty/templates_c";
$smarty->cache_dir = "$path/temp/smarty/cache";
$smarty->config_dir = "$path/temp/smarty/configs";
require_once("$path/temp/login.php");
$db_server = mysql_connect($db_hostname, $db_username, $db_password);
if (!$db_server) die("Unable to connect to MySQL: " mysql_error());
mysql_select_db($db_database)
or die("Unable to select database: " mysql_error());
if (isset($_POST['author']) &&
isset($_POST['title']) &&
isset($_POST['category']) &&
isset($_POST['year']) &&
isset($_POST['isbn']))
{
$author = get_post('author');
$title = get_post('title');
$category = get_post('category');
$year = get_post('year');
$isbn = get_post('isbn');
if (isset($_POST['delete']) && $isbn != "")
{
$query = "DELETE FROM classics WHERE isbn='$isbn'";
if (!mysql_query($query))
{
echo "DELETE failed: $query<br>"
mysql_error() "<p>";
}
}
else
{
$query = "INSERT INTO classics VALUES"
"('$author', '$title', '$category', '$year', '$isbn')";
if (!mysql_query($query))
{
echo "INSERT failed: $query<br>"
mysql_error() "<p>";
}
}
}
$query = "SELECT * FROM classics";
Trang 4$result = mysql_query($query);
if (!$result) die ("Database access failed: " mysql_error());
$rows = mysql_num_rows($result);
for ($j = 0 ; $j < $rows ; ++$j)
{
$results[] = mysql_fetch_array($result);
}
mysql_close($db_server);
$smarty->assign('results', $results);
$smarty->display("$path/temp/smartytest.tpl");
function get_post($var)
{
return mysql_real_escape_string($_POST[$var]);
}
?>
There are a couple of things that you must have done to ensure this program will work:
• You must have worked through the examples in Chapter 8 and have the table
classics ready-populated in the publications database (or another database you may
have used)
• You must have copied the file login.php (created in Chapter 10) to the temp folder
you created earlier, or Example 12-3 will be unable to access MySQL
The program starts off by loading in both the Smarty class and login.php files from their correct places Then it is followed by the program code from the old sqltest.php file,
without the HTML output that it used to have In place of the HTML, we’ll use the presentation layer template that I’ll show next
The main thing remaining to note is the replacement of the mysql_fetch_row function with the new mysql_fetch_array function, just before the call to mysql_close The rea-son for this is to fetch an entire row as an associative array
The function mysql_fetch_array returns a row from the database with the value in each column as an element of the array, and the column name as the array element name The
$results object is an array of arrays Each execution of $results[] = mysql_fetch_array($result); adds another array of results to the $results array This makes it easy to pass a lot of data directly to the Smarty template How easy? Just
a single line is used:
$smarty->assign('results', $results);
This passes an entire array of arrays using the name results
Trang 5The following line in Example 12-3 displays the Smarty template, then program exe-cution ends So now let’s look at the template, which is in Example 12-4 Type it in
and save it as smartytest.tpl in the temp/smarty/templates folder you created earlier.
Example 12-4 The smartytest.tpl file
<html><head>
<title>Smarty Test</title>
</head><body>
<form action="smartytest.php" method="post"><pre>
Author <input type="text" name="author">
Title <input type="text" name="title">
Category <input type="text" name="category">
Year <input type="text" name="year">
ISBN <input type="text" name="isbn">
<input type="submit" value="ADD RECORD">
</pre></form>
{section name=row loop=$results}
<form action="smartytest.php" method="post">
<input type="hidden" name="delete" value="yes">
<input type="hidden" name="isbn" value="{$results[row].isbn}">
<pre>
Author {$results[row].author}
Title {$results[row].title}
Category {$results[row].category}
Year {$results[row].year}
ISBN {$results[row].isbn}
<input type="submit" value="DELETE RECORD"></form>
</pre>
{/section}
</body></html>
In Figure 12-2, you can see the result of using this template file from the
smartytest.php program The first half of the file simply creates the form used to add
more records to the MySQL database—the interesting stuff begins at the {section opening tag A {section} tag is used for looping over arrays of data Each time through the loop in this example, the Smarty variable row is assigned a value representing the iteration of the loop, starting from 0
In the same {section} tag, the loop keyword indicates the array that must be processed
In this case, it is the $results array we passed to the template from the previous pro-gram Given these parameters, it is possible to pull any data wanted from the result rows that were returned by MySQL
For each row, any element can be accessed by its column name For example, to output
the current row’s year field, use {$results[row].year}, where row refers to the current iteration of the loop, or the current row being processed, and .year tells Smarty which column to reference It can do this because we passed an associative array from
Trang 6smartytest.php (now you see why the program was changed from using mysql_fetch_row to mysql_fetch_array)
The loop ends with a closing {/section} tag that will cause the loop to reiterate if there are any more rows to process Otherwise, the HTML below it is displayed
As you can see, this leaves a tremendous amount of control over layout and design with whomever edits the template They can place any items of data in any positions and in any order But at no time do they have any access to your program code, and there is nothing they can do to inject bugs into your program or corrupt the MySQL database
And as for you the programmer? If you’re handing over the task of layout
to a web designer, you’ll never have to worry what the output is going
to look like All you need do is give them a very simple Smarty template
showing all the data you are passing to it, and the form input your
pro-gram will accept from it It’s up to them to then knock it all together
into an award-winning design Think of the freedom that gives you to
write fast and effective code, without the dilemma of how to present its
output.
Figure 12-2 The result of combining smartytest.php and smartytest.tpl
Trang 7You have now seen how to refer to both string and numeric variables, as well as arrays, within a Smarty template If you think templating will be useful in your projects, you can learn what else it can do for you at http://www.smarty.net/crashcourse.php; the full documentation is available at http://www.smarty.net/manual/en/
In the next chapter, we’ll look at a range of practical PHP functions and techniques that you’ll need to create efficient programs
Test Your Knowledge: Questions
Question 12-1
Name three benefits of using a templating system such as Smarty
Question 12-2
How does a PHP program pass a variable to a Smarty template?
Question 12-3
How does a Smarty template access a variable that has been passed to it?
Question 12-4
What Smarty programming tag is used to iterate through an array?
Question 12-5
How do you enable Smarty templating in a PHP program?
See the section “Chapter 12 Answers” on page 445 in Appendix A for the answers to these questions
Trang 9CHAPTER 13
Cookies, Sessions, and Authentication
As your web projects grow larger and more complicated, you will find an increasing need to keep track of your users Even if you aren’t offering logins and passwords, you will still often find a need to store details about a user’s current session and possibly also recognize them when they return to your site
Several technologies support this kind of interaction, ranging from simple browser cookies to session handling and HTTP authentication Between them, they offer the opportunity for you to configure your site to your users’ preferences and ensure a smooth and enjoyable transition through it
Using Cookies in PHP
A cookie is an item of data that a web server saves to your computer’s hard disk via a web browser It can contain almost any alphanumeric information (as long as it’s under
4 KB) and can be retrieved from your computer and returned to the server Common uses include session tracking, maintaining data across multiple visits, holding shopping cart contents, storing login details, and more
Because of their privacy implications, cookies can be read only from the issuing domain
In other words, if a cookie is issued by, for example, oreilly.com, it can be retrieved only
by a web server using that domain This prevents other websites from gaining access
to details to which they are not authorized
Due to the way the Internet works, multiple elements on a web page can be embedded from multiple domains, each of which can issue its own cookies When this happens, they are referred to as third-party cookies Most commonly, these are created by ad-vertising companies in order to track users across multiple websites
Because of this, most browsers allow users to turn cookies off either for the current server’s domain, third-party servers, or both Fortunately, most people who disable cookies do so only for third-party websites
Trang 10Cookies are exchanged during the transfer of headers, before the actual HTML of a web page is sent, and it is impossible to send a cookie once any HTML has been transferred Therefore careful planning of cookie usage is important Figure 13-1 illus-trates a typical request and response dialog between a web browser and web server passing cookies
This exchange shows a browser receiving two pages:
1 The browser issues a request to retrieve the main page, index.html, at the website http://www.webserver.com The first header specifies the file and the second header
specifies the server
2 When the web server at webserver.com receives this pair of headers, it returns some
of its own The second header defines the type of content to be sent (text/html)
and the third one sends a cookie of the name name and with the value value Only
then are the contents of the web page transferred
3 Once the browser has received the cookie, it will then return it with every future request made to the issuing server until the cookie expires or is deleted So, when
the browser requests the new page /news.html, it also returns the cookie name with the value value.
4 Because the cookie has already been set, when the server receives the request to
send /news.html, it does not have to resend the cookie, but just returns the
reques-ted page
Figure 13-1 A browser/server request/response dialog with cookies