December 5th, 2009 §
DEADLINE
- All final projects must be complete by the last day of class.
REQUIREMENTS
- projects must show your mastery of the technologies we have learned in this class: XHTML, CSS, Javascript (using JQuery), PHP, and MySQL.
- projects must be completely information architected before you start programming
- projects must involve at least 3 distinct web pages.
- you are required to present your site to the class on the last day of class
- all filenames must be all lowercase with no spaces or special characters except underscore “_”
- all variable names in PHP and Javascript must be written in lower camelCase.
- all CSS class names and IDs must be written in lowercase, with no special characters except the underscore “_” character.
- final projects must be working and accessible on the web (if it only works on your client machine, it is not a working web site)
- projects must be linked to from your blog.
GRADING
Grades will be based on your ability to exhibit mastery of Information Architecture and Web Development programming techniques.
- Information Architecture (20%)
- Programming (50%)
- Ability to conceptualize and realize a fully-functioning, well thought-out site (30%)
PRESENTATIONS
You will be required to present your work to the class on the last day of class.
Presentations should be no more than 10 minutes.
Here are some suggested questions to answer in your presentation:
You
- what’s your name?
- remind us… what do you do when not in this class?
- did you have any previous design or development experience?
- any previous experience with the web?
Concept
- three sentence description of your site
- why did you decide to build this site?
- who is your intended audience?
- does this site serve a particular need, either personal or business?
Information Architecture
- how many main pages are there, and how are they conceptually related? In other words, what is the hierarchical structure of the site? Perhaps show a simple sitemap diagram to help explain.
- what are the main navigation elements people can use to get from one page to another?
- is there a consistent header, footer, or navigation section on every page?
- how does a user know where they are in the hierarchy of your site? Breadcrumbs? Highlighted navigation links? Or is your site so simple a user couldn’t possibly get lost?
- what kind of content are you showing on each page?
- how are the bits of information on each page related to each other (if at all)?
- what is the most important info on each page, and what is the least important info, and how did that affect the layout of the page?
Design
- what were you thinking in terms of design of your site?
- what design techniques did you use to get the pages to look as they do?
- did you borrow any design ideas from other sites?
- are you happy with the design of your site?
Development
- are you using page “templates” in PHP?
- is there anywhere where you are passing data from one page to another?
- is your data stored in a database or hard-coded into the XHTML?
- if using a database, did that make development easier, or more difficult?
- are you using Javascript, JQuery, and any JQuery plugins?
- did you use any AJAX, and if so, where?
- discuss any interesting development challenges you faced in any of these technologies.
The future
- is this site a good representation of what you originally planned?
- what remains to be completed on your site?
- what parts do you think work, and which do you think don’t work?
- do you plan to continue developing this site?
- are you hoping to actually launch it as a real website?
- are you planning to continue with web development?
- what parts of web development interested you most?
- what parts of web development interested you least?
- how has this class reinforced or changed your view of the web?
November 23rd, 2009 §
In your readings, you may have come across mention of PHP Sessions. Sessions are another mechanism, in addition to the $_GET, $_POST, and $_COOKIE variables that allow you to “maintain state”, meaning to pass data from one page to another.
Session variables are just like cookies, but easier
PHP provides a set of functions that allow you to read and write session variables. The basic idea is that session variables allow you to store data for as long as the user’s session is still alive. Generally, a session is alive as long as the user’s browser is open, just like cookies. These session variables can be accessed from any page on the site, just like cookies.
These are variables that are stored on the server, and last for a limited amount of time. They are functionally very similar to cookies, and in fact PHP does use cookies to perform most of the tasks involved with Sessions. But PHP hides the internal details of how Sessions work, which makes your job a little bit easier.
How to use sessions in PHP
Any script that uses session variables, either to read or write them, needs to call the session_start() bult-in PHP function at the top of the script. This is just a command to tell PHP that you want to use sessions on this page.
Once you have done that, you can create a session variable like this:
//create a session variable called "test_variable"
$_SESSION['test_variable'] = "this is the value of the test variable";
Once you have created a session variable, any other page on your site can access that variable like so:
//echo the value of the session variable called "test_variable"
echo $_SESSION['test_variable'];
Example Files
Here is an example of a script that writes a session variable, just like the example code above.
And this page reads that same variable and outputs it to the page.
Further reading
Here are some pages that cover sessions, and explain how to write PHP code to deal with them:
http://php.about.com/od/advancedphp/ss/php_sessions.htm
http://www.tizag.com/phpT/phpsessions.php
http://www.htmlgoodies.com/beyond/php/article.php/3472581
http://us3.php.net/session
November 23rd, 2009 §
As a general rule, any data that comes from a user is not to be trusted. So anytime you are dealing with data that may (or may not) have originated from a user, you need to sanitize that data before doing anything else with it. Think of it as basic web hygiene, akin to washing your hands in the restroom. Quoting Google’s CEO, Eric Schmidt, the intenet is a “cesspool”. None of us needed him to tell us that – it’s obvious.
Anytime your site deals with data that does not originate from your own code, you need to sanitize it before letting it touch the internal organs of your website. When we talk about sanitizing, we’re not talking about removing bad words from the code, we’re generally talking about preventing malicious hackers from trying to break into our website by sending data to the server that may allow them to exploit faults in our code or weaknesses on the server.
User-generated content may often come from any of the following sources:
Practical sanitization
No need to get paranoid yet. For our practical purposes, any data that you get from the $_REQUEST, $_GET, $_POST, or $_COOKIE arrays should be sanitized.
Let’s say you have code like this:
$dummyData = $_REQUEST['dummy_data'];
This is getting data from the $_REQUEST variable, which as we know is automatically populated with data from the query string in links, from form fields, or from cookies. In other words, it’s potentially tainted. And let’s say you are planning to store that $dummyData in a database table like so:
$myQuery = "INSERT INTO abloomberg_dummy (data) VALUES ('{$dummyData}')";$result = mysql_query($myQuery);
You absolutely must sanitize it to prevent malicious things like SQL injection attacks before you run that query.
An example
This example uses PHP code to do just that. It uses an object-oriented Sanitize class (as in classes and objects in object-oriented programming) that I based off of another well known (but not object-oriented) script.
To use this Sanitize class in your own PHP scripts, before you do anything else:
- download a copy of the zip archive, unzip it, and put the file Sanitize.class.php in the folder for your project.
- make sure your script includes this file by using require_once(“Sanitize.class.php”);
Once you have that set up, you’re ready to use this class. Here is an example usage:
<?php //file: index.php //an example of using the Sanitize class
//include the Sanitize class into this script require_once("Sanitize.class.php");
//on a live site, you'd want to sanitize all data that you got from the user //in otherwords, any time you use data you got frm the $_REQUEST, $_GET, $_POST, or $_COOKIE variables //For example, if the data was coming from a form or query string in a link: //$dirtyData = $_REQUEST['something'];
//in this example, for simplicity, i'm just sanitizing the contents of a variable that's hardcoded $dirtyData = "this is a test with an HTML tag <a href='#'>click me</a>";
/* First choose how you want to santize the data. The choices are: (PS: notice that these are static properties of the Sanitize class - hence the :: symbol)
Sanitize::HTML //replaces any HTML tags with "HTML entities" Sanitize::SQL //prevents against SQL injection attacks Sanitize::UTF8 //makes sure data is in UTF8 format Sanitize::INT //makes sure the data is an integer Sanitize::FLOAT //makes sure the data is a float (decimal) Sanitize::LDAP //prevets against any LDAP code Sanitize::SYSTEM //prevents any system commands from being run Sanitize::PARANOID //all of the above */
//set the $flags variable to be the sum of all the flags you want to use from the list above $flags = Sanitize::HTML + Sanitize::SQL; //this example removes any HTML or SQL commands from the string
//now pass the data and the $flags variable to the sanitize function to sanitize it $cleanData = Sanitize::sanitize($dirtyData, $flags); //call the static method "sanitize of the Sanitize class
//now your data is clean echo $cleanData; //the text stored in this variable has been "sanitized"
//you may want to "view source" in the browser to see what happened to the text?>
Understanding the Sanitize::sanitize() method
The most important part to understand is the command that actually does the sanitizing:
$cleanData = Sanitize::sanitize($dirtyData, $flags); //call the static method "sanitize of the Sanitize class
This line calls the Sanitize::sanitize() function and passes it two arguments: the data to be sanitized, and the flags that indicate what type of sanitization you want to do. The result of this sanitize() function is then put into the variable $cleanData, which now has the sanitized version of the data.
In this example, we have set the $flags variable to indicate that we want to remove any HTML or SQL code from the data:
$flags = Sanitize::HTML + Sanitize::SQL; //this example removes any HTML or SQL commands from the string
We can use any combination of the available flags by adding them together.
Now that the data has been sanitized, you can safely store that data in a database without worrying about SQL injection attacks:
$myQuery = "INSERT INTO abloomberg_dummy (data) VALUES ('{$cleanData}')";$result = mysql_query($myQuery);
Or do whatever else you want with it. But rest assured it does not have any malicious HTML or SQL code in it.
Note that since this example is object oriented, we never have to look at the source code of Sanitize.class.php. This is abstraction at work.
November 6th, 2009 §
Let’s cover the details of the SELECT statement in SQL. The SELECT statement is the command we use to do the Read part of database CRUD. CRUD is an acronym that stands for Create, Read, Update, Delete – the four operations you are most likely to do with a database. At any given time, you are either creating data, reading data, updating data, or deleting data.
We’ll start with the simplest possible SELECT statement in action, and then move to more nuanced implementations.
Let’s say we run a business managing art collections for wealthy individuals. We might want to build an inventory management application to keep track of which paintings our clients own.
The first step towards that would be to have a table that holds a list of our clients. Let’s call this table “collectors”. And let’s say we put the following information in it:

collectors table
An easy read
To do a query on the database to get all the information on all the rows in our table, we might do a simple SELECT statement as follows:
SELECT * FROM collectors WHERE 1
And reacall that in PHP, we execute queries on the database using the mysql_query() built-in function:
$myQuery = "SELECT * FROM collectors WHERE 1";
$result = mysql_query($myQuery);
This would return the full data set internally represented in basically the same way as what we’ve already seen. The order that the data is stored inside of a database is not necessarily chronological order, so the data may show up in a different order if you don’t specify in what order you’d like to receive it.

result set of full select query
Selecting specific fields
Let’s hypothetically say we only wanted to get the id and last name for each collector in our table. To do this, we would specify which fields we were interested in as follows:
SELECT id, last_name FROM collectors WHERE 1
Notice that we use a comma delimited list of field names after the SELECT keyword. This query would return a data set that looked like this:

A result set with only two fields
Ordering results
And now let’s say we wanted to order the results alphabetically by last name starting with A and ending in Z:
SELECT id, last_name FROM collectors WHERE 1 ORDER BY last_name ASC
The “ORDER BY” clause takes two parameters: the field we want to order the results by, and the order we want them returned in: either ASC or DESC for ascending and desc ending respectively.
Our example query would return a result set that looked like this:

result set ordered by the last_name field
Modifying the WHERE clause
To do a query that only returned the results for the collector with id #3, we would do a query like this:
SELECT * FROM collectors WHERE id=3
This would return a data set that looked like this:

result set matching only a single row
We can specify any criteria we want in the WHERE clause. If we only wanted to get the data for users who were NOT id #3, we could do this:
SELECT * FROM collectors WHERE id<>3
The <> symbol is the SQL way of saying NOT EQUALS.
Paginating results
Lastly, but not leastly in this set of examples, let’s say we had 400 collectors in our table. And we want to make a web-based interface that only shows 10 at a time, ordered alphabetically by last name. Will will have page number links so users can click on which “page” of results they want to view: 1,2,3,4, etc.
To paginate results, we would require a LIMIT clause on the SELECT query. For example, this query would return only the first 10 rows:
SELECT * FROM collectors WHERE 1 ORDER BY last_name ASC LIMIT 0,10
The LIMIT clause in this case takes two arguments, separated by a comma: the result number to start from, and the number of results to return. In this case, we are telling SQL to start from the first result in the entire data set of results, and return only 10 results total.
To get the next “page” of results, we might make a query to start from the 11th result, and return the next 10:
SELECT * FROM collectors WHERE 1 ORDER BY last_name ASC LIMIT 11,10
And so on…
Joining multiple tables of data
Now that we’ve covered all the basic elements of the SELECT statement, let’s use them to select data from multiple tables.
Let’s say we had a second table in our example. This table was a list of all the paintings that each of our collectors owns. Let’s call this table “paintings”, and it might look like this:

paintings table
Notice that this table has a foreign key field, “collector_id” that holds the id of the collector who owns each particular piece.
So let’s now say we wanted to combine the two sets of data. We want to get a list of all the paintings in our database, as well as the last names of collectors who own them. We might do a query like this:
SELECT paintings.*, collectors.last_name FROM paintings, collectors WHERE paintings.collector_id=collectors.id
This would return a set of data that looked like this:

esult set with data from two tables
Notice that we have merged data from both tables. The result set now has all of the data from the “paintings table”, as well as the last_name field from the “collectors” table.
There are two new things going on in this example. Firstly, when we are dealing with multiple tables, we have to be very clear about which fields we want to get data from, and which table those fields are in.
In this case, we asked for all fields from the “paintings” table by specifying “paintings.*”, and we also asked for only the “last_name” field of the “collectors” table by specifying “collectors.last_name” in the query.
Secondly, the WHERE clause tells SQL how to merge the tables. By specyfing “WHERE paintings.collector_id=collectors.id”, we are telling SQL to match up the two sets of data by the fields “paintings.collector_id” and “collectors.id”. In other words, we are telling SQL that the “collector_id” field in the “paintings” table is a foreign key that points to the “id” field of the “collectors” table.
So for every row in the “paintings” table, SQL looks at the “collector_id” field, and finds the “last_name” field from the corresponding row in the “collectors” table.
This type of merging of data from two tables by matching up a field in one table with another field from another table is known as an inner join in SQL terminology. This is, by far, the most common type of join, or merge, that developers do.
July 22nd, 2009 §
A few of you may be interested in adding search functionality to your sites. Unfortunately, creating a really good search is something that is far beyond the scope of this course.
However, there are a few simple options: using MySQL’s built-in search features, and using Google Search on your site.
Using MySQL to do search
I have written a post outlining the built-in search features available in MySQL. It is obvious but nevertheless important to note that in order to use MySQL’s search features, you need to have all the searchable data on your site stored in MySQL tables.
Using Google Custom Search
Google Custom Search is relatively easy to add to your page, and does not require you to be using MySQL. You simply copy and paste some code that google generates for you when you sign up for the service. This is clearly an advantage, since it will make your entire site searchable, not just those pages that use MySQL. However, there are two disadvantages: The search bar is branded with the Google logo, and when a user performs a search, they are taken to Google’s web site, which means they are taken away from your website. Click here to see an example of Google Custom Search in action.
July 21st, 2009 §
Many of you are building portfolio sites for your final projects. Many portfolio sites share the same requirements and constraints, so I encourage you to exchange information about sites you like, and techniques you’re using on your blogs for all to see.
A number of Content Management Systems (CMS’s) that claim to make the design and development of portfolio sites as painless as possible. CMS’s generally make it possible for developers to publish content on the web without writing any code.
Be warned: regardless of what they claim, learning any CMS requires significant time and energy – sometimes an equivalent amount as learning to code from scratch. So unless the out-of-the-box CMS looks exactly like what you wanted it to look like, or provides features you would never be able to do on your own, just beware that you will probably need to learn the intricate details of each of these CMS’s before you can adequately customize it to suit your own site design.
With that warning, here are some popular CMS’s that have been recommended to me for use with portfolio sites. They all come with default themes that create decent-looking sites with no coding. Each of these CMS’s should have either a demo or examples of real live sites that use them. If nothing else, browsing through the examples linked from these sites may help you brainstorm what you want your own portfolio site to look like:
In addition, each of the major multi-purpose PHP-based CMS’s can be customized to be suitable for a portfolio site. These are the most popular CMS’s, and they might be overkill for a simple site that just requires a few pages. However, each allows you to install plugins or add-ons that add functionality that might be useful for such a site:
April 26th, 2009 §
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.
April 18th, 2009 §
Your assignment today is to complete a blog with comments. This should be based off of your assignments from last week, where you created a blog where users were required to register and login before they could post to the blog.
There will be changes to two pages in your blogs.
index.php
The home page will show all the blog posts, as well as all of the comments associated with each blog post. There will also be a link to “Add a comment” to any blog post.

Home Page
I recommend you study what I wrote about SELECT statements in an earlier post, especially the last bit about joining two tables together. It would be nice if you could join the users and posts tables together when doing a query for all the blog posts to show on the home page. This would allow you to get all the data about the post, as well as the data about the user who posted it in one fell swoop. Something like this:
$myQuery = "SELECT abloombert_posts.*, abloomberg_users.username FROM abloomberg_posts, abloomberg_users WHERE abloomberg_posts.user_id = abloomberg_users.id ORDER BY created DESC";
$result = mysql_query($myQuery); //run query
if ($result) {
//loop through each post
while ($row = mysql_fetch_array($result)) {
//get this post's id, title, body, and username of the user who posted
$userId = $row['user_id'];
$username = $row['username'];
$title = $row['title'];
$body = $row['body'];
$created = $row['created'];
//etc...
}
}
The link to “Add a comment” has to somehow pass the id of the blog post to which the comment should be associated to the comment.php script. This can be done by passing that data in the url of the link. For example
<a href="comment.php?post_id=<?php echo $postId ?>">Add a comment</a>
comment.php
The comment page will have a form that users can fill out to submit a comment. This page should show the user the title and author of the blog post they are about to comment on.

Comment Page
In other words, this page will have to take the post_id that was passed to it from index.php, and do a read from the posts database table to get the information for the post with that id.
You will probably use code similar to this:
$postId = $_REQUEST['post_id']; //get the post id that was passed from index.php
$myQuery = "SELECT * from posts where id={$postId}";
$result = mysql_query($myQuery);
//... loop through each row of the results and get the data about this post
The form where the user fills in the comment will also need to pass the post_id to the script that processes the comment so it can store the post_id in the comments table.
Assuming you have the blog post “id” field in a variable called $postId, the code for the form will probably look something like this:
<form action="process_comment.php">
<input type="hidden" name="post_id" value="<?php echo $postId ?>" />
<label for="comment">Comment:</label>
<textarea name="comment" id="comment"></textarea>
<input type="submit" value="Post Comment!" />
</form>
Notice the hidden input that has the value of the post’s “id” field. This means that when the user clicks the submit button, the form sends two pieces of data to the process_comment.php script: the post_id and the comment the user entered.
process_comment.php
The script that processes the comment the user entered must take the blog post id, the id of the current user, and the comment the user entered, and store this info in a new row in the “comments” table.
To get the necessary data, you will need to retrive it from the $_REQUEST and $_COOKIE variables. The post_id and comment will be in the $_REQUEST variable, and the user_id will be in the $_COOKIE variable, assuming you stored it in a cookie when the user logged in.
$userId = $_COOKIE['user_id'];
$comment = $_REQUEST['comment'];
$postId = $_REQUEST['post_id'];
So make sure you are storing the user’s id in a cookie when they login, or else this obviously won’t work.
Once you have that info, put together a SQL query that inserts this data into a new row in the “comments” table.
$myQuery = "INSERT INTO abloomberg_comments (user_id, post_id, comment) VALUES ({$userId}, {$postId}, '{$comment}')";
$result = mysql_query($myQuery); //run the query
Then redirect the user back to the home page.
header("Location: index.php");
April 18th, 2009 §
If you remember way back in Class 5, we saw examples of using JQuery, the Javascript framework. Some of those examples used JQuery to create event handlers for mouseover, mouseout, page load, etc.
In particular, the show/hide example showed how to change the contents of the page in response to user events. In this case, we were making an element show up or disappear depending on user actions. This is basic DHTML.
You can think of AJAX as doing something similar. With AJAX we often make things show up on the page that were not there before. The difference between our old show/hide example and an AJAX version is that the content that shows up on the page using AJAX would not be pre-loaded on the page, as it is in the show/hide example.
AJAX is a way of making requests to the server without reloading the entire page. You can think of it as being a behind-the-scenes way of making requests to the server.
Sometimes AJAX is used to load new content to display on the current page. Other times, AJAX is used to autotmatically submit form data to the server without requiring the user to actually submit a form in the normal way.
Here are the AJAX examples we covered in class today:
April 16th, 2009 §
Now that we’ve established what object-oriented programming is in theory, it will be useful to go through how this theoretical idea is actually implemented in PHP.
The skeleton of a class definition
The following is a bare-bones definition of a Dog class in PHP. This code would go into a file called Dog.class.php:
<?php
//file: Dog.class.php
class Dog {
public function __construct() {
}
}
?>
This class, as it currently stands, has no properties, no methods, and is basically useless. But it shows you the bare minimum amount of code necessary to define a class in PHP.
The __construct() method is a special type of method that is automatically called by PHP when an instance of the class is created. This is known as a “constructor function”, and is generally used to do some initial setup of the properties of the object that is being created.
For example, let’s say we have another script, index.php, which creates a Dog object:
<?
//file: index.php
require_once("Dog.class.php"); //include the Dog class definition file
$sparky = new Dog(); //create a new Dog object and store it in a variable
?>
When the script runs the “new Dog()” command, this tells PHP to create an object of type Dog. PHP creates this object, and then calls its __construct() method automatically.
Adding properties
Let’s now try to do some basic setup of the Dog object when it is created. Most likely, we would conceptually want to give the Dog a name at the time it is created.
To do this, we need to give the Dog class a “name” property, and then allow the constructor code to set that property to some value when the object is created.
Here is the updated Dog.class.php file:
<?php
//file: Dog.class.php
class Dog {
private $name;
public function __construct($dogName) {
$this->name = $dogName;
}
}
?>
The code to create a new Dog object would now look something like this:
<?
//file: index.php
require_once("Dog.class.php"); //include the Dog class definition file
$sparky = new Dog("Sparky"); //create a new Dog object and store it in a variable
?>
The first thing to note is the “private $dogName” code in the updated Dog class definition. This declares a “name” property of any Dog objects. Note that we define this property in the class definition file, but it actually comes into use for Dog objects created from that class. This is an important distinction: you define things in the class file that you intend to use for the objects created from that class. Sometimes these properties are called “instance variables” because they apply to all object instances of the specified class.
The keyword “private” indicates that any property or method will only be accessible to code within the class definition itself. Any code outside of this class definition will be ignorant of the existance of the “name” property of any Dog. This is an example of the concepts of abstraction and encapsulation: the inner workings of the Dog class can be hidden from world outside world.
The alternative is “public”, which we see being used in the constructor function, but can be used for any property or method that you want to make accessible to code outside of the class definition.
In index.php, we have supplied an argument to the constructor function by putting the word “Sparky” inside the parentheses of the “new Dog()” command. You’ll recognize that this is not so different from how we pass arguments to regular functions in PHP and Javascript.
PHP automatically calls the __construct() function when we declare “new Dog()”, and the constructor function now puts the word “Sparky” into the variable called $dogName.
The following line of code in the constructor function then modifies the $name property of the Dog object so that it too has the word “Sparky” in it:
$this->name = $dogName;
The $this keyword is a special variable that refers to the current object. It can only be used inside of a method in a class definition file. It refers to the current instance of the class. In this case, when the code is run, $this refers to the Dog object that we are calling “Sparky”, and not to any other Dog object that may exist at that time.
The syntax “$this->name” is how you would refer to the “name” property of the current object. You can use similar syntax for any property or method that is encapsulated inside of an object. For example, $this->doSomething() would call the doSomething() method of the $this object.
So we have effective created a Dog object, and set its name property to be “Sparky”. But what use is that?
Accessor methods
Obviously, you want to make it possible to use that “name” property in some way. Let’s say we want to be able to echo the name of the dog we created somewhere in our index.php script. We need a way to access this “name” property from outside of the class definition file.
But I’ve already said that the “name” property is “private”, and therefore not accessible to any scripts outside of the class definition file. So how do we access it?
The answer is that we have to create what are known as “accessor methods” for our class. By convention, an objects properties are not directly accessible to code outside of the class definition, so we supply public methods to get and set those property values (known sometimes as “getter and setter functions”.
Our updated Dog.class.php file will now look like this:
<?php
//file: Dog.class.php
class Dog {
private $name;
public function __construct($dogName) {
$this->setName($dogName);
}
public function getName() {
return $this->name;
}
public function setName($dogName) {
$this->name = $dogName;
}
}
?>
And our index.php file will echo out the dog’s name like this:
<?
//file: index.php
require_once("Dog.class.php"); //include the Dog class definition file
$sparky = new Dog("Sparky"); //create a new Dog object and store it in a variable
echo $sparky->getName();
?>
We have thus created accessor methods for the “name” property. These are two new public methods in the Dog.class.php file: one to set the “name” property of the Dog object, and another to get the “name” property of the Dog object. It is important that they are both “public”, so they can be called from index.php. And the “name” property itself is “private”, and therefore not directly accessible from the code in index.php.
Note that I have also updated the constructor function so that it too calls the setter method, rather than duplicating the same code found in that method.
The script in index.php now creates a new Dog object, and then outputs the name property of that object by calling its getter method.
Finishing the example
Now let’s finish this example by adding another property and a few new methods. We’ll add an “age” property, as well as the getter and setter methods for that property. We’ll also add a “bark()” method that will just output some text. And finally, we’ll add a static method, which we’ll discuss below.
Here’s the updated Dog.class.php:
<?php
//file: Dog.class.php
class Dog {
//declare private variables that will be accessible from scripts outside of this class
private $name;
private $age;
//function __construct is a "constructor function", which means it is called automatically when a new object is created
public function __construct($name) {
$this->name = $name;
}
//a function that tells the current Dog object to bark...
public function bark() {
echo "<p>{$this->name} says 'woof'</p>";
}
//this is a setter function - it allows you to set the value of a private property of the current object
public function setAge($dogAge) {
$this->age = $dogAge;
}
//this is a getter function - it allows you to get the value of a private property of the current object
public function getAge() {
return $this->age;
}
//example of a static function - these are not dependent on any particular instance of this class
//in fact you CANNOT use the variable $this in a static function, because there is not current object to refer to
public static function scratch() {
echo "<p>Oooo that feels good</p>";
}
} //end class
?>
And the updated code from index.php:
<?
//file: index.php
require_once("Dog.class.php"); //include the Dog class definition file
$sparky = new Dog("Sparky");
$sparky->setAge(5);
$petie = new Dog("Petie");
$petie->setAge(3);
$sparky->bark(); //call the bark function of the Dog, "Sparky"
$petie->bark(); //call the bark function of the Dog, "Petie"
//echo $sparky->getAge();
Dog::scratch(); //call the static "scratch" method of the Dog class
?>
This script now creates a Dog object and gives it the name “Sparky” and sets its age property to be 5. Then it creates a second Dog object, gives it the name “Petie”, and sets its age property to be 3.
The code then calls the bark() method of both Dog objects. Each Dog object will run its own bark() method. Each object will run this command:
echo "<p>{$this->name} says 'woof'</p>";
And since each object has a different value in the “name” instance variable, they will output different things. Sparky will echo “Sparky says woof”, while Petie will echo “Petie says woof”.
Static vs. instance methods
Finally, we call the static method scratch(). The syntax to call a static method is this:
Dog::scratch(); //call the static "scratch" method of the Dog class
The double colon, “::” indicates that the scratch() method is not a method of any particular Dog object (i.e., not an instance method), but is rather a method of the class itself. In otherwords, an object does not need to have been created in order to call this method.
We can call this method on a particular object, like we do with any other method of an object:
$sparky->scratch()
But the only reason to make a method static is so that we don’t have to have a particular object in order to call it. So we usually call static methods directly from the class itself instead:
Dog::scratch();
As we saw, Sparky’s bark() method does something slightly different from Petie’s bark() method. Static methods are called static because they are never dynamic like this, and they never refer to the properties of a particular object instance.
Whereas the processing of the bark() method depends on the $this->name property of the current object, static methods cannot ever use the $this keyword because they do not refer to any particular object at all. They are usually used for general utility methods that never need to change depending on context. Hence the keyword static.
A slight variation on this example code is available here.