*

2005 / December 15th/ Useful PHP coding tips for writing maintainable code

Disclaimer: This guide is intended for those fairly new to coding and who like to dabble with programming—not those who wish to program professionally. There is a lot of terminology I’ve left out, and a lot of not-so-perfect practices. This guide aims to put people on the right road, not offer a perfect solution.

It’s funny, but the best thing that ever happened to my PHP coding was to play with Rails. I’ve learned a great deal from the framework, and now when I have to go back to PHP, I can write somewhat maintainable code. Amazing - I know. I thought I’d share some tips I’ve learned along the way.

Comment on your comments

I know, I’m sure you hear this everywhere–but seriously–comment! Comments in your code can help you remember what was once second nature, but now forgotten. Every single time you create a new function, declare the input variables and explain example inputs. Is $sort supposed to be ‘ASC’ or is it supposed to be ‘alpha’ ? Both make perfect sense, and may seem obvious to you while coding–but maybe a month down the road it won’t be.

Use arrays as often as possible

Arrays are probably the second most underused feature in PHP to a newcomer to the coding world. Arrays are awesome. Learn them. Love them. Don’t forget that the keys to an array ($array[key] = value) are just as meaninful as the array itself! Browse through the Array page on php.net for a while and find out some of the cool things you can do. Also, don’t forget about the control foreach($array as $key => $value) as it’s immensely useful in cycling through data.

Here’s a great method I use all the time for including files using arrays:

$includes = Array(
  'app/categories.php'
  'app/products.php'
);

foreach($includes as $include)
  {
    require_once($include);
  }

Objects are a good thing

In my opinion, objects are the most underused feature in PHP to newcomers. I know they seem extremely scary at first, but if you do a few tutorials using them you’ll see they’re really not all that bad. The biggest hurdle I had to overcome was figuring out how I was actually going to use them.

Here’s a good example that I think serves to show the best use of objects in every-day scripting. First, let’s start off with a little bit of build-up:

class Base
  {
    function find_all($input)
      {
        // Code here that performs a database query to find all
      }
    function find_one($input)
      {
        // Code here that performs a database query to find one
      }
  }

class Product extends Base
  {
    // stuff in here
  }

class Category extends Base
  {
    function products($input)
      {
        $product = new Product;
        return $product->find_all( Array('category' => $this->category_id) );
  }

Now, you can call something like this later:

$category = new Category;
$category = $category->find( Array('id' => 5) );
foreach($category->products() as $product)
  {
    echo $product->name
  }

Basically, there are two major benefits to Objects (to a newbie, at least):

  1. Inheritance - If you noticed, there isn’t a function find() for the Category object, but you can still perform call it. This is because Category extends Base - and Base has a find() function. Category inherits all the properties and functions from Base.
  2. Modular Code - By separating your code out, you can reduce repetition and make global changes easier. Instead of replacing 15 different instances of find_something_function, you have one find_all function you can change to effect the entire app.

Function input variables

I used to just add input variables to my functions until they got out of control. It wouldn’t be uncommon for me to have something like:

function get_stuff($id, $sort, $limit, $style, $output){
.... 200 lines later ...
$var = get_stuff(5, 'ASC', 15, 'html', false) // wait... was order the second or the fifth variable?

That kind of coding gets old really quick. A great solution is just to always have one input: an associative array. This array can give you meaningful variable names and you never have to remember orders again! Here’s an example:

function get_stuff($input)
... 200 lines later ...
$var = get_stuff( Array('id' => 5, 'output' => false, 'sort' => 'ASC', 'limit' => 15) ); //

Then you can just grab the values inside the function as $input['sort'] or $input['limit']. Amazing improvement in maintainability. With a good helper function written, you could even easily have default values lying in an existing array, and merge the input array with the default array.

Start with a good directory structure

Nothing’s worse than have 30 different PHP files all independently including and requiring one another. It’s a recipe for disaster. If you’d like a good template to start on, I’ve included a zip file that contains two different directory structure templates. Consider these “ultra-lightweight” frameworks to get you started in the right direction. Download them here.

The basic idea is to always keep code and HTML separate. There’s one folder for procedural code (phpprocframework) for those of you too timid to delve into object oriented and MVC-style coding. The other folder is for MVC fanatics (phpoopframework).

Another quick tip on file naming: always include the name of whatever you’re doing in the file name, not just the directory. While browsing through a filesystem, /app/controllers/categories/controller.php may make perfect sense. But when you have all of these files open in a text editor, all you can see is “controller.php, controller.php, controller.php” Underscores are my prefered naming convention: categories_controller.php.

Always call one file and include the content, don’t call many files and include the header/footer

The first introduction many people have to Server Side Includes is by including a header and footer into a page. I’ve got to tell you, this is the wrong way to go about things. It’s much better to have one wrapping file that includes the middle content. This also alliviates a lot of the include path woes that many newbies face.

Doing this allows you to control your codebase from one point of entry instead of multiple points of entry. Never again do you need to wonder whether a file is included or not - you only have to edit one file.

The wrong way to do it:

<?php include "header.php" ?>
<h1>This is a body page!</h1>
<?php include "footer.php" ?>

The right way to do it:

<!-- Header HTML here -->
<?php include "body.php" ?>
<!-- Footer HTML here -->
A word from the sponsors. Advertise with Warpspire

24 Comments

comments feed

  1. Gravatar
    Marco

    December 16th | #

    Most of the stuff that’s so nice about Rails is the fact that it forces MVC and OO. In PHP you can easily produce ’shite’ by coding loads of loosely coupled procedural scripts instead of a real application. I refuse to see the revolutionary aspects of Rails compared to PHP that some ‘developers’ think there are. They simply never built an MVC application. It can be done in PHP. Very well even. In fact it could already be done when Rails didn’t even exist yet.

    I’m not saying Rails isn’t nice, I’m just saying you can do everything ‘Rails style’ with PHP if you show some discipline ;)

  2. Gravatar
    Kyle

    December 16th | #

    Marco,

    If you delve far enough into rails you’ll see the benefits immediately. Ruby’s fully OO architecture allows so much more than you could ever do with PHP. It’s not easy to explain off-hand, but I guess you’ll just have to play with it if you want.

    I fully agree PHP can do MVC, and it does it well sometiems. It’s just that it’s not as clean, or beautiful as Rails’ implementation of Ruby. It never will be. PHP was a procedural scripting language with OO tacked on, whereas Ruby is a OO language to the core. I might consider wriitng a post soon explaining a bit of the differences from my point of view (given I’m not a trained programmer, I’m just a designer).

  3. Gravatar
    Eddy Bones

    December 16th | #

    Good article, Kyle. Those are great tips for those delving into programming. When I started out I didn’t learn it the right way, and PHP didn’t help put me on track. I’m just getting into the habit of classes and inheritance now, so those are great for people to learn right off the bat. It’s better to work hard to learn it right the first time rather than work hard to learn it wrong and then work harder to unlearn the bad stuff.

  4. Gravatar
    Mike P.

    December 23rd | #

    Some good tips for people new to programming and PHP.

    I’d be careful about what you say about MVC and procedural code, though, as it is a bit misleading.

    One can apply the principals of MVC to procedural code quite easily and enjoy the same benefits. I tend to encourage new learners, who often don’t get into OOP right away, to structure their apps the MVC way. Or better, Harry Fuecks provides some timely thoughts about MVC, in particular at the very end “Back to Beyond” and this bit:

    Model?those functions that wrap calls to your db
    View?the templates / scripts that output HTML
    Controller?the stuff that examines variables like $_GET and $_POST and works out what to do next

    Starting from that point as a loose definition, one can use these principals with or without OOP and reap some of the benfits that Harry outlines in the “Back to Beyond” section.

  5. Gravatar
    Mike P.

    December 23rd | #

    Hmm.. You may want to explain what ‘basic html’ is allowed in the comments ;-) That blockquote was suppose to be a list… For clarity:

    Model?those functions that wrap calls to your db

    View?the templates / scripts that output HTML

    Controller?the stuff that examines variables like $GET and $POST and works out what to do next

  6. Gravatar
    Kyle

    December 23rd | #

    Weird Mike, it shows to me that you put in blockquote tags. Maybe you got caught up by Markdown somewhere along the line?

    I do agree that MVC does not neccecarily imply OOP. However, for the purposes of 99% of developers out there, it does. Chances are, if you’re looking into MVC there’s an extremely high chance that any examples you run into will consist of OOP-based frameworks.

  7. Gravatar
    williamwdoyle

    December 28th | #

    these are some great tips…. the only question i had was about your includes for headers and footers. I am not disagreeing with you that adding the variable content probably saves some of the hassles of directory locations for includes files, etc., but isn’t the whole point of having header and footer includes to reduce the redundancy of placing the same information in web page after web page? I have coded a couple of web sites with header and footer includes and saved myself a bunch of time from copying and pasting and with good results. I am just curious about your take on it….

  8. Gravatar
    Jatinder

    June 28th | #

    Nice tips. Especially the “Function input variables” one.

    But I don’t agree with the last part about not including the header.php or footer.php files.

    The main motive behind including the header and footer files is that most websites use the same HTML code throughout for their header and footer. This code is wrapped up into header.php and footer.php code and included wherever necessary.

    If the header of the website needs some changes, I will just need to modify the header.php instead of applying changes to each and very page.

    I also fail to see how including just the body.php “alliviates a lot of the include path woes”

  9. Gravatar
    Kyle

    June 29th | #

    Jatinder: The whole point is that you have one file for both the header and footer. Take a look at how wordpress works to see what I mean.

  10. Gravatar
    Raam Dev

    January 25th | #

    Great tips! I’ve already discovered, the hard way no doubt, every single one of the mistakes you mentioned above!

    Awesome advice on function input variables… I knew that sample “wrong” function looked horridly familiar. :)

  11. Gravatar
    Tristan

    April 7th | #

    Hey Man,

    Thanks for the great info!!!! Keep up the good work. You Rock!!!!

    -Tristan

  12. Gravatar
    Bill

    May 7th | #

    Very+good+web+site%2C+great+work+and+thank+you+for+your+service.

  13. Gravatar
    Hillary

    May 11th | #

    Thank%2Byou%2Bfor%2Byour%2Bsite.%2BI%2Bhave%2Bfound%2Bhere%2Bmuch%2Buseful%2Binformation…e

  14. Gravatar
    name

    July 2nd | #

    d450.txt;d451.txt;d452.txt;d453.txt;d454.txt

  15. Gravatar
    name

    August 8th | #

    15.txt;5;7

  16. Gravatar
    Mendy

    September 2nd | #

    with anything be bothered I can’t lately. ,

  17. Gravatar
    Sasha

    September 2nd | #

    anything can’t with be I bothered lately. ,

  18. Gravatar
    Erich

    September 2nd | #

    it is. how That’s ,

  19. Gravatar
    Bush

    December 6th | #

    It\’s a great and valuable site!o

  20. Gravatar
    Bill

    December 7th | #

    You have built a good website

  21. Gravatar
    Bill

    December 7th | #

    Wow!!! Good job. Could I take some of yours triks to build my own site?s

  22. Gravatar
    Anonymous

    January 9th | #

    fsd

  23. Gravatar
    Melissa

    March 20 | #

    Excellent+web+site+I+will+be+visiting+oftenI

  24. Gravatar
    Antonis

    April 2nd | #

    Very nice website.

    I have one comment. You said not to use include for header but instead add it as html and include the body. But what happens if in the middle of a 50 pages project you realise that you need to add a javascript library to your header. Do you go through all 50 pages and add it? Or what if you want to change some meta of your header that should apply globaly to the site?

Make a Comment

don’t be afraid, it’s just text

Comments are parsed with Markdown. Basic HTML is also allowed.