Separate display from logic

PHP lets developers write ugly code. And I mean really ugly, unmaintainable, horrific code. I’ve had to work on my share of projects that would make spaghetti code look organized. It doesn’t have to be that way though. Seasoned developers know the benefit of organized code. One organization technique that I believe is essential is the practice of separating display code from logic code. Lets discuss a couple methods of handling this in PHP.

A simple method

One of the simplest methods you can employ is just separating code that generates HTML from the rest of your code. Using the PHP project structure I described previously, all the HTML generation code would reside in the www directory, and everything else would exist in classes in the lib directory.

By “HTML generation” code, I mean any code whose sole purpose is to format and display HTML. This would include all echo and print statements, as well as loops to iterate over data sets. Any business logic or data access code would be considered “logic” in this case, and should be separated from the display.

Why is this a good practice? Lets look at two examples.

Example #1 with no separation of display and logic:

<?php
  $sql = "SELECT * FROM users WHERE username = 'luke'";
  $stmt = $pdo->prepare($sql);
  $row = $stmt->fetch();
  echo "Hello {$row->first_name} {$row->last_name}!";
?>

Example #2 separated into a User class, and a display script:

<?php
  class User {
    ...
    public static function get_user($username) {
      $sql = "SELECT * FROM users WHERE username = :u";
      $stmt = $pdo->prepare($sql);
      $row = $stmt->fetch();
      return new User($row);
    }
    ...
  }
<?php
  include_once("classes/User.inc");
  $user = User::get_user("luke");
  echo "Hello {$user->first_name} {$user->last_name}!";
?>

While Example 2 is certainly a bit more code up front, can you see the benefit over Example 1? There is now a reusable method called User::get_user() that can be used everywhere. This also allows for unit testing of the User class, to ensure that the method always works as we would expect; division of labor, to allow some programmers to work on back-end classes while others focus on the front-end display; and it is more maintainable, since we only have one place that fetches a user from the database instead of duplicating that logic all over our site.

The model, view, controller (MVC) method

Another popular code organization method is called MVC for model, view, controller. This has been popularized in recent years by the rise of Ruby on Rails which uses the MVC method by default. For larger projects, this is an excellent way to organize code. In the interest of time, I won’t delve into examples. In general though, here is how each part of MVC is differentiated:

  • Model – The model can be thought of as a data container. It would be a User or a Product class that holds all the information about something. This would also include the database which is where the data actually resides.
  • View – The view is usually some sort of template that takes models and creates a meaningful interface with which the user interacts. This would be very similar to the “display” part of the previous example.
  • Controller – The controller can be thought of as a traffic cop. This part is in charge of instantiating models and passing them to views.  The controller glues everything together and delegates user actions to the right places.

This can be done in PHP easy enough by differentiating your classes into models and controllers, while still keeping your view clean of any business logic. A true MVC model would likely use a template engine instead of echoing HTML directly from a PHP script, and the PHP script would act as part of the controller.

Conclusion

You should use whatever method works best for any given situation. No one solution is the best. However, you should always use some sort of organization technique, or your code will end up being a nightmare to maintain. Remember: “Always code as if the person who will maintain your code is a maniac serial killer who knows where you live.”

Posted in PHP | 1 Comment

Spreedly reviewed; New PHP API released

Ever hear of Spreedly? It’s a fantastic service I’ve been using to manage the subscriptions for NeoBudget. Spreedly specializes in one thing: recurring transaction processing, and they do it extremely well

A brief review of Spreedly

In case you’ve never attempted handling your own recurring transactions, let me give you a hit: it’s hard. I’ve worked on projects before, where a significant portion of my time was spent creating and testing the complex logic involved with prorating, refunding, upgrading, downgrading, and generally managing subscriptions. This is why, when I heard about Spreedly, I was eager to try it out. And I wasn’t disappointed.

Everything is handled over a very simple HTTP-based API. My site makes basic GET/POST/PUT requests to their web services, and they handle all the logic. They have a set of useful functions that can be used to create and manage users, pay for subscriptions, and even administer existing customers. Not to mention that it’s free to create a test site to play with.

When I first migrated NeoBudget over to Spreedly, it literally took me about three hours of coding. I set up the test site and got it working. After I rolled the code to production, transactions started coming through without any problems. It worked just like the test site. I’ve been using it now since November 2008, and I can definitely say they’ve made my life a lot easier.

Spreedly PHP API v2.2 released

When I started with Spreedly, no one had written a PHP wrapper around their API so I undertook the task. The first few versions of the PHP wrapper were released in early 2009. Spreedly has since made many improvements and added much functionality to their API, and sadly the old v2.1 release was sorely out of date having been released 10 months ago.

This morning, I brushed the dust off the old code base and gave it a good cleaning. Much of the innards have been reworked to be more robust. On top of that, I added support for invoices, payments, lifetime comps, store credits, one-time fees, updating existing subscriber information, and allowing another free trial.

Check it out on my Spreedly PHP API project page.

Posted in PHP, Spreedly | Leave a comment

Secure username and password authentication with PHP

With PHP-based websites that I create, I use a very simple but secure method for handling authentication. This basic method is secure, protects the privacy of the user, and works with any browser that supports cookies.

1. The database

The first thing to do is create a user table in the database.

CREATE TABLE user (
    username VARCHAR(32) PRIMARY KEY,
    password_sha1 VARCHAR(40) NOT NULL
);

The main thing to note here is that the password should never be stored in the database and it should not be recoverable. Here, I am storing an SHA1 hash, not the actual password. In fact, you can generally judge the security of a website by whether or not it's possible to get them to send you your password.

If a user forgets their password, a new random one should be generated, updated in the user table, and sent to the user. When they sign into the site, they should be reminded to change their password to something they can remember.

2. The sign in page

There is nothing special at all about the sign in page. It is simply a form with a username and password field. This is, however, the weakest point in the security of this authentication scheme. Be sure that this page is encrypted with SSL, or else the password they enter will be sent across the Internet in plain text.

<html>
<body>
<form method="post" action="_signin.php">
<label for="username">Username</label>
  <input type="text" name="username">
<label for="password">Password</label>
  <input type="password" name="password">
  <input type="submit" value="Sign in">
</form>
</body>
</html>

3. The form handling page

Here we have the meat of this authentication method, the PHP script that handles the form post.

<?php
  include_once("database.inc");

  $username = $_POST['username'];
  $password_sha1 = sha1($_POST['password']);

  $sql  = "SELECT username ";
  $sql .= "FROM user ";
  $sql .= "WHERE username=:u AND password_sha1=:p";
  $stmt = $pdo->prepare($sql);
  $stmt->execute(array(
            ":u"=>$username,
            ":p"=>$password_sha1
          ));
  $row = $stmt->fetch();

  // clear out any existing session that may exist
  session_start();
  session_destroy();
  session_start();

  if ($row) {
    $_SESSION['signed_in'] = true;
    $_SESSION['username'] = $username;
    header("Location: /dashboard.php");
  } else {
    $_SESSION['flash_error'] = "Invalid username or password";
    $_SESSION['signed_in'] = false;
    $_SESSION['username'] = null;
    header("Location: /index.php");
  }
?>

There are a couple important things to note here.

  • Don't do anything with the plain-text password. Notice that the first thing this script does is create a SHA1 hash of the password. SHA1 is a popular one-way hash algorithm that takes any string of bits and creates a 40-character hash code. Once you have the hash code, it is not possible to decode it and get the original password.
  • Hashes are compared, not passwords. Also notice that this script checks to see that the SHA1 hash of what they typed and the SHA1 hash stored in the database are identical. If they are not, then we can assume their password isn't correct. It isn't necessary to know their actual password for this comparison.
  • Store state in the session, not in cookies. PHP maintains a cookie called PHPSESSID with the user's browser that identifies this session. That is the only cookie you should need to deal with, and it is set in the session_start() method. When you store values in the session, it is stored on your server, not transmitted across the network. This way, it is impossible for a hijacker to pretend to be signed in. (See my notes at the end about session hijacking.)

4. Validation in the application

To handle validation on a per-page basis, I usually create a validate.inc include file that I can include on any page that requires the user to be authenticated. This script will start the session and check if the user is authenticated. If they are not, then it forwards them to the sign in form. Otherwise it allows execution to continue.

<?php
  session_start();
  if (!$_SESSION['signed_in']) {
    $_SESSION['flash_error'] = "Please sign in";
    header("Location: /index.php");
    exit; // IMPORTANT: Be sure to exit here!
  }
?>

Other considerations

Session hijacking is a possible weakness of this method. While it's difficult, it's not impossible to spoof the session cookie and pretend to be another user. To get around this, you can store the IP address of that the user in the session when you authenticate. Then in your validate script, check the $_SERVER['REMOTE_ADDR'] value with the IP address stored in the cookie.

Conclusion

Secure authentication is not complicated, but care needs to be taken at key points to ensure the privacy and security of your users.

Posted in PHP, Security | Leave a comment

Two types of websites

Something I have noticed over the years is that there are fundamentally two uses of the Web: web pages, and web applications. Each are created, developed, and maintained very differently. It is useful to understand which you are creating before starting so you can employ the most appropriate development strategies.

Web pages

Web pages are informational in nature such as toyota.com, blogs such as getrichslowly.org, or even ecommerce sites such as ebay.com. Typically they display mostly static content that is generated by the organization itself and displayed, consumed, or purchased by the end user.

With web pages, the standard HTTP GET/POST model works just fine. Users are accustomed to clicking links to browse pages where each click loads a new page on the website. This is in fact the way that the Web was initially designed and the use for which it was conceived.

Developing web pages is very much a design process, and much more work should go into the usability and feel of the site itself. There isn’t as much back-end programming with scripting languages such as PHP or Rails. The involvement of those languages is usually limited to content delivery and formatting of the content. A project developing a web page for an organization will typically spend more time in design than in programming.

Web applications

Web applications are tools that can be used online such as gmail.com, spreedly.com, and neobudget.com. Typically they display user-generated content and provide a useful service to the user, rather than just providing information. These are becoming more and more popular as users are getting more comfortable sharing information online. I have noticed a definite trend toward moving applications from the desktop to the Web for the convenience afforded by such online applications.

Google is banking on this trend. They have invested significant resources creating a web browser specifically designed to speed up web applications, and they’re also working on an operating system with the sole purpose of getting users online as fast as possible.

Developing web applications is much more like developing a desktop application. Much of the time is spent with back-end business logic. In fact, this business logic is what provides the functionality that drives users to use the application.

Another significant portion of development time is spent on the user interface. A web application’s user interface is very different from a web page. Remember, web pages mostly display content and link to other content. Web applications on the other hand are much more richly interactive. Many are driven by complex event-based interfaces just as a desktop application would be, and this is where AJAX can be used effectively to enhance these rich interfaces.

Conclusion

There is nothing terribly profound here in this article. However, understanding this simple separation can help clarify development priorities. Before sitting down and creating a website, I recommend spending a few minutes analyzing the purpose of the site. Which category does it fall under? Knowing this will help you understand the way people will use your site, and where you should spend your time in development.

Posted in Observations, Usability | Leave a comment

Handling PHP form posts

It is very common to handle form posts at the top of a PHP script that prints HTML. This happens most frequently on CRUD screens where a form will post back to itself to handle the updates. There are several reasons why this is not good practice including:

  • Page reloads. If the user reloads this page, the form will be resubmitted along with the post parameters. This will cause your script to execute the CRUD logic again, and also causes confusion with the end user.
  • Maintainability. This is doesn’t do proper separation of display and logic. In order to promote readable and maintainable code, it is usually best to keep all your processing functions separate from your display.

Here’s a simple example of how to do this poorly:

include_once("classes/UserDao.php");
$username = $_POST['username'];
$password = $_POST['password'];
if (UserDao::authenticate($username, $password)) {
    echo "Invalid username or password.";
    exit;
}

echo "<html><body>";
echo "<p>Congrats! You signed in!</p>";
echo "</body></html>";
?>
↑ Example 1: authenticating at the top of a view ↑

A better way to handle form posts is to create separate scripts to handle the POST processing and the display. In my PHP sites, scripts that process a post are prefixed with an underscore and they use Location redirects with the header() function. These scripts do not echo anything, they simply process the request and forward on to a display page. Usually, they will update session variables or save to the database.

Another convention I use is to never use SQL inside of the web root. Since the POST scripts are inside my web root, this forces me to write classes to encapsulate all my database logic. In fact, most logic is encapsulated in classes to make unit testing easier.

Reworking our previous example above, I’ve created a script called “_authenticate.php” that a sign in form would post to. Notice it doesn’t display anything, and all SQL and authentication logic has been abstracted into the UserDao class.

<?php
include_once("classes/UserDao.php");
session_start();
$username = $_POST['username'];
$password = $_POST['password'];
if (UserDao::authenticate($username, $password)) {
    $_SESSION['username'] = $username;
    header("Location: /dashboard.php");
} else {
    $_SESSION['username'] = null;
    $_SESSION['flash_error'] = "Bad username or password.";
    header("Location: /signin.php");
}
?>

Using this method will make your code more readable and understandable, and whoever has to maintain your code later will thank you.

Posted in PHP | Leave a comment

JavaScript performance

There is an exciting trend in the browser market today. A war is being fought over JavaScript performance. The browsers each seem to be trying to outdo each other with optimizing their JavaScript engines. Firefox has drastically improved their engine in the past few releases with SpiderMonkey and TraceMonkey, and Safari’s SquirrelFish engine seemed to be unbelievably fast. That is, until Chrome’s V8 hit the market. Take a look at some of these articles that show performance of some of these engines:

For complex JavaScript applications, much of the application’s performance is out of our hands as developers. It depends, in a large part, on the browser. However, there are some things we can do to make our JavaScript applications run smoothly and feel snappy regardless of the browser.

Programming JavaScript for performance

Many of the same performance techniques used in other languages such as C and Java can be used with JavaScript as well. Many articles have been written on how to optimize code in general. They all suggest excellent things such as making sure your algorithm is efficient, cache frequently used values, and unrolling loops. These tips can be applied to any language to improve performance.

The DOM

One unique thing with JavaScript is the DOM. The DOM (Document Object Model) is a representation of a web page in JavaScript objects. DOM manipulation is often a performance bottleneck for complex sites. This is because the DOM is more than just an object model, it represents the rendered page. Any changes to the DOM must also be reflected on the rendered page. Thus, DOM manipulation invokes dynamic, run-time rendering in the browser (sometimes called document reflow).

When manipulating the DOM, try creating an object model of what you want to display before injecting it into the DOM. That causes the browser to only invoke dynamic rendering once (when you insert the whole object model) rather than with each manipulation.

Compare these two MooTools examples which inject a couple elements dynamically.

var div = new Element('div').inject(document.body);
new Element('p', {html: 'Hello'}).inject(div);
new Element('p', {html: 'World!'}).inject(div);

↑ Example 1: adding to DOM immediately ↑

var div = new Element('div');
new Element('p', {html: 'Hello'}).inject(div);
new Element('p', {html: 'World!'}).inject(div);
div.inject(document.body);

↑ Example 2: adding to DOM later ↑

The code in Examples 1 and 2 are very similar with one key difference. Notice Example 1 injects div into document.body immediately. Now it’s part of the DOM. When the next line injects into div, it’s also injecting directly into the DOM, and the same with the next line. This causes 3 injections into the DOM and causes the browser to reflow 3 times.

The second example builds a sub-DOM first, and injects it once at the end. This small change can cause dramatic results. For this simple example, you would likely not notice anything. But I’ve worked on massive JavaScript rendered applications, and the difference between immediate and delayed injection is very noticeable.

Variable scope

In JavaScript, as with most other languages, variables can be accessed based on their scope. When a variable x is encountered, the compiler will start looking through the various scopes to find it, starting with the local scope and moving outward to the global scope. As such, one way to improve performance is to use the local scope as much as possible.

Since the local scope is searched first, if a variable exists in the local scope, the compiler doesn’t need to continue searching. This saves CPU cycles, and can be a big boost in performance-critical portions of code. Here’s an example:

var global_counter = 1;
var increment() {
    for (var i=0; i &lt; 100000; i++)
        global_counter++;
}

↑ Example 3: accessing global variable ↑

var global_counter = 1;
var increment = function() {
    var local_counter = global_counter;
    for (var i=0; i &lt; 100000; i++)
        local_counter++;
    global_counter = local_counter;
}

↑ Example 4: caching global variable locally ↑

While certainly not as elegant, Example 4 is faster because it removes 100,000 extra scope lookups by caching the global_counter in the local scope.

Closures

Another performance tip is to be very careful with closures. While closures are a beautiful part of the language, they are also a common source of memory leaks and slowdowns.

Closures make an outer local scope available to an inner function. Since JavaScript lets you pass around functions as variables, the outer scope is passed around as well. As long as the function stays around, the outer scope stays around too. Here’s an example:

var get_handler = function() {
    var x = 1;
    return function() {
            x++;
            alert(x);
        };
}

↑ Example 5: closure memory leaks ↑

Here we have a function returning a function that makes use of a local variable, x. Normally, the local variable x would get garbage collected when get_handler() finishes executing. But this closure is holding a reference to that variable, preventing it from being cleaned up. This happens most frequently with event handlers, which are often created as closures. These event handlers often stay around for a very long time, gobbling up memory like an unsated lemure.

As with the DOM example, this simple example isn’t bad. But imagine this happening in every closure in a large JavaScript application. This shared scope can cause a massive drain on memory over the runtime life of the application.

Class methods

Often, object oriented programming is simulated in JavaScript using functions. This can be nice for those familiar with object oriented programming, but it imposes a structure that is not native to JavaScript. JavaScript is prototype-based. Rather than defining class methods at run-time, consider using the prototype property. Compare these two examples:

var MyClass = function() {
    this.initialize = function() { /* ... */ },
    this.get_value = function() { /* ... */ }
};

↑ Example 6: a simulated Class ↑

var MyClass = function() {};
MyClass.prototype.initialize = function() { /* ... */ };
MyClass.prototype.get_value = function() { /* ... */ };

↑ Example 7: using JavaScript prototype ↑

In Example 6, every time a new instance of MyClass is created, initialize and get_value are set to new instances of their respective functions. This is a waste. Using the prototype property, we can add functions to MyClass once. When a new instance of MyClass is created, it inherits the properties of its prototype. It’s actually using the same instance of these functions, thus saving memory and the time it would take to instantiate the function instance.

Concluding thoughts

There are certainly hundreds more places where JavaScript performance can be improved. The few listed in this article are some of the most common pitfalls and can often provide the most bang for your buck. I highly recommend reading the pages in the “Further reading” section at the end of this article, as they provide much more thorough explanations and techniques for boosting performance in JavaScript

Further reading

Posted in JavaScript, MooTools, Performance | Leave a comment

Structure of a PHP website

PHP is free-form and has no imposed structure.  It is just a scripting language. Those familiar with Rails will feel lost with this lack of structure.  It’s easy to just throw another file in the document root to handle a new page.  However, this quickly turns into the dreaded file pile nightmare that plagues the vast majority of PHP-based websites.

For the past several years, I’ve used the same basic structure for all my PHP websites, and I believe this format works extremely well to keep a growing site organized.

Basic file structure

Previously, I mentioned that I have a structure I’ve been using for years when creating a new PHP website.  This structure has served me very well, so let me expand upon it a bit more.

  • lib/ – Here I store all my include files that provide utility functions and classes.  By keeping this outside the document root, we are assured that users can’t view our source through the web.
  • lib/classes/ - This subdirectory contains all classes.
  • www/ - This is the document root and contains all the .php files.  Each .php file follows the basic structure in the next section.  Files beginning with an underscore are POST files, and do not display anything.  They process data and forward to another page.  More on this later.
  • src/ – This contains source JavaScript and CSS files.  This directory is explained in detail in my post about concatenating and compressing.
  • database/ – This contains the schema and rollout scripts necessary to maintain changes to the database.
  • tests/ - Unit tests using PHPUnit.

Rendering HTML content

Most files that display HTML use the following structure:

<?php
    include_once("validate.inc");
    include_once("header.inc");
?>
<!-- CONTENT -->
<?php
    include_once("footer.inc");
?>
  • lib/header.inc – This displays the page title, sidebar, navigation, and sets up any global variables necessary for the site.
  • lib/footer.inc – This displays the copyright notice, contact information, and anything else that should appear in the footer.  This can also deconstruct open connections if necessary.
  • lib/validate.inc – If the site requires authentication, the validate.inc include file makes sure the user is authenticated.  If they are not, they are forwarded to the sign-in page. This must be included before the header.

Handling POST data

Scripts that handle POST requests always begin with an underscore (e.g. _signin.php).  These do not display any HTML, and always redirect to another page using Location redirection.  I’ll cover this technique more in a future post.  For example:

<?php
    do_something($_POST['id'], $_POST['value']);
    header("Location: /index.php");
?>
Posted in PHP | Leave a comment

MooZoom extension for MooTools

Apple.com at one point had a nifty effect on their website that would zoom a thumbnail image to a full image. Many people have created JavaScript solutions to imitate this feature.

The problem with existing solutions (see FancyZoom and ReMooz) is that they load the images into the DOM when you click the thumbnail. This results in a slow user experience. They also use graphics for shadows, which causes more loading time for the end user. One of my passions is performance optimization, so this annoyed me.

My solution is MooZoom. I’ve just released version 0.9.1 which contains more options and speed improvements over the initial 0.9 release.  See for yourself: I use it on the Projects page for this site.

MooZoom on GitHub
MooZoom on the MooTools Forge

Posted in JavaScript, MooTools, Performance | Leave a comment

Amazon S3 cloud storage and content delivery networks

Recently, I discovered the joy of cloud storage. Cloud storage is simply an outsourced facility used to host static content on the web. Since storage is cheap, and bandwidth is getting cheaper, these hosted services are starting to become very popular.  The concept is simple, you upload your static files (such as images or videos) to ease the load on your own web server.

I’ve been playing around with Amazon S3 lately, which is Amazon’s cloud storage solution.  S3 is incredibly easy to configure and use.  Basically once I signed up, I just created a bucket which is a globally unique name.  This bucket name is used in links to your content.  Once you upload files to your bucket, you can access them at http://YOURBUCKET.s3.amazonaws.com/myfile.mp4.  Now, this large file will use Amazon’s bandwidth when the files are downloaded rather than your server’s bandwidth.  And yes, it’s dirt cheap.  I’m usually billed less than 75 cents per month for my personal use.

Why would I do this?  What is the benefit?

First, this eases the load on my web server.  It no longer needs to answer requests for these static files.  Second – and this is the key to performance boosting – Amazon’s bandwidth is a lot faster than my personal server, meaning that the files are usually downloaded much faster.

Another benefit is that Amazon also has another service called CloudFront, which lets you take this one step further.  When using CloudFront, the files in your bucket will be distributed to data centers around the globe.  So when someone from Asia visits your website, the images would be downloaded from a server in Asia, rather than somewhere in the US.  By distributing your static files to servers around the globe, you ensure that the content is loaded as fast as possible no matter where your users may be located.

Posted in Performance | Leave a comment

Is PHP a viable option?

PHP has gotten a bad rap in the past few years, especially from the Rails community.  It’s often seen as the poor-man’s scripting language that should never be used for anything serious. In many ways, I think this is an unfair reputation and this series, called “PHP web design,” is designed to show the benefits of PHP and explain best practices. PHP certainly has a plethora of limitations, don’t get me wrong.  I’ll be exploring the good and the bad as we delve into the depths of PHP.

The bad

Lets get the bad parts of PHP out in the open.  There are many more flaws than I’ll list here, but for the sake of brevity I’ll list the ones that I think are the worst.

  • Horrible memory management. If you ever need to maintain and process large arrays of data, you’ve likely hit memory limits in PHP.  I ran some tests using the memory_get_usage() function.  A script that simply creates an array variable takes 93 KB of RAM.  Storing 1000 integers in that array takes 290 KB.  Storing 10,000 integers takes over 2 MB.  And that’s just storing integers.  Complex objects take much more space.  The overhead for each element in PHP is enormous.
  • Lack of internal consistency. I’ve worked with PHP for over 10 years, and the fact that I still have to look up the parameter order for str_replace() really says something.  For string manipulation functions, sometimes the haystack is the first parameter and sometimes it’s the last.  There is very little internal consistency or convention.  This is because PHP evolved over time, rather than being designed.
  • Can you say, “slow?” If you have a long-running complex algorithm, you can expect it to take an order of magnitude longer in PHP than with most other scripting languages.  Scripting languages in general are slow, but PHP seems to be exceptionally slow.  I usually offload complex tasks to Perl or Ruby.  Depending on the task, I sometimes offload to C to squeeze out every ounce of performance possible.
  • Bad design is easy. PHP does not promote good design.  It’s very easy to hack a website together and have an unmaintainable jumble of spaghetti code before long.  It takes discipline and consistency to create a well-structured PHP site.

The good

For all its flaws, there are many reasons that I think PHP is still a viable solution for websites and web applications.  Here are some of the best things PHP has going for it.

  • Simplicity. PHP is simple and easy to learn.  The code is straightforward and easy to read (assuming the site has been properly structured).  It only takes a matter of minutes to get a fully working basic site structure in place.
  • Prevalence. PHP is everywhere.  It is included in all Linux distributions, and is available on most web hosts.  You don’t have to look far to find a server with PHP enabled.
  • Minimal server requirements. Basic PHP is very easy to install without any fuss.  It can be compiled with very few dependencies.  All you really need is a web server like Apache, and you can have PHP up and running in a few minutes. If you’re using pre-built packages, it’s even easier.
  • Amazing centralized documentation. I have rarely seen better online documentation than what is available at php.net.  This documentation has been up and maintained for years, and user comments are invaluable.  The documentation is easy to read and the functions can be understood in a matter of seconds.  They all contain great examples, and the ones that don’t are provided by user comments.
  • There’s a function for that. Say what you will about the lack of consistency and convention, but there are built-in functions for almost everything with PHP.  This is very handy once you get to know them.
  • Beautiful object-oriented features. Yes, I said it.  PHP 4 had awful object oriented functionality, and few realize the depth of change that came with PHP 5.  I have developed some rich APIs with PHP 5 that take full advantage of abstract classes and interfaces, as well as complex subclassing. The object oriented capabilities of PHP 5 are beautiful, to say the least.

Concluding thoughts

Yes, PHP has its flaws and we are all aware of these flaws.  But major sites like Facebook still use PHP.  I’m running NeoBudget on a 256 MB slice on Slicehost and haven’t come close to running out of RAM. I believe PHP can be a good choice for creating a website or web application. This series will explore good PHP programming practices and will hopefully help rid the world of the stigma that has been associated with PHP.

Don’t agree with me? Feel free to heckle me in the comments.

Posted in PHP | Leave a comment