Posted: October 31st, 2009 | Author: amos | Filed under: assignments, php | Tags: arrays, class 7, templates | No Comments »
Your in-class assignment today is to update your e-commerce pages from the previous class to be more “dynamic” and “templatized”.
Templatize the common sections of all pages in the entire site
Use separate PHP include files for the top ad banner, global navigation, breadcrumbs, skyscraper ad, and footer. On a real site, these sections would be the more-or-less the same on all pages, so you would want to have them stored in reusable files. These files will be included into the main XHTML file for each page using the include() function of PHP. Feel free to check out the include examples that are up on the server.
Note: As a convention in this class, whenever you create a file that has a snippet of XHTML that is included into another page but never displayed directly on its own, I would like you to give it a name prefixed with the “_” character. For example, the include files used in this assignment could be called:
- _header.php
- _breadcrumbs.php
- _ad_banner.php
- _ad_skyscraper.php
- _footer.php
Templatizing these parts of the page will allow you to reuse those sections on multiple pages on your site, if you ever build it out to be more than one page, without having to rewrite the code for each. Naming the files with this convention will make it obvious when looking at a list of your own files which ones are main XHTML pages and which ones are meant to be include files.
Templatize the products
Once you have finished that, it’s time to start templatizing the actual products that are displayed on the page as well. This would, in theory, allow you to use the same page template for multiple categories of products.
We will do this in a different way than how we templatized the repeating sections of the page. We will be using multidimensional arrays this time. This exercise will be useful as a preparation for when we start to store data in databases.
Eventually, we will want the data for the products to be pulled from a database. But for now, we’re just going to store data in an array as an intermediary step to that goal.
To templatize the products, create a PHP multidimensional array that contains all of your product data. And use a PHP foreach loop to loop through that array and display the product data for each product on your page, rather than having it all hard-coded in the XHTML.
Do the tutorials, understand the examples
You are going to have to go through all the PHP tutorials on the Tizag site and my introduction to arrays in order to get a grasp of arrays and multidimensional arrays in particular.
Here is an example of how to get starting using a multidimensional array for this assignment. I did not show how to use the foreach loop here, so you will have to investigate that, based on the example of looping through an array using the foreach command shown here.
Be sure to keep a backup of the work you did on the e-commerce page in previous classes – do not overwrite it, just make a copy of it.
Links to helpful documentation
Posted: October 31st, 2009 | Author: amos | Filed under: php | Tags: class 7 | No Comments »
Today we enter the realm of server-side technologies. PHP is the server side scripting language that we will be focusing on, but many of the high-level concepts we will be exploring with PHP could just as easily apply to other server-side languages like ASP.NET, Ruby, Python, Java Server Pages, and others.
What is PHP used for?
You may wonder why we even need server-side languages, given the we have seen how the vast majority of web pages are created with a combination of XHTML, CSS, and Javascript. Use Firefox to View -> Page Source on any web page and you will probably see XHTML, CSS, and Javascript code, but absolutely no PHP.
Web developers use XHTML, CSS, and Javascript to control how content shows up in the web browser and how the user interacts with that content. That’s the sole purpose of client-side technologies. Server-side technologies, like PHP, are used to control how that content is assembled and managed on the server before it has even been sent to the browser. Thus, PHP is used to dictate what is often referred to as the “business logic” of a web site.
There are three main uses of PHP:
- web page templating
- storing and retrieving content
- tracking user sessions
These three uses are not mutually-exclusive. For example, templating and tracking users depends upon the ability of PHP to store and retrieve content.
Web page templating
Most web sites have elements of the page that are repeated on each page. Very commonly, global navigation or other important navigation elements are repeated on all pages of a site. For example, Google uses the same global navigation links across many of its sub-sites. Notice that the global navigation remains mostly the same from page-to-page, with slight changes:

Global navigation of Google home page

Global navigation of Google home page with logged-in user

Global navigation of Google Images with logged-in user

Global navigation of Google News with logged-in user
It is very unlikely that Google engineers have hand-coded each of the pages on the Google site individually to have the same XHTML and CSS code for this top section. If this were the case, and Google decided to make a slight change to the layout of this top navigation section, the engineers would have to go through the code of each one of the pages of all these Google sub-sites, and change the XHTML accordingly. This would be a very inefficient and expensive way of maintaining a site.
It is much more likely that the engineers have coded this top section once, and are reusing that same code on each of the pages, with slight variations. If they then wanted to make a change to this top section across the site, they would change that one bit of code, and the rest of the site would update automatically. This would be referred to as being a template.
Take another look at the websites you frequently visit, and you will probably see that there are many sections of content that are repeated on each page.
Storing and retrieving content
When you visit many sites, you will see that the content is updated regularly but the design often does not change. For example, news sites, e-commerce stores, and blogs all have regularly udpated content (news, products, and blog posts, respectively), while maintaining a consistent design.
Every time a new product is added to a store, the web developers do not usually have to hand-code the new product information. Rather, they build a site that allows an administrator to enter the details of a new product into a form, and when they click submit, that information is stored in a database. And each time a consumer visits the e-commerce site, the server-side code retrieves the latest list of products from the database and fits them into a web template.
As an example, consider the products on Amazon.com. The listings of Sheets and the listings of Comforters look identical in layout and design, however the products that are listed in those two sections are different. This is because the data is being pulled from two different data sets in a database – one for sheets, and one for comforters, but the data in each case is being fit into the same template.

Amazon.com Sheets

Amazon.com Comforters
Thus, the storage and retrieval of data is critical for any dynamic web site. And this use of server-side scripting generally goes hand-in-hand with the templating of web pages. In this case, the template would control the general layout and design of the products section of the site.
Data can be stored and retrieved to/from a variety of different places
- databases, which store data in a way that is conceptually similar to spreadsheets
- files, such as text or image files
- web services, which are a mechanism that allows one server to store and retrieve data from another server
- cookies, which are small bits of information that a server can store temporarily on the client computer
PHP can be used to handle the details of using each of these storage mechanisms.
Tracking user sessions
It is often desirable for a web site to be able to track visitors. For example, a user who logs in to their webmail account expects to see their own mail and not someone else’s. Thus, in order for the webmail web server to properly determine which user is currently using the site, it must track each visitor to the site in some way in order to differentiate between multiple users visiting the site at the same time.
Sometimes you want to track users even when they haven’t logged into your site. For example, if you were giving a tutorial on your site, you may want to know how far each user has gotten in the tutorial, even without requiring them to log in.
Tracking users usually involves using cookies at the very least. Often, it will also involve the other sorts of data storage as well.
Posted: July 22nd, 2009 | Author: amos | Filed under: php, server | Tags: class 8 | No Comments »
Some sites allow users to upload files to the server. Most often, this is the case for sites that allow users to upload images. But the same technique is used regardless of the type of file. Uploading files of any type, be they images, audio files, video files, text files, or any other type, is a singular process.
This example shows how to allow users to upload files to the server. As with any site, it all starts with the XHTML. Click here to see this example code in action.
An XHTML page with a form
When uploading files to the server, it is absolutely necessary to give the <form> tag an extra attribute: enctype=”multipart/form-data”. This tells the server that it should expect to receive not only text in the form data, but also possibly a file as well. Omitting this extra attribute is a common mistake.
Here is an example XHTML page with a file upload form on it. We’ll call it “index.html“. The especially relevant bits for this example are the <form> tag, and the <input type=”file”> tag:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>File Upload Example</title>
<link rel="stylesheet" type="text/css" href="styles/main.css" />
</head>
<body>
<div id="container">
<h1>File Upload Example</h1>
<p>Please upload an image:</p>
<form action="process_file.php" method="POST" enctype="multipart/form-data">
<input type="file" name="uploadfile">
<br /><br />
<input type="submit" value="Upload!">
</form>
</div><!-- end container -->
</body>
</html>
When the user clicks the submit button, the data entered into the form is sent along with an HTTP POST request to the server for the script, “process_file.php”. This we surmise from the “method” and “action” attributes of the <form> tag.
A PHP script to process the uploaded file
The following code is from “process_file.php“, which is the PHP script that receives the data passed along with the HTTP POST request, and decides what to do with it.
<?php
require_once("Uploader.class.php");
//create a new instance of the Uploader class
//the constructor function for the Uploader class takes three parameters: the "name" attribute of the <input type="file" name="..."> field, the subdirectory where you want to store the files, and the maximum file size allowed
$uploader = new Uploader("uploadfile", "files", "10M");
//try to do the upload
if ($uploader->upload()) {
//it worked... so get the new location of the file from the $uploader->getPermanentPath() function
$path = $uploader->getPermanentPath();
//redirect to success page, and pass the new path along
header("Location: success.php?path=" . urlencode($path));
}
else {
//it didnt work! so get the new error message from the $uploader->getError() function
$error = $uploader->getError();
//redirect to failure page, and pass the error message along
header("Location: failure.php?error=" . urlencode($error));
}
?>
Let’s analyze this file. The first thing we do is require the inclusion of another file, named “Uploader.class.php”. This file is an object-oriented bit of PHP code that I have written. This Uploader class file contains the code that does the dirty work of file uploading.
The nice thing about object oriented code is that it is built to be taken for granted (click here if you’re interested in a brief intro to object-oriented concepts.) This is one of the core philosophies of object-oriented coding: different processes should run independently of one another, and the internal workings of each process should not matter to the functioning of the other processes. This is known as “encapsulation”. So in this case, I will not explain how this class works. The code is well commented if you want to look for yourselves. I will just describe how it should be used.
Once we have included the Uploader class file, we create an Uploader object. To do so requires passing three pieces of data to the Uploader “constructor function” (read here for a brief intro to how to do object-oriented programming in PHP)
$uploader = new Uploader("uploadfile", "files", "10M");
- The first parameter is the value we gave the “name” attribute of the <input type=”file” name=”…” /> tag in the XHTML form, in this case it is “uploadfile”.
- The second parameter is the subdirectory on the server where we want to store any uploaded files… you’ll see on the server that we have set up a “files” subdirectory in this project folder. (Note: This folder must allow web browsers to write data to it. You can use a file-transfer program such as WinSCP or Cyberduck to make sure the permissions for this folder allow “Others” to “Write” to it. Usually this can be done by right-clicking on the folder in WinSCP, or Control-clicking on the folder in CyberDuck, and selecting the “Properties” or “Info” menu in WinSCP and CyberDuck respectively)

Control-click menu in Cyberduck

Info menu in CyberDuck - make sure "Others" can "Write"
- The last parameter is an option maximum file size that you want to allow users to upload, in this case 10M.
Now that the object is set up, we try to do the upload, and we test to see if it worked or not.
if ($uploader->upload()) {
//... it worked ...
}
else {
//... it failed ...
}
If the upload was successful, we redirect the browser to a “success.php” confirmation page. We also pass along the path of the newly uploaded file on the server to the success.php script.
If the upoad failed, we redirect the browser to a “failure.php” page that explains that an error occurred, and we pass along an error message as part of the request for that failure.php script.
The success confirmation page
The success.php confirmation page simply shows a user-friendly message indicating that the upload was successful. The PHP script on this page retrieves the data that was passed along with the HTTP GET request for the page. This data is the path of the newly uploaded image file on the server. The script on this page uses that path as the “src” attribute of an <img> on the page, which makes the uploaded image appear on the page.
<?php echo "<?" ?>xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Success! File Uploaded</title>
<link rel="stylesheet" type="text/css" href="styles/main.css" />
</head>
<body>
<div id="container">
<h1>Success! File Uploaded</h1>
<p>Thanks. Your image has been successfully uploaded to <?php echo $_REQUEST['path'] ?></p>
<a href="<?php echo $_REQUEST['path']; ?>">
<img src="<?php echo $_REQUEST['path'] ?>" />
</a>
</div><!-- end container -->
</body>
</html>
The failure error page
The failure.php error page simply shows a user-friendly error message indicating that the upload was unsuccessful. The PHP script on this page retrieves the data that was passed along with the HTTP GET request for the page. This data is the error message that was output by the Uploader object.
<?php echo "<?" ?>xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Failure! File Not Uploaded</title>
<link rel="stylesheet" type="text/css" href="styles/main.css" />
</head>
<body>
<div id="container">
<h1>Failure! File Not Uploaded</h1>
<p>Your image failed to upload</p>
<p><?php echo $_REQUEST['error'] ?></p>
<p>
<a href="index.html">try again</a>
</p>
</div><!-- end container -->
</body>
</html>
Posted: July 21st, 2009 | Author: amos | Filed under: email, php | Tags: class 8 | 1 Comment »
PHP’s built-in mail() function allows you to send emails from PHP code. This can be useful when, for example, you want to include a “Contact Me” form on your website, and you want an email to be sent to you whenever someone fills out that form.
The mail() function has three required parameters: the “To” email address, the subject of the message, and the content of the message. There is also a fourth additional header that can contain one or more additional information, such as who the message is “From”, any “CC” or “Bcc” email address, and some other obscure things.
Click here to view this example code in action.
XHTML page with form
In this example, we’ll look at the most common scenario: how to use an XHTML form that a user can fill in to send a message with all four parameters, “To”, “From”, subject, and message content.
The first thing to do would be set up an XHTML document called “index.html” with a form that users can fill in to send the email. A typical “Contact us” XHTML document might look like this:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Contact us</title>
<link rel="stylesheet" type="text/css" href="styles/main.css" />
</head>
<body>
<div id="container">
<h1>Contact us</h1>
<p>Fill out this form, and click submit, and we'll receive an email!</p>
<form action="process_email.php" method="POST">
<label for="name">Your Name:</label>
<input type="text" id="name" name="name"/>
<br />
<label for="email">Your Email:</label>
<input type="text" id="email" name="email"/>
<br />
<label for="subject">Subject:</label>
<input type="text" id="subject" name="subject"/>
<br />
<label for="message">Message:</label>
<textarea id="message" name="message"></textarea>
<br />
<input type="submit" value="Send email!"/>
<br />
</form>
</div><!-- end container -->
</body>
</html>
As you can probably notice from the attributes of the <form> tag, this form will be using the HTTP POST method of passing data to the server. And when a user clicks submit, the data the user entered gets sent, along with the POST request, to the file called “process_email.php”.
PHP script to process the data entered in the XHTML form
The PHP script that receives this data, called “process_email.php“, looks like the following:
<?php
$to = "yourname@yourdomain.com"; //the email address where you want to receive these emails//get the data the user entered in the form
$name = $_REQUEST['name']; //get the data the user entered in the name field and store it in a variable
$email = $_REQUEST['email']; //get the data the user entered in the email field and store it in a variable
$subject = $_REQUEST['subject']; //get the data the user entered in the subject field and store it in a variable
$message = $_REQUEST['message']; //get the data the user entered in the message field and store it in a variable
//put together the email headers, which contain the name, email, and other info about the mail program we're using
$phpVersion = phpversion(); //this calls a built-in PHP function that returns the current version of PHP installed
$headers = <<<END
From: {$name} <{$email}>
Reply-To: {$email}
X-Mailer: PHP/{$phpVersion}
END;
//use php's built-in mail() function to send this e-mail
mail($to, $subject, $message, $headers);
//redirect to success page
header("Location: success.php?to={$to}");
?>
Let’s analyze this file. You can see that the first thing this code does is hard-code the “To” address. Since these emails are supposed to all be going to us, we don’t want to ask the users of our site to enter in the email address to which they want to send these emails. We don’t want to give them the ability to send emails to anyone but us! So we hard-code that address.
The other variables we set up are all just storing the data the user entered on the XHTML page in the form. We access that data by reading it from PHP’s built-in $_REQUEST array, which has all the information on all data that was submitted along with any type of HTTP request.
Then we assemble a set of extra headers that indicate who the email is “From”, what address the receiving email program should use as the “Reply-to” address, and the name of the program that was used to send this email (in this case, we’re simply substituting the version of PHP).
Finally, we call the mail() function of PHP, along with the parameters necessary to actually send the email. Once that is finished, we redirect the user’s browser to the page, success.php, which has a user-friendly confirmation message. We redirect the browser by sending a “Location” HTTP header to the browser in response to the browser’s request for this page. This tells the browser that it should redirect to success.php, rather than stay on the current page.
The header we send to the browser in response to its request for this page looks like this:
header("Location: success.php?to={$to}");
You may recognize that we are attaching some data onto the query string of the file that we are instructing the browser to request instead of the current page. So when the browser requests that other file, it will pass some data back to that other server script along with the new request. To be exact, the browser will request the following file from the server with the following query string:
sucess.php?to=yourname@yourdomain.com
In this case, the data being passed is the “To” address indicating to where the email was sent.
Confirmation screen
The confirmation page, called “success.php“, receives that data in the $_REQUEST array, and outputs a friendly message that acknowledges the successful sending of the email to that address that was passed along with the request.
<?php echo "<?" ?>xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Success! Email Sent</title>
<link rel="stylesheet" type="text/css" href="styles/main.css" />
</head>
<body>
<div id="container">
<h1>Success! Email Sent</h1>
<p>Your email has been successfully sent to <?php echo $_REQUEST['to'] ?></p>
<p><a href="index.html">Click here to send another</a></p>
</div><!-- end container -->
</body>
</html>
Posted: July 19th, 2009 | Author: amos | Filed under: php | Tags: class 7 | No Comments »
When we learned how to create and use Javascript variables, and Javascript functions, we were learning techniques that apply across many programming languages. Fortunately, in this regard, Javascript and PHP are very similar, and we will not have to re-learn the theory of variables and functions. We will just focus on the slight differences between the syntax of the two languages.
PHP variables
In PHP, variables are declared and defined like this:
$someVariable1 = 10;
$someVariable2 = "something";
Notice the dollar sign before the name of each variable – in PHP all variable names begin with the dollar sign. Also notice that, like Javascript, all PHP instructions must end in a semi-colon.
Variables do not need to be explicitly declared in PHP. Whereas in Javascript, we declared variables, as in “var someVariable”, before using them, in PHP, we usually just define them. PHP automatically handles the declaration. There are some circumstances in which we may want to declare our intention to use a variable in PHP without actually giving it a defined value. Doing so is as simple as:
$someVariable1;
Like Javascript, PHP is a mostly untyped language, meaning a single type of variable can hold the any type of data: numeric values, Strings (i.e., text), arrays (i.e. lists), and other more complicated types of data (i.e. objects.)
PHP functions
Functions in PHP look almost identical to their Javascript counterparts. A simple function definition might look like:
function doSomething() {
echo "Hello World";
}
To call this function, one would use the following code:
doSomething();
This function would simply output the text “Hello World”. “echo” is a special PHP command to output some text.
Parameters in functions must use the PHP syntax for variable names, meaning they must begin with a dollar sign. For example, here is a function that accepts a parameter:
function sayHello($personName) {
echo "Hello, " . $personName;
}
This function takes one parameter, which it calls $personName. It then concatenates the text, “Hello, ” with the value of the variable $personName. Unlike Javascript, PHP does not use the “+” sign to do string concatenation. In PHP, “+” is used only for mathematical addition. PHP uses the concatenation operator to concatenate strings. So, for example, calling the function like this…
sayHello("Andy");
…would put the word, “Andy” in the variable called $personName. The function then concatenates the text, “Hello, ” with the word “Andy”. And ultimately, the function would output the following text:
Hello, Andy
PHP arrays
The built-in array() function of PHP is used to create arrays. Recall that arrays are lists of things, not single values like regular variables.
To create an empty array which can be populated with data later in the code, call the array() function with no parameters.
$arrSomething = array();
To add an element to the array at index 15, use code such as:
$arrSomething[15] = "the sixteenth value in the array";
To add an element to the array at the next available index, simply leave the index blank, as in the following code:
$arrSomething[] = "the new value";
To output the value of the 16th item in the array (remember that arrays are indexed starting from number 0, so the 16th item actually has an index value of 15):
echo $arrSomething[15];
In our example, that statement will output the following text, since that is what we stored earlier at index 15 of the array:
the sixteenth value in the array
PHP associative arrays
PHP arrays, like Javascript arrays, can be indexed by either integers or Strings. When they are indexed by Strings, they are often called “associative arrays”. To create an element in an array indexed by a String, use code like this:
$arrSomething["my_birthday"] = "October 3".
To output the value of this item of the array later in the code:
echo $arrSomething["my_birthday"];
This will output the following text:
October 3
PHP multidimensional arrays
PHP, being a loosely-typed language, allows you to put anything you want into a variable. Variables can contain numbers, strings, objects, or any other data type. Arrays are the same. Array elements can hold numbers, strings, objects, and other data types including other arrays.
$myArray = array();
$myArray[] = 100; //array element 0 holds the number 100
$myArray[] = "some text"; // array element 1 now holds the string, "some text"
$myArray[] = array(); //array element 2 now holds an empty array
$myArray[] = array("this", "that", "the other"); //array element 3 now holds an array with three elements in it
echo $myArray[0]; //outputs the number, 100
echo $myArray[1]; //outputs the text, "some text"
echo $myArray[2]; //outputs the text, "Array"... this is probably not what you wanted.
echo $myArray[3]; //outputs the text, "Array"... this is probably not what you wanted.
echo $myArray[3][0]; //outputs the text, "this"
echo $myArray[3][1]; //outputs the text, "that"
echo $myArray[3][2]; //outputs the text, "the other"
Posted: July 19th, 2009 | Author: amos | Filed under: php | Tags: class 7 | No Comments »
PHP is the server-side programming language we will use for the remainder of this course. PHP is a general-purpose language that can be used for many things. However, parts of the language have been especially designed to be easy-to-use in web development. The primary uses of PHP in web development are:
- templating
- business logic
Templating
Templating is the process of distilling the component parts of a web page, or a set of web pages, such that there is as little redundancy between pages as possible. This is easily illustrated with an example.
The BBC News website uses the same header section on every single page:

BBC News header
Every page on the BBC News site also has the exact same left navigation section:

BBC News left navigation
… and every page on the BBC News site has the same footer at the bottom:

BBC News footer
Given that there are thousands of pages within the BBC News website, if the website managers decided to add a new featured link to the header, they might have to modify the top section on 10,000 seperate XHTML pages. Clearly, this can become unmanageable, even for a much smaller site.
Any web developer with a modicum of experience would immediately realize that a site such as this should be broken down into templates. Most likely, the XHTML code for the top header section is stored in its own file, isolated from the rest of the page. Let’s say this file is called “_header.html”. Every page on the site includes “_header.html” into the top section of the XHTML for that individual page. If the site administrators want to add a new link to the top header, then they edit only “_header.html”, and all the pages on the site automatically show that update, since they are all loading the header XHTML code from that file.
The same process would occur for the left navigation section, footer, and any other elements that repeat themselves across the site.
Business logic
The second most important use of PHP is to implement what is called “business logic.” This consists of the logical rules necessary to determine what content should be shown on any given page.
For example, when a user goes to bing.com, and enters a search term in the form, you know enough to realize that this is probably an XHTML page with CSS style sheets, and a <form> tag with a <input type=”text” …> text input where users enter in the term they want to search. When you type a search term into this form, such as “web development intensive”, and click submit, you are taken to a new page with the search results. Somehow, this new page knows what you typed in the form on the last page, and has gone and retrieved a list of sites that match the search term “web development intensive”, presumably from a giant directory of websites somewhere.
The search results page is presumably templated. Each search result page looks pretty much the same. The header, footer, left nav, and right nav sections of the page look pretty much the same no matter what you search for. It’s really just the exact details of the search results that differ from one search to the next. It’s safe to assume that this page is templated, and the details of exactly what search results are shown on any given search results page are dictated by certain business rules. The logical rules determine what content gets put into the template.
This page has used business logic rules to infer what it was you wanted to do on this site, and has retrieved the relevant content from a database somewhere and shown you the search results in well-formatted (presumably templated) XHTML code. Any e-commerce site, news site, search engine, classifieds site, or any other type of site with dynamic content that is stored in a database will most likely operate the same way.
Posted: May 4th, 2009 | Author: amos | Filed under: mysql, php, search | Tags: class 11 | No Comments »
As we discussed in class, there are two ways of implementing search functionality on your sites using built-in MySQL commands.
The first technique takes advantage of the WHERE LIKE clause in SQL. The second technique takes advantage of the FULLTEXT search feature built into MySQL.
Both these methods, of course, presume that the content you want to be searching is stored in a MySQL database. If the content you want to search is hard-coded in an XHTML page, rather than stored in a database, then these methods will not be useful to you, and you would do better to use Google Custom Search, Yahoo Search, or some other service that provides search functionality for regular XHTML documents.
Search using WHERE LIKE
This is the simplest form of MySQL search. You can see this example live in your browser here.
Let’s assume that we have a table, called “abloomberg_blogposts” that stores a bunch of blog posts. The table has the fields, “id”, “title”, “message”, and “created”.
As you know, the SQL query to read all the rows from the table would be:
SELECT * FROM abloomberg_blogposts WHERE 1
The “WHERE 1″ part of the query tells MySQL to return all the rows in the table.
To read only those rows that had the title “cat”, we could run this query:
SELECT * FROM abloomberg_blogposts WHERE title LIKE '%cat%'
In this case, the “WHERE title LIKE ‘%cat%’” part of the query tells MySQL to return only those rows in the table where the “title” field contains the string, “cat”. The “%” percent signs indicate wild card that matches any character or bunch of characters.
Because of the use of the wild cards before and after the search term, this query will match any of the following strings:
cat
catamaran
bobcat
concatenate
If we only wanted to match those rows where the “title” field began with the word, “cat”, we could use the following query with only a wild card after the search term:
SELECT * FROM abloomberg_blogposts WHERE title LIKE 'cat%'
Likewise, if we wanted to only match those rows where the “title” field ended with the word, “cat”, we could use this query:
SELECT * FROM abloomberg_blogposts WHERE title LIKE '%cat'
Finally, if we wanted to search more than one field, we can combine multiple queries together using the UNION keyword in SQL. For example, if we wanted to search both the “title” and the “message” fields at once, we could use the following query:
SELECT * FROM abloomberg_blogposts WHERE title LIKE '%cat%' UNION SELECT * FROM abloomberg_blogposts WHERE message LIKE '%cat%'
We could chain together as many queries as we like using the UNION keyword, and MySQL will return the combined results of all of them.
Assuming you are running queries like this in PHP, rather than directly in SQL, you will probably want to store the search term in a variable rather than hard-code it in the SQL command. Replacing the search term with a PHP variable called $searchTerm will make your queries look something like this:
$myQuery = "SELECT * FROM abloomberg_blogposts WHERE title LIKE '%{$searchTerm}%' UNION SELECT * FROM abloomberg_blogposts WHERE message LIKE '%{$searchTerm}%'";
Search using FULLTEXT search
The alternative method of searching in MySQL is to use the FULLTEXT search feature built into MySQL. You can see this example live in the browser here.
This method allows you to search more than one field in a single query. It also allows you to be a bit more flexible with your search, and it is smart enough to ignore common words like “a”, “the”, “of”, etc.
Here is an example of using MATCH AGAINST to search for the word “cat” in both the “title” and “message” fields of our “abloomberg_blogposts” table:
SELECT * FROM abloomberg_blogposts WHERE MATCH (title, message) AGAINST ('+"cat"' IN BOOLEAN MODE)
As you can see, the fields you want to search go inside the MATCH(…) section, and the search term you want to find goes inside of the AGAINST(…) section of the query.
The plus sign, “+”, in the query indicates that you want to search for all rows that contain the word “cat”. If you replaced this with a minus sign, “-”, the query would return all rows that did not contain that word.
Assuming you are running this query in PHP, rather than directly in SQL, you will most likely want to replace the search term with a variable. And your PHP code would look something like this:
$myQuery = "SELECT * FROM abloomberg_blogposts WHERE MATCH (title, message) AGAINST ('+\"{$searchTerm}\"' IN BOOLEAN MODE)";
Important Note: In order to use this FULLTEXT search feature, MySQL requires you to create a FULLTEXT index on any text field (including varchar and text fields) that you want to use in your search. The FULLTEXT index is a way of optimizing those fields for search.
If you look at the structure of the abloomberg_blogposts table in phpMyAdmin, you will see that there is a FULLTEXT index on the title and message fields, which allows this example search to work.

Indexes used by the abloomberg_blogposts table
Creating a FULLTEXT index in phpMyAdmin
You must create such an index on the fields you intend to search in your own code in order to use the FULLTEXT search technique. Creating such an index is simple in phpMyAdmin. First go to the “Structure” tab of the table you will be searching. In the Indexes box on that page, in the “Create an index on … columns” text field, fill in how many fields you wish to create the index for (i.e. how many fields you will be searching), and then click Go. The next page will ask you which fields you want to index (i.e. which fields you will be searching), and it also asks you to name this index. You can name the index anything, but it’s probably best to use a name that includes the field names the index uses. In my example, the index is named, “title_message”.
More information on FULLTEXT search
http://www.onlamp.com/pub/a/onlamp/2003/06/26/fulltext.html
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
http://dev.mysql.com/doc/refman/5.1/en/fulltext-boolean.html
Posted: May 2nd, 2009 | Author: amos | Filed under: mysql, php | Tags: class 11 | No Comments »
Here is an example of how to do pagination of data in PHP.
Let’s say you have a database table full of animals. You only want to show 10 animals per page, with “previous” and “next” buttons to allow users to go to the previous or next page of results.
There are a few different things we need to keep track of in our code to make this type of pagination work. Here’s a quick run-down of the most important pieces of code in the controller:
- $pageNum = the page number of the page the user is viewing
- $numRowsPerPage = the number of results we want to show on each page
- $startIndex = the index of the first row we want to display on this page
- $endIndex = the index of the last row we want to display on this page
- $numRowsTotal = the total number of results in the database
- $numPagesTotal = the total number of pages of results
The current page number
The current page number is retrieved from the query string of the URL using the ubiquitous $_REQUEST variable.
//FIGURE OUT WHICH PAGE OF RESULTS TO SHOW
$pageNum = $_REQUEST['page']; //which page to show
//if no page requested, load the first page
if (empty($pageNum)) {
$pageNum = 1;
}
This code checks for the page number in the query string. If there is no page number there, it defaults to page 1.
The number of results to show on each page
The $numResultsPerPage variable is just hardcoded to some value:
//PAGINATION SETTINGS
$numRowsPerPage = 10; //how many results to show per page
The index of the first row to show
If the user is viewing page 1, and there are 10 rows per page, then the first row we want to show them is row 1, and the last row is row 10. If they are on page 2, then the first row we want to show them is row 11, and the last is row 20… because they have already seen 1-10.
The general formula for this is:
//calculate the start index of the rows to show on this page
$startIndex = ($pageNum-1) * $numRowsPerPage; // get the starting index number of the first item to show on this page
The index of the last row to show
In general, the index of the last row on the page is just the index of the first row, plus the number of rows on the page.
//calculate the end index
$endIndex = $startIndex + $numRowsPerPage;
However, on the very last page, it may be that there are fewer than 10 results. This means that the index of the last row may not be just the index of the start row plus 10. So we need to check to make sure that if we are on the last page, the value we calculated for the index of the last row is not greater than the total number of rows in the table.
//make sure on the last page that we don't have an end index that is greater than the total number of rows
if ($endIndex > $numRowsTotal) {
$endIndex = $numRowsTotal;
}
The total number of rows
The total number of rows is just how many rows there are in the database table.
$numRowsTotal = sizeof(getAnimals()); //get the total number of animals in the database
This function getAnimals() returns an array with the full list of animals, and we use PHP’s built-in sizeof() function to get the number of elements in that array.
The total number of pages
The total number of pages is just the total number of rows, divided by the number of results per page. That’s the math.
$numPagesTotal = ceil($numRowsTotal / $numRowsPerPage); //get the total number of pages
Display the number of results
Assuming the aforementioned variables have all been set up properly in the PHP in your controller script, you will probably want to display the indexes of the results shown on any given page, as well as the total number of results somewhere in the XHTML template you are using for the view of your application.
The following bit of XHTML interspersed with “template-style” PHP will display the start and end number of the results on the page, as well as the total number of results in a nicely formatted, “normal” way that is commonly used by search engines:
<span>Displaying <?php echo $startIndex + 1 ?>-<?php echo $endIndex ?> of <?php echo $numRowsTotal ?> results</span>
This will output something like this in the browser,
Displaying 1-10 of 35 results
Display links to other pages
Let’s say you have 10 pages of results. The first time a user comes to your site, they will see page #1. So obviously, in your XHTML templates, you will also want to dislpay links to the other pages of results. To do this, you will make use of some of the other variables we have set up in the PHP controller script.
Here is an example of how to use the PHP variables to output a very ordinary set of links to other pages:
<?php if ($pageNum > 1) : ?>
<a href="index.php?page=<?php echo $prevPage ?>">Prev</a>
<?php endif ?>
<?php if (($pageNum-1) * $numRowsPerPage + $numRowsPerPage < $numRowsTotal) : ?>
<a href="index.php?page=<?php echo $nextPage ?>s">Next</a>
<?php endif ?>
<?php for ($i=1; $i<=$numPagesTotal; $i++) : ?>
<a <?php if ($pageNum == $i) : ?>class="selected"<?php endif ?> href="index.php?page=<?php echo $i ?>"><?php echo $i ?></a>
<?php endfor ?>
Let’s take this code line-by-line. The first three lines here display the “Prev” link to the previous page:
<?php if ($pageNum > 1) : ?>
<a href="index.php?page=<?php echo $prevPage ?>">Prev</a>
<?php endif ?>
If the user is on the first page, it doesn’t make sense to have a link to the previous page since there is no previous page, so we check to make sure the user is not on the first page before displaying this link.
The next three lines of code display the link to the “Next” page:
<?php if (($pageNum-1) * $numRowsPerPage + $numRowsPerPage < $numRowsTotal) : ?>
<a href="index.php?page=<?php echo $nextPage ?>s">Next</a>
<?php endif ?>
This code is basically just making sure that there is a next page before outputting the link. It doesn’t make sense to show a link to the next page if we’re already on the last page.
And these last three lines display the page numbers of all the pages as links:
<?php for ($i=1; $i<=$numPagesTotal; $i++) : ?>
<a <?php if ($pageNum == $i) : ?>class="selected"<?php endif ?> href="index.php?page=<?php echo $i ?>"><?php echo $i ?></a>
<?php endfor ?>
The for loop here loops through from the first to the last page, and displays each page number as a dynamic link to that page of results. It highlights the current page by adding a CSS class called “selected” to the link tag.
Posted: April 26th, 2009 | Author: amos | Filed under: php | Tags: class 9, controller, model, mvc, view | No Comments »
MVC architecture is a growing trend in software development of all kinds, including for the web. If you can master object-oriented programming combined with MVC architecture, you can consider yourself to be a very knowledgeable developer.
This architecture divides the code involved in any project into three parts: Model, View, and Controller. It’s important to bear in mind that the idea of dividing a project into these three parts is a concept. How that concept should actually be implemented in practice depends on who you’re talking to, what language(s) you are programming in, as well as the framework you are using, if any.
M is for Model, V is for View, and C is for Controller.
The Model is the part of the code that deals directly with the database. So all the code that does the database CRUD (create, read, update, delete) functions, as well as any other code that makes direct queries to the database should be considered part of the Model. Any time any code in any application you are building needs to interact with the database in any way, it has to do that by calling functions in the Model.
The View is the part of the code that creates the interface that the user sees. For web development, the View consists mostly of the XHTML, CSS, Javascript, and any other client-side technologies that create the actual interface of the web site. The view is the sort-of template that is then filled in with data that comes from the Model.
The Controller is the sort of brains of the operation. It is the glue that links the Model, the View, and the user together. The controller’s main function is to figure out what the user is trying to do, and to then use the Model to get the data that is necessary to do that, and then use the View to display that data to the user in a nicely designed page.
Posted: April 25th, 2009 | Author: amos | Filed under: php, rss | Tags: class 10 | No Comments »
In class today, we’re looking at an example of how you can use the SimplePie PHP library to pull content from any site’s RSS feed and display it on your own pages.
In this example, SimplePie is acting as the Model in an MVC architecture. index.php is the Controller, and index_view.php is the View.
In the example files, you will notice that there is a folder called “cache”. This is where SimplePie temporarily stores copies of the RSS feeds that you load. It keeps each cached copy of the RSS feed for several minutes, so that if you reload your page, it doesn’t have to always reload the same data from the site that publishes the RSS feed.
In fact, some sites will ban your site from accessing their RSS feeds forever unless you store cached copies of their feeds. This is because they want to minimize the number of requests that are made to their servers. SimplePie does this by default if you have a “cache” folder available.
You’ll also notice an “images” folder. This stores default placeholder images for media files. SimplePie integrates with the JW Media Player application. So if a particular RSS feed has media attachments, whether audio or video, SimplePie will automatically generate the appropriate JW Media Player code, so you don’t have to worry about doing it yourself.
If you use SimplePie, you will need to make sure you have the simplepie.inc file (which holds the main SimplePie code), the cache folder (which stores cached copies of all RSS feeds), the images folder with default images, and the idn folder (which holds other misc SimplePie files).