Monday, November 12, 2007

Planning PHP Projects

Planning PHP Projects

The biggest problem I see is most PHP scripts is a lack of structure and organization. What heralds this is a lack of planning. Many PHP programmers don't think through projects before they dive into the coding. This is a tutorial I wrote 3-4 months ago. I have learned a lot since then, especially concerning OOP techniques. I am currently working on a new version, however, I considered it complete enough to be posted here. Please comment so that the next revision of it will improve!

Planning?

When coding a large, or even moderate or small size, project the most important thing is planning. When you get to the level in which you will, without a tutorial or book, be programming something on your own you know you can do the coding. You know you can connect to databases, print things to the screen, create basic classes, etc. However, what many people do when they reach this stage is skip the planning process and dive right into the coding procedure.
While improvisation during programming is good, if you want a streamlined application that shows consisten programming practices, is easy to update, and is simple to code, the best tool is a plan. If you have a database structure, if you have outlined the structure of your code, if you know exactly what you want your application to do, programming is a breeze. Succesful planning is not treated in most books or tutorials, because in the books and tutorials the author does the planning for you. But once you are creating an application on your own, you must plan and look ahead.
Hopefully, this tutorial will help you understand how to plan an application. It will be, eventually, a two or three part series that will address planning features, planning classes, database structure, templating, message abstraction, and hopefully some basic coding technique. It is not intended to teach you how to code PHP, instead it is intended to show you how to structure and plan your code well.
Enjoy! I have utilized these practices while creating programs, and when it comes to adding features and creating new versions, planning and good code structure is the most important part of the process.

Planning the Program Features

The basic need is to understand what your program will be doing. The example I will use throughout is a basic guestbook application. Initially, what you want to do is figure out the basic features that will contain everything else. For a guestbook application, I would probably outline something like this:
1.) The ability to view entries 2.) The ability to post entries 3.) Administration 4.) Templating
How did I arrive at these features? I looked at other guestbooks and saw what they had and tried to categorize it. I then looked to see what they didn't have that I would like and added that in and categorized it. The whole idea is just to have the roughest outline of the most basic features.
Now we can try to flesh it out. Brainstorm what you think a guestbook (or whatever your application is) should have. I figured out something like this:

  1. Viewing entries
    1. Default view is 10 entries at a time, but allow people to view more
    2. Maybe JavaScript expanding and collapsing of entries?
    3. Transfer BBCode to HTML
  2. Posting entries
    1. Place a link on every page to the posting page
    2. Required fields: name, entry
    3. Optional fields: e-mail, website, IM usernames, location
    4. Hidden fields: IP address (for banning spammers)
  3. Administration
    1. Editing posts.
    2. Deleting posts.
    3. Banning people by IP (if someone consistently spams your guestbook)
    4. Bad word filter settings?
    5. Basic settings -- site name, guestbook name, site URL, database user/pass/database/host
    6. Admin response to entries
    7. Easy modification of templates and addition of new ones through the Admin panel
    8. Login and authentication, obviously
  4. Templating
    1. Basic replacing of {VARS} with values from DB or flatfile
    2. If you don't want to code it yourself, systems such as Smarty and patTemplate are excellent and easy to use

This is by no means complete, but can you see that once a list such as this is available, programming is made that much easier? When I begin to write the script, I can see exactly where I want to go. I know how the various features will connect, and I understand the purpose behind what I am doing.

Planning the Coding

Here is where you decide how the backend/coding will work. Do you want to run it off a database? If so, which one (MySQL, SQLite, PostGreSQL, MS Access, etc.). Or do you want to do it flatfile, if so, how? And in general, what will the structure of your code be? My advice for large applications can be summed up in three words: Object Oriented Programming.
The best way to program a large PHP program -- and indeed any large program (and in fact many small ones) -- is to use OOP. Think of it this way. Say you have a forum script and it is OOP. You have a class named view. Inside that, you have a function called viewThreads(); that accepts a few different values to tell it which threads to view. Now, suppose you have a page titled viewforum.php and at one point you want to view certain threads. So you call $view->viewThreads(); . You also have a search function, and in it you want to view certain threads. Well, you call the same function. Now say you want to change the programming for viewing threads. If you didn't have OOP, you'd have to open up every file that views threads and change it. With OOP, you just change the class. You could just do a bunch of functions, but the use of OOP is that a class is more organized, can do something automatically every time it is called, and can be easily extended. (Not to mention more advanced class passing and handling functions not introduced until PHP 5)
So, you've decided to use classes. Or rather, I've decided that you will at least for this tutorial. What classes will you have, and what will each do? If you are going to use a database you might want a database class to handle connections. Then you'll want an entry class that handles viewing and adding entries. An administration class to handle administration, and a templating class. I would recommend, for a large project, to use a templating class like Smarty or patTemplate. These will save time and add powerful features you may not want to spend time programming yourself. The point is that you are coding a guestbook, not a template system. So use a template system, and get on with the guestbook. (Or forum, or CMS, or whatever.)
After you've decided on your classes, a good idea is to outline the classes and the functions in them. I'll give you an example here:
PHP Example: (!)

class Entry {

function Entry() {
//This function will include and initialize a global variable containing the database class
//Notice the class is named the same as this function. That means this function will run
//when the class is called
}

function view( $num, $start ) {
//This class will access the database and get the number of entries specified in $num, starting at the entry with the ID of
//$start
}

function post( $name, $email, $website, $aim, $yim, $msn, $icq, $title, $post ) {
//This class takes the information placed in it and adds it to the MySQL database
}

}

Obviously, more functions are needed for the class to work, and the coding is yet to be done, but the basic structure is there. Do this for all your classes and the work will be greatly simplified.
I haven't done everything necessary for planning -- there are still classes to plan out and stuff like that -- but this is an example of how it should be done. For your CMS or forum, or -- indeed -- guestbook, using this type of planning and structure will make your life easier, your coding better, and is the way to go if you are coding even a relatively smallish project.

Coding the Program -- Methods to make Coding Easier

Templating

It is extremely important to start out with a template and templating system. Everything you code will be built around this, so don't leave it to the end. I would recommend using the Smarty templating system, but if that fails go for patTemplate (another good system). But whatever you choose, or if you code it yourself, get it working before anything else. Because the template system is the main thing the end user will see and use, you need it to work. Not much about the structure, but one thing I would recommend doing is creating a template management class. Not a templating class that does the actual work, but one that manages it. So, say you are using Smarty, you would do something like:

PHP Example: (!)

class Template {

function Template( ) {
require_once("Smarty.php");
$smarty = new Smarty();
}
function showTpl( $tpl ) {
$smarty->display( $tpl );
}
}

You could do more, but even just this means that you can easily include the beginnings and ending of the Smarty code into every page without having to write it over and over.

Abstraction

What's abstraction? Well, it could be used as in "database abstraction", which means that this is a script that lets you use tons of different database utilities (MySQL, SQLite, PostGreSQL, etc.) without changing your code. But it also means something else. It means easy coding -- or at least easier. Look at it this way -- suppose you want something all over your pages to be the same. Well, either you can just write everything exactly the same over and over, or you can create another page that has the values you need and can be included into each page. The basic - or easiest - method of doing this is seen in sites that have several pages -- navbar.php, header.php, footer.php, etc. -- and include those pages into one that has the content. This type of thing is rendered obsolete by use of Smarty -- but you can go further -- especially for a large program.
One way is to create a messages class. "What messages?" you say. Well, whenever you do a program at some point you'll want to show a message -- whether it's "Thank you, your guestbook entry has been added to the database" or "Sorry, wrong username" -- and having a file like this will make it easier to have the same messages appear between scripts. An example script of this type would be:
PHP Example: (!)


class msg {

function msg( $num ) {
$start = "<p style="font-color:red">";
$end = "</p>";
$message = $start;
switch( $num ) {
case 1:
$message .= "Wrong username";
break;

case 2:
$message .= "Wrong pass";
break;
}
$message .= $end;
echo $message;
}
}

If you have a login page, you would access it like follows:
PHP Example: (!)

include "msg.php";
if( $pass != "arr" ) {
$msg = new msg( "2" );
}
elseif( $user != "user" ) {
$msg = new msg( "1" );
}

Obviously, that is not the correct way to create a login system, but you see how the message system could help. I included it as an example of a type of system that makes coding easier. So wherever you have a login, or somewhere where someone has to supply a username or password, just use the class and if you want to change the wording everywhere you have just one file to edit!
Not only that, if you need a new message, just add a new case inside the class, and then call it as you would the others. No need for echos, s, etc. If you are using a template system you can't put the templating for the message inside the class as I did, but if your template system supports this you can create a hidden sub-template that gets shown if the message class is called. Just 3 more lines of code in the message class is necessary for this using the Smarty system.
Now do you start to see what I mean by abstraction?
The only other important thing to cover in this is structure. Indent everything. Add a tab for each function in a class, and a tab for all the code inside that function, loop, or if statement.
And. . . COMMENT. Comment everything. You may think you'll know what you meant by a certain bit of code, but after a couple of months when the time comes to update. . .you'll be happier if you commented everything.

System!

If you look at this tutorial, you'll see my biggest point. System makes coding easier. If you have a system, anything can work, and probably will work much more easily. De-bugging is easier if you have different classes, and if you use templating systems along with classes your actual code will look cleaner and will update more easily.
Establish ways that you do certain things, and do things that way in every piece of code. Ever since I started thinking about this and programming using classes and tools like this my coding has taking huge leaps and bounds. Coding sloppily, on the other hand, may take less time initially (cutting out the planning and classes and suchlike), but when you go back to add new features, change a message, or change the template, you will pay for it.
If you are interested, try taking a simple application, and if you want to, try a bit of coding within the OOP environment using Smarty and a message class that employs Smarty's hidden/shown features. Just try out what I've outlined and see what you think. I practically guarantee that it will be much simpler after the planning stage to start programming, and that using classes for everything will make your life tons easier. If you don't know how to program OOP, check out a few tutorials (I will be writing one soon myself). It is worth the time.
There's obviously more to it that this, however, this tutorial covers some of the basic methods of planning. If you want to know how to design a database, look at the LAMP tutorial on this website. You can even find a tutorial here on message abstraction. However you do it, planning and system help. Hope this tutorial helped you

No comments: