30 PHP Best Practices for Beginners

30+ PHP Best Practices for Beginners

PHP is the most widely-used language for programming on the web. Here are thirty best practices for beginners wanting to gain a firmer grasp of the fundamentals.

Editor’s Note: The “Best Practices” series has been my baby for three articles now. However, due to my focus on the CI video series, I’ve decided to hand off this next entry to Glen. Having said that, I’m not very good at keeping my mouth shut! I thought it might be fun to sporadically add a few rebuttals to his tips. I hope he doesn’t mind!

1. Befriend the PHP Manual

If you’re new to PHP, then it’s time to get acquainted with the awesomeness that is the PHP manual. The PHP manual is incredibly thorough and has truly helpful comments following each article. Before asking questions or trying to figure out an issue on your own, save some time and just head straight to the manual. Odds are the answer to your question is already nestled in a helpful article at the PHP.net site.

2. Turn on Error Reporting

Error reporting in PHP is very helpful. You’ll find bugs in your code that you might not have spotted earlier, as not all bugs keep the application from working. There are different levels of strictness in the reporting that you can use, but E_ALL will show you the most errors, critical and warnings alike.

Once you’ve gotten your application ready for production, you’ll want to turn off error reporting, or your visitors will see strange errors that they don’t understand.

3. Try an IDE

IDE’s (Integrated Development Environments) are helpful tools for any developer. While they’re not for everyone, an IDE definitely has its place. IDE’s provide tools like

  • syntax highlighting
  • code completion
  • error warnings
  • refactoring (reworking)

And many other features. There are plenty of great IDEs out there that support PHP.

Try an IDE

4. Try a PHP Framework

You can learn a lot about PHP just by experimenting with PHP frameworks. Frameworks like CakePHP or CodeIgniter allow you to quickly create PHP applications, without having to be an expert with PHP. In a sense, they’re almost like PHP training wheels that show you what a PHP application should look like, and show you valuable programming concepts (like separating the logic from the design, etc.).

Rebuttal: I personally wouldn’t recommend that beginners use a framework. Learn the fundamentals first. :)

5. Learn the DRY Approach

DRY stands for Don’t Repeat Yourself, and it’s a valuable programming concept, no matter what the language. DRY programming, as the name implies, is ensuring that you don’t write redundant code. Here’s an example from Reinhold Weber:

Learn the DRY approach

This code…

$mysql = mysql_connect('localhost', 'reinhold', 'secret_hash');
mysql_select_db('wordpress') or die("cannot select DB");

now with the DRY approach:

$db_host = 'localhost';
$db_user = 'reinhold';
$db_password = 'secret_hash';
$db_database = 'wordpress';
 
$mysql = mysql_connect($db_host, $db_user, $db_password);
mysql_select_db($db_database);

You can read more about the DRY programming principle here and here.

6. Indent Code and Use White Space for Readability

If you don’t use indentations and white space in your code, the result looks like a Jackson Pollack painting. Ensure that your code is readable and easy to search because you’ll most definitely be making changes in the future. IDEs and advanced text editors can add indentation automatically.

7. “Tier” your Code

Tiering your applications is nothing more than separating the different components of the code into different parts. This allows you to easily change your code in the future. NETTUTS writer Jason Lengstorf has written an excellent article on how to tier your PHP applications for easier maintenance.

8. Always Use <?php ?>

Often times programmers try to take shortcuts when declaring PHP. Here are a few common ones:

<?
    echo "Hello world";
?>

<?="Hello world"; ?>

<% echo "Hello world"; %>

While these do save a few characters, all of these methods are depreciated and unofficial. Stick with the standard <?php ?> as it will be guaranteed to be supported in all future versions.

9. Use Meaningful, Consistent Naming Conventions

Naming this isn’t just for your own good. There’s nothing worse than trying to find your way through some other programmer’s nonsensical naming conventions. Help yourself and others by using names that make sense for your classes and functions.

10. Comment, Comment, Comment

Aside from using white space and indentations to separate the code, you’ll also want to use inline comments to annotate your code. You’ll thank yourself later when you’re needing to go back and find something in the code, or if you just can’t remember what a certain function did. It’s also useful for anyone else who needs to look over your code.

11. Install MAMP/WAMP

MySQL is the most popular type of database to use with PHP (though it’s not the only one). If you’re wanting to set up a local environment to develop and test your PHP applications on your computer, look into installing MAMP (Mac) or WAMP (Windows). Installing MySQL on your own computer can be a tedious process, and both of these software packages are drop-in installs of MySQL. Clean and simple.

Install MAMP/WAMP

12. Give your Scripts Limits

Putting a time limit on your PHP scripts is a very critical thing. There are times when your scripts will fail, and when they do, you’ll want to use the set_time_limit function to avoid infinite loops and database connection timeouts. The set_time_limit puts a time limit on the maximum number of seconds a script will run (the default is 30). After that time period, a fatal error is thrown.

13. Use Objects (or OOP)

Object-oriented programming (OOP) uses objects to represent parts of the application. Not only is OOP a way to break your code into separate, logical sections, it also reduces code repetition and makes it much easier to modify in the future. If you’re wanting to learn more, DevArticles has a great write-up on object-oriented programming with PHP.

14. Know the Difference Between Single and Double Quotes

It is more efficient to use single quotes in strings as the parser doesn’t have to sift through the code to look for escaped characters and other things that double quotes allow. Always try to use single quotes whenever possible.

Rebuttal: Actually, that’s not necessarily true. Benchmark tests show that, when testing strings without variables, there are definite performance benefits to using double quotes.

15. Don’t Put phpinfo() in your Webroot

Phpinfo is a beautiful thing. By simply creating a PHP file that has

	<?php phpinfo(); ?>

and dropping it onto the sever somewhere, you can instantly learn everything about your server environment. However, a lot of beginners will place a file containing phpinfo() in the webroot of the server. This is a really insecure practice, and if prying eyes gain access, it could potentially spell doom for your server. Make sure phpinfo() is in a secure spot, and as an extra measure, delete it once you’re done.

don't put phpinfo() in your web root

16. Never, Ever Trust Your Users

If your application has places for user input, you should always assume that they’re going to try to input naughty code. (We’re not implying that your users are bad people. It’s just a good mindset.) A great way to keep your site hacker-free is to always initialize your variables to safeguard your site from XSS attacks. PHP.net has an example of a properly secured form with initialized variables:

	<?php
	if (correct_user($_POST['user'], $_POST['password']) {
	    $login = true;
	}

	if ($login) {
	    forward_to_secure_environment();
	}
	?>

17. Store Passwords with Encryption

Many PHP beginners often plunk sensitive data like passwords into the database without applying any encryption. Consider using MD5 to encrypt passwords before you put them into the database.

echo md5('myPassword'); // renders - deb1536f480475f7d593219aa1afd74c

Rebuttal: Keep in mind, however, that MD5 hashes have long since been compromised. They’re absolutely more secure than not, but, with the use of an enormous “rainbow table,” hackers can cross reference your hash. To add even more security, consider adding a salt as well. A salt is basically an additional set of characters that you append to the user’s string.

18. Use Database Visualization Design Tools

If you’re finding it difficult to plan and modify databases for your PHP applications, you might look into using a database visualization tool. MySQL users can work with DBDesigner and MySQL Workbench to visually design your databases.

use database visualization design tools

19. Use Output Buffering

Output buffering is a simple way to greatly improve the performance and speed of your PHP script. Without output buffering, your script will show the HTML on the page as it’s processed – in pieces. Adding output buffering allows the PHP to store the HTML as a variable and send it to the browser in one chunk.

To enable output buffering, simply add ob_start() like so at the top of the file.


Rebuttal: Though not required, it’s generally considered to be a good practice to go ahead and append the “ob_end_flush();” function as well to the bottom of the document. P.S. Want to compress the HTML as well? Simply replace “ob_start();” with “ob_start(‘ob_gzhandler’)”;

Refer to this Dev-tips article for more information.

<!DOCTYPE html>
<?php ob_start('ob_gzhandler'); ?>
<html lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
	<title>untitled</title>
</head>
<body>
     
</body>
</html>
<?php ob_end_flush(); ?>	

20. Protect your Script From SQL Injection

If you don’t escape your characters used in SQL strings, your code is vulnerable to SQL injections. You can avoid this by either using the mysql_real_escape_string, or by using prepared statements.

Here’s an example of mysql_real_escape_string in action:

$username = mysql_real_escape_string( $GET['username'] );

and a prepared statement:

	$id = $_GET['id'];
	$statement = $connection->prepare( "SELECT * FROM tbl_members WHERE id = ?" );
	$statement->bind_param( "i", $id );
	$statement->execute();

By using prepared statements, we never embed the user’s inputted data directly into our query. Instead, we use the “bind_param” method to bind the values (and escaping) to the query. Much safer, and, notably, faster when executing multiple CRUD statements at once.

Read more on creating secure PHP applications at Nettuts.

21. Try ORM

If you’re writing object-oriented PHP, then you can use the nifty object relational mapping (ORM). ORM allows you to convert data between relational databases and object-oriented programming languages. In short: ORM allows you to work with databases the same way that you work with classes and objects in PHP.

There are plenty of ORM libraries for PHP like Propel, and ORM is built into PHP frameworks like CakePHP.

22. Cache Database-Driven Pages

Caching database-driven PHP pages is an excellent idea to improve the load and performance of your script. It’s really not all that difficult to create and retrieve static files of content with the help of our good friend ob_start(). Here’s an example taken from Snipe.net:

	// TOP of your script
	$cachefile = 'cache/'.basename($_SERVER['SCRIPT_URI']);
	$cachetime = 120 * 60; // 2 hours
	// Serve from the cache if it is younger than $cachetime
	if (file_exists($cachefile) && (time() - $cachetime < filemtime($cachefile))) {
	include($cachefile);
	echo "<!-- Cached ".date('jS F Y H:i', filemtime($cachefile))." -->";
	exit;
	}
	ob_start(); // start the output buffer
	// Your normal PHP script and HTML content here
	// BOTTOM of your script
	$fp = fopen($cachefile, 'w'); // open the cache file for writing
	fwrite($fp, ob_get_contents()); // save the contents of output buffer to the file
	fclose($fp); // close the file
	ob_end_flush(); // Send the output to the browser

This bit of code will use a cached version of a page that is less than 2 hours old.

23. Use a Caching System

If you’re wanting a more robust caching system, there are a few caching scripts for PHP that might be more complete than the above example.

use a caching system

24. Validate Cookie Data

Cookie data, like any data passed on the Web, can be harmful. You can validate cookie data with either the htmlspecialchars() or mysql_real_escape_string().

25. Use Static File Caching Systems

Aside from using database caching systems like Memcached, you might also want to try a templating system to increase performance in your PHP applications. Smarty is a robust templating system has caching built into it.

26. Profile your Code

Profiling your code with a tool like xdebug can help you to quickly spot bottlenecks and other potential problems in your PHP code. Some IDEs like Netbeans have PHP profiling capabilities as well.

27. Code to a Standard

Once you’ve gotten the ropes of PHP down, you can start learning about coding to a standard. There are differences between standards out there (say Zend and Pear), and finding one and sticking with it will help with the consistency of your coding in the long run.

28. Keep Functions Outside of Loops

You take a hit of performance when you include functions inside of loops. The larger the loop that you have, the longer the execution time will take. Take the extra time and line of code and place the function outside of the loop.


Editor’s Note: Think of it this way. Try to remove as many operations from the loop as possible. Do you really need to create that variable for every iteration of the loop? Do you really need to create the function each time? Of course not. :)

29. Don’t Copy Extra Variables

Some people like to try and make their code more appealing by copying predefined variables to smaller-named variables. This is redundant and could potentially double the memory of your script. Google Code has bad and good examples of variable usage:

Bad

	$description = strip_tags($_POST['description']);
	echo $description;

Good

	echo strip_tags($_POST['description']);


Rebuttal: In reference to the comment about “doubling the memory,” this actually is a common misconception. PHP implements “copy-on-write” memory management. This basically means that you can assign a value to as many variables as you like without having to worry about the data actually being copied. While it’s arguable that the “Good” example exemplified above might make for cleaner code, I highly doubt that it’s any quicker.

30. Upgrade to the Latest Version of PHP

While it seems like a common sense thing, many people don’t upgrade PHP as often as they should. There are lots of performance increases between PHP 4 and PHP 5. Check your server to make sure you’re up to date.

31. Reduce the Number of Database Queries

Any way that you can cut back on the number of database queries, the better your PHP script will perform. There are tools like Stace (Unix) and Process Explorer (Windows) that allow you to find redundant processes and how you might combine them.

Reduce the number of database queries

32. Don’t be Afraid to Ask for Help

It’s only human nature to want to hide the fact that we don’t know much about a certain topic. Nobody likes being a n00b! But how are we going to learn without asking? Feel free to use forums, IRC, StackOverflow to ask more seasoned PHP developers questions. The PHP website has a page on getting PHP help.

Have any rebuttals of your own? I’m sure you do! Let’s start the debate.


Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.jsxtech.com Jaspal Singh

    Nice list, Thanks for sharing

  • http://www.irishurls.com Paul McClean

    MAMP is great until you need to upgrade to a new version of PHP.

  • ozgur uksal

    this is a nice post. Thank you for sharing

  • http://www.danielgolden.net/ Daniel

    To post something like this is risky seeing as how we all disagree on so many of these points. There should be a disclaimer stating that there is no real 30 best practices, but as a beginner get a feel for the language and use what works best for you.

  • great article glen, but I disagree in two points

    Number 10, you give the impression that it’s good to comment every line, actually if you have to comment probably your code is too messy and should be refactored to a simpler form, only then you should add comments!

    On number 19, the ob_start() should be on the first line, before any output is sent or it will fail

  • http://butenas.com Ignas

    I’m developing with PHP a few years but I read this article and could say – good for beginers to learn and good for others to remember all the basic steps. Thanks ;)

  • http://www.webtint.net/ Johnny

    Awesome. This is really good for people who are just beginning in PHP

  • http:://raxanpdi.com php/ajax

    Excellent Post!

    I would also add “Use a Source Code Repository” as one of the best practices

  • Imran Khan

    It’s very essential for every beginners of PHP , Excellent POST

  • http://www.freetradeforum.com Sohail Ahmed

    Excellent post! I will cache systems first…

  • bill

    Bookmarked!
    I liked the info on double vs single quotes. I will read the PHP manual. I have never seen any webpage with the cacheing being done but will check this out. I always wondered about copying the raw variables to shorter ones but this seems redundant. This post will go a long way to making me a better PHP dude. Thanks!

  • http://ardlian.net ardlian

    thx for sharing

  • Fred

    I’d offer these hard-learned lessons as well:

    Whenever possible, use defined constants rather than globals for persistent configuration variables. For example, the name of a database or table or form variable. Doing this makes it easier to affect code changes without having to change all your hard-coded global variable names throughout the code base. In otherwords, whenever you find yourself using the same global twice, define() it.

    Capture the low hanging fruit once and keep it. Use a config (bootstrap) file to gather things like the current timestamp, script root, server info, browser info, etc.
    Don’t keep calling mktime() everytime you need it in a script.
    Don’t keep calling $_SERVER[] everytime you need to find PHP_SELF.
    Get it once and define() it.

    Encrypt (not encode) your $_GET variables and hidden $_POST variables to prevent tampering. I can’t think of any good reason NOT to do this.

    Consider keeping a session hit counter, incrementing the counter at each page request. This is an easy way to prevent form re-submission, and ignore the browser’s back button (if your app needs that). Embed the (encrypted) current hit count in all your forms and links. When the next page request is received, test it against the session. This is also an easy way to force bookmarked links to login, when a login is required. It’s also provides an easy mechanism for expiration (aka- your own garbage collection threshold).

    Unless something’s likey to change, don’t use some_function() in loop declarations. for instance,

    don’t do this:
    for($i=0 ; $i < keep_refinding_the_same_max_value() ; $i++ )
    {
    }

    do this:
    $max = find_max();
    for($i=0 ; $i $arg3);
    }

    $array = populate($arg);
    if(!isset($array['val_1'])){$array['val_1'] = 1;}
    if(!isset($array['val_2'])){$array['val_2'] = 2;}

    when this is possible

    $array = array('val_1'=>1,’val_2′=>2);
    function populate($arg3,&$array)
    { $array['val_3'] = $arg3;
    }
    populate($arg3,$array);

  • Fred

    for some reason my last point didn’t copy-paste correctly. Let’s try again.
    ————————————————————( apologies )———————–

    Populate complex structures by reference vs by return

    why do something like this:

    function populate($arg3)
    { return array(‘val_3′=>$arg3);
    }

    $array = populate($arg);
    if(!isset($array['val_1'])){$array['val_1'] = 1;}
    if(!isset($array['val_2'])){$array['val_2'] = 2;}

    when this is possible

    $array = array(‘val_1′=>1,’val_2′=>2);
    function populate($arg3,&$array)
    { $array['val_3'] = $arg3;
    }
    populate($arg3,$array);

  • Fred

    more oddity on copy-paste……
    ——————————————————–( Hmmm )————–
    Unless something’s likey to change, don’t use some_function() in loop declarations. for instance,

    don’t do this:
    for($i=0 ; $i < keep_refinding_the_same_max_value() ; $i++ )
    {
    }

    do this:
    $max = find_max();
    for($i=0 ; $i < $max ; $i++ )
    {
    }

  • Fred

    funny… this web site totally omitted another part of my post. Go figure.
    ———————————–( let’s see )—————–
    Avoid using elseif if you’re looking to solve a single condition among three or more DISTINCT possible conditions, use select:case – it’s way faster.

    elseif will evaluate each and every elseif before it returns

    if($suspect == ‘foo’)
    {}
    elseif($suspect == ‘bar’)
    {}
    elseif($suspect == ‘barfoo’)
    {}
    elseif($suspect == ‘boofar’)
    {}
    elseif($suspect == ‘booboo’)
    {}
    elseif($suspect == ‘farfar’)
    {}
    elseif($suspect == ‘foobar’)
    {}
    else
    {}

    whereas select:case will bail on the first solved condition.
    select ($suspect)
    {
    case ‘foo’: // This is most likely so we challenge this first
    break;
    case ‘bar’: // This is the second most likely so we challenge it next
    break;
    case ‘barfoo’: // so on…
    break;
    case ‘boofar’: // so on…
    break;
    case ‘booboo’: // so on…
    break;
    case ‘farfar’: // so on…
    break;
    case ‘foobar’: // this is the least likely to happen, so it’s last
    break;
    default:

    }

  • smego

    thanx

  • http://ehussain.in Hussain Cutpiecewala

    This is really useful post for me…
    Thanks

  • KGTM

    Wonderful topic. PHP as taken many “PHP Sucks” because newbie programmers didn’t event started to knew this essential practices, and many people that post source code for teaching don’t talk much about this, because some don’t know it too or just to make things more simple.

    But this should be from where every PHP newbie should start looking into.
    Instead of a “hello world”, this :)

    Lets take PHP good name to its rightful place, where it should be.

    Glen, a very good topic indeed, nice work. Keep it going.

    Regards
    Fábio Antunes

  • http://dremi.info dr.emi

    thank (twice) for this article, it open my idea for future project

  • Johannes

    #21: Please add doctrine the upcoming star for ORM on php side.

    You can also combine #21 with #18 via different plugins for cake, propel and doctrine.

  • Ego

    Help! I’m having issues with php, just started learning it using xampp, and I keep getting this error!”Warning: Cannot modify header information – headers already sent by (output started at *******”. I tried removing all the whitespaces and so on but still the same issue, its so frustrating!
    the code is:
    for the login processing page :

    and the db-connecting page code is:

  • Aleko

    Than you for this information .This is inevitable information for beginners

  • confused

    I remember a few years back people in #php on efnet were telling me that output buffering slowed things down one day and that they sped things up the next. Lots of other examples like that over the years.

    I refuse to believe anything anyone says about php except zend, IBM, Rasmus and a few others.

    I’ll send you a list of my 48 php questions I still can’t get a definitive answer for.

  • Test

    Highlighted

  • Shameed

    thanks a lot!!!

    I found the best guide here to become a real php programmer.
    Thank you very much once again

  • http://harikt.com Hari K T

    Great article .

    Really wonderful one to help the newbies and also to those who are coding in procedure oriented language now too .

  • http://akiweb.eu/ Áki

    Thanks. awesome

  • Sett

    nice article! but is missing an bracket here:

    if (correct_user($_POST['user'], $_POST['password']) {
    $login = true;
    }

  • http://www.holeycoww.co.uk holeycoww

    Excellent tutorial for beginners wanting to learn the fundemental basics of php coding!

    Thanks so much for posting this.

  • http://spotdex.com/ David Moreen

    This is actually a really great list. Good things to follow.

  • http://zangtumb.tumblr.com King Dumb

    #11. Install MAMP/WAMP

    Are you not forgetting the original ?

    LAMP it up !

  • Alex Bongo

    Thanks for sharing. PHP is freedom. It is awesome to see how different people flame up their concerns and ideas about great post like this. Readers’ comments extend the list to like 101 PHP best practices!

    Nice article Glen!

  • Tommy

    Great list! One thing though, the article that’s linked to on OOP is just too outdated. It contains several things that are no longer true for php.

  • http://devnotes.info/ devnotes

    thanks for very useful article, i must try profiling with xdebug :/

  • http://www.prabeengiri.com.np Prabeen

    Nice and well defined to help beginners improve their coding style in php.

  • bala2111

    awesome…!!! bookmarked this page :)

    Very helpful for a n00b like me ..lolz

  • Raphael Costa

    Wondeful TOPIC!

  • http://www.saimen.nl Simon Blok

    Bookmarked :-)

  • http://de.tinypic.com/r/15pmyl4/5 Gezim Rugova

    Interesting colection!

    don’t do this:
    insert into table(x,y,z) values($x,$y,$z)

    do this:

    // init array
    $aFields = array();

    // ass. array
    $aFields = array(
    ‘id’ => $id,
    ‘title’ => $title,
    ‘link’ => $link
    );

    // insert into DB
    $cFieldListCsv = implode(‘,’, array_keys($aFields));
    $cValueListCsv = implode(‘,’, array_values($aFields));

    $cSql = “INSERT INTO Table_XYZ ($cFieldListCsv) VALUES($cValueListCsv)”;

    // set statement
    $g_database->query($cSql);

    • Bob Carolgees

      Can I ask why should you place your insert commands in an array ?

  • http://godsea.adicto.org Jordi Rivero

    Excellent tutorial for beginners

  • http://palavalli.com/ Nagarjun Palavalli

    Thanks for making this article available. You mention quite a few points such as your recommendation to use IDEs but, you don’t suggest any. Please do suggest a few so that we can get working.

    • http://www.arminder.co.uk Arminder Dahul

      That’s what I wanted to know. I expect the usual one would be Dreamweaver. The other one I have used which is OK is Aptana.

  • http://gosti.org.ua Elena

    It was very helpfull. But the paragraph about SQL injections is not quite full. I would add to it more explanations or examples.

  • Evert Padje

    Good article! I don’t see the use of #19, ob_* functions are really bad because they’re used to hide errors 9 out of 10 times beginner programmers use it. For example, one might have added some whitespace before session_start(), which generates a ‘headers already sent’ error. By using ob_start this problem is hidden, but not solved.

  • http://www.gamefriction.com Caleb

    I find myself to be the kind of ‘PHP coder’ who can’t write my own scripts from scratch.

    I can take a PHP based news article system with admin and go through the code and re-develop that code to work for pretty much any other type of CMS I want to, but I can’t write a News system from scratch. Same for a user login and registration system.

    I know enough that I can look at the code and make changes big or small but not enough to build from the ground up.

    Is there any suggested resources that might help me with this? (forums, tutorial sites, etc.) I am always looking through the tuts-plus sites like a madman trying to learn as much as I can.

  • http://abcd waheed

    i need a valid and easy tutorial for object oriented login system

  • http://lksdf waheed

    i need a valid and easy tutorial for object oriented login system
    please help me to contact with me via my email id waheed@yahoo.com
    thanks
    whaeed

  • Bala

    THanks for the tut….

    @jeff

    I wanna download the whole series of Diving into php series….where can i get them ?

  • http://longlivephp.blogspot.com Shashi kanth

    Thanks a lot for the simple and useful tuts.
    Very beneficial for the fresh php guys like me.

  • http://www.tantawy.org Mahmoud Tantawy

    Great Tips, thanks for sharing