Add Power to Your PHP With Multi-Tiered Applications

Add Power to Your PHP With Multi-Tiered Applications

Apr 14th, 2009 in PHP by Jason Lengstorf

As PHP applications become more and more complex, it can be easy to end up with a tangled mess of code that makes maintenance nearly impossible. Applying the concept of tiered applications can help to alleviate some of the difficulty in maintaining complex applications.

PG

Author: Jason Lengstorf

Jason Lengstorf runs Ennui Design, a freelance design and development effort. When he's not glued to his keyboard, he's likely to be wearing cowboy shirts, deadlifting, or pretending to know stuff about wine.

What Do You Mean by Tiered Applications?

Tiered programming is the practice of keeping different components, ideas, or languages separate from each other. In front-end development, tiered markup would be using external stylesheets and JavaScript.

Example of tiered markup using external JavaScript and CSS

By linking to a CSS file rather than embedding styles in your HTML markup, it becomes easier to change the formatting of your websites because now all styling information is conveniently stored in one place, separated from the markup of the document. And multiple HTML pages can pull in the exact same CSS file, your whole site can be updated style-wise by simply changing one line of CSS.

In back-end development, the same rules apply, but we're dealing with different components. In broad terms, we're looking at three tiers: the Database (storing and retrieving data), Business (processing and handling of data), and Presentation (how data is displayed) tiers.

Why Should I Care?

Make your functions plug and play by using tiered applications.

It might not be immediately obvious, but separating your applications into a tiered structure will have a huge impact on your code's ability to change in the future. For example, if you have a blogging system set up, and it becomes necessary to create an RSS feed for the blog, a properly tiered application would allow you to simply set up an RSS template, then call the database and business functions that you've already written.

On the opposite end, if your client suddenly decided that PostgreSQL was a better choice for their organization than MySQL, you would only have to rewrite your database functions, all without touching the business or presentation logic of the application.

In terms of reusability, you could have multiple database functionalities (supporting MySQL, PostgreSQL, and Oracle, for example), that could be easily dropped into new rollouts of your application using just a few lines of code in one place, rather than editing several lines of your code across multiple functions.

The Wrong Way

To start, let's take a fairly simple task—pulling the title and body text of an entry out of a database, creating a shortened version of the entry, and placing the data into HTML markup—and go about it in entirely the wrong way. In the following code, we'll write one function to perform all of our tasks:

function displayEntry()
{
	$entryDisp = NULL;

	// Get the information from the database
	$sql = "SELECT title, entry FROM entries WHERE page='blog'";
	$r = mysql_query($sql) or die(mysql_error());
	while($entry = mysql_fetch_assoc($r)) {
		$title = $entry['title'];
		$text = $entry['entry'];

		// Create the text preview
		$textArray = explode(' ',$text);
		$preview = NULL;
		for($i=0; $i<24; $i++) {
			$preview .= $textArray[$i] . ' ';
		}
		$preview .= $textArray[24] . '...';

		// Format the entries
		$entryDisp .= <<<ENTRY_DISPLAY

<h2> $title </h2>
<p>
$preview
</p>
ENTRY_DISPLAY;
	}

	return $entryDisp;
}

This code outputs HTML markup along these lines:

<h2> Entry One </h2>
<p>
This is the shortened description of entry number one. It 
displays the first 25 words of the entry and then trails 
off with an ellipsis...
</p>
<h2> Entry Two </h2>
<p>
This is the shortened description of entry number two. It 
displays the first 25 words of the entry and then trails 
off with an ellipsis...
</p>

Though this might appear logical, it's actually really undesirable. Let's go over what makes this code a less-than-optimal approach.

The Problem with This Approach

Lumping functions causes redundant code and difficult maintenance.

Poor Legibility—This code is diluted. Its purpose, though documented in the comments (sort of), is tough to discern. If you wrote this, then came back to it in six months, it wouldn't be instantly clear what was going on, which means a few seconds/minutes wasted trying to interpret your own code.

Too Narrow in Focus—This function is crippled by its specificity: the database query only works for one type of entry; the text preview creation is hard-coded into the function; the formatting is specific to the type of entry being displayed. In order to create a slightly different implementation of this functionality, we'd be forced to create a second function that looked almost exactly the same, even if all we needed to change was the number of words in the text preview.

Lack of Scalability—This is pretty closely related to the idea of being too narrow in focus; if we want to add more functionality (such as a link or an image), our function will get larger and more difficult to manage. And what if we want to add conditions that affect how an entry is displayed? It's easy to see how programming like this allows for code to quickly become sprawling and unmanageable.

The Big Problem: Lumping Database, Business, and Display Logic

This is the sweeping issue that is causing all of the aforementioned problems.

By combining all three of our logic types, we end up with a narrow, messy, hard-to-manage, nearly-impossible-to-reuse tangle of code.

Imagine an application where each type of display (RSS feed, entry preview, full entry display, etc.) was built with a function like the one above, with the database access, business logic, and presentation logic all written together. Now imagine that there are nine pages on the site, all of which have their own entry display and preview functions.

Even if we assume the application is really simple and that there are only two functions per site page, we're still looking at almost twenty functions that will need to be updated if changes become necessary.

Improving the Code

To improve the code above, we'll spread our different types of logic across several functions. If done properly, we should end up with a set of highly reusable, easily understood functions that stack to perform a variety of tasks.

Smaller, interchangeable functions allow for easy maintenance.

To get started, we'll plan out the necessary functionality to get a better idea of how it should be constructed:

  1. Retrieve the entry and title columns for a given page from the "entries" table in the database
  2. Shorten the body of the entry to a 25-word preview and append an ellipsis
  3. Insert the data into HTML tags to display on the user's browser

As you can see, our plan clearly identifies a database, business, and presentational tier. We can now write functions to fulfill each of these steps with relative ease.

Step 1—The Database Tier

To get information from the database, we're going to write a very simple function. To encourage good coding practice, I'm going to use the mysqli extension, but I'm not going to focus on how it works. If you're not using it already, I'd encourage you to explore mysqli or a similar extension (i.e. PDO) to secure your MySQL queries against injection attacks.

So let's jump right into the code:

function getDataFromDB($page)
{
	/*
	 * Connect to a MySQL server
	 */
	$mysqli = new mysqli('localhost', 'user', 'password', 'world');
	if (mysqli_connect_errno()) {
		printf("Connect failed: %s\n", mysqli_connect_error());
		exit;
	}

	/*
	 * Create a prepared statement for pulling all entries from a page
	 */
	if ($stmt = $mysqli->prepare('SELECT title, entry FROM entries WHERE page=?')) {
		/*
		 * Create a multi-dimensional array to store
		 * the information from each entry
		 */
		$entries = array();

		/*
		 * Bind the passed parameter to the query, retrieve the data, and place
		 * it into the array $entries for later use
		 */
		$stmt->bind_param("s", $page);
		$stmt->execute();
		$stmt->bind_result($title, $entry);
		while($stmt->fetch()) {
	        $entries[] = array(
				'title' => $title, 
				'entry' => $entry
			);
	    }

	    /*
	     * Destroy the result set and free the memory used for it
	     */
	    $stmt->close();
	}

	/*
	 * Close the connection
	 */
	$mysqli->close();

	/*
	 * Return the array
	 */
	return $entries;
}

If you break down what this function is doing, we are literally just requesting two columns (title and entry) from our table (entries), then storing each entry in a multi-dimensional associative array, which is the return value of the function. We pass one parameter, $page, so that we can determine which page we're grabbing information for. In doing so, we've now created a function that will work for every page of our site (provided they all have a 'title' and 'entry' field).

Notice that our function does nothing to handle the data; it simply acts as a courier, grabbing the information we request and passing it on to whatever comes next. This is important, because if it did anything more, we'd be in the realm of business logic.

Why is it important to separate the business logic from the database logic?

The short answer is that it allows for database abstraction, which essentially means that the data could be migrated from MySQL into another database format, such as PostgreSQL or Oracle, all without changing the data-handling functions (business tier), since the output would still simply be a multi-dimensional associative array containing entries with a title and entry column, no matter what kind of database we're using.

Step 2—The Business Tier

With the data loaded into our array, we can start processing the information to suit our purposes. In this example, we're trying to create an entry preview. In the first example, the length of the preview was hard-coded into the function, which we decided is a bad practice. In this function, we'll pass two parameters to our code: the text to process, and the number of words we want to display as our preview.

Let's start by looking at the function:

function createTextPreview($text, $length=25)
{
	/*
	 * Break the text apart at the spaces and create the preview variable
	 */
	$words = explode(' ', $text);
	$preview = NULL;

	/*
	 * Run a loop to add words to the preview variable
	 */
	if($length < count($words)) {
		for($i=0; $i<$length; $i++) {
			$preview .= $words[$i] . ' '; // Add the space back in between words
		}
		$preview .= $words[$length] . '...'; // Ellipsis to indicate preview
	} else {
		/*
		 * If the entry isn't as long as the specified preview length, simply
		 * return the whole entry.
		 */
		$preview = $text;
	}

	/*
	 * Return the preview
	 */
	return $preview;
}

In the function above, we simply check that the number of words in the supplied entry is greater than the number of words we want to show in our preview, then add words to the newly-created $preview variable one at a time until we hit our target length, at which point we append an ellipsis and return $preview.

Just like in our database tier, we're keeping the code within the bounds of the business tier. All we're doing is creating a text preview; there is no interaction with the database, and no presentational elements such as HTML markup.

Step 3—The Presentation Tier

Finally, we need to display the data we've retrieved and processed. For our purposes, we'll be displaying it with extremely simple HTML markup:

<?php
	$entries = getDataFromDB(); // Load entries into an array
	foreach($entries as $entry) {
		/*
		 * Place the title and shortened entry text into two appropriately
		 * named variables to further simplify formatting. Also note that
		 * we're using the optional $length parameter to create a 30-word 
		 * text preview with createTextPreview()
		 */
		$title = $entry['title'];
		$preview = createTextPreview($entry['entry'], 30);
?>

	<h2> <?php echo $title; ?> </h2>
	<p> <?php echo $preview; ?> </p>

<?php
	} // End foreach loop
?>

The idea behind this code is simple: first, load the entries using our database function, then loop through the entries, shortening the entry text using our preview function and then placing the title and entry preview into presentational markup.

Now, in order to change the layout of the entry previews, only two lines of HTML need to be adjusted. This is a far cry less confusing than the original function that handled all three tiers.

Closing Thoughts on Tiered Programming

I'd like to point out that the above example is very basic, and is meant only to demonstrate the concept of tiered programming. The idea is that by keeping the different types of programming logic separated, you can vastly increase the readability and maintainability of your code.

NOTE: There's a great article on TheDailyWTF.com discussing the use and misuse of tiered software design, and wonderful commentary on the article that presents differing opinions. Multi-tiered applications are extremely useful, but also easy to misunderstand and over-complicate, so remember to thoroughly plan your software before building to avoid causing more problems than you're solving.

Do you have any thoughts on tiered applications? What steps are you taking to maximize ease of maintenance and future changes in the code you write? Let us know in the comments!

  • Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.


Related Posts

Check out some more great tutorials and articles that you might like

Enjoy this Post?

Your vote will help us grow this site and provide even more awesomeness

Plus Members

Source Files, Bonus Tutorials and
More for $9 a month for all TUTS+
sites in one subscription.

Join Now

User Comments

( ADD YOURS )
  1. PG

    Jeffrey Way April 14th

    Really great job, Jason. Feel free to submit as many articles as you like. :)

    ( Reply )
  2. PG

    Michael Rice April 14th

    Super duper awesome.

    ( Reply )
  3. PG

    Matt Hauth April 14th

    As Borat would say….Very Nice.

    ( Reply )
  4. PG

    Scott April 14th

    I do like this frame of programming, but it’s really just Model-View-Controller programming using a different name.

    http://en.wikipedia.org/wiki/Model-view-controller

    ( Reply )
    1. PG

      EllisGL April 15th

      I was thinking the same thing.

      ( Reply )
    2. PG

      Tommy M April 15th

      Ditto exactly. Stole my post haha.

      ( Reply )
    3. PG

      Don April 16th

      This is actually not MVC, it is a pattern that can be used with MVC for the behaviors of a class. MVC is a tiered pattern used for a whole system. The idea here is that methods in just the controller itself also need an organizational model. It’s more a micro-pattern stressing generalizability and single behavior methods so our code is cleaner and more manageable.

      ( Reply )
    4. PG

      Jan Jadud December 23rd

      Not exactly:
      http://en.wikipedia.org/wiki/Multitier_architecture

      read about the difference

      ( Reply )
  5. PG

    crysfel April 14th

    this is the MVC pattern!!

    ( Reply )
  6. PG

    Roosevelt P. April 14th

    Very good article, it will help new developers a lot.

    Perhaps you should go over MVC in your next article :) .

    ( Reply )
  7. PG

    Steve April 14th

    This looks like it’s Model-View-Presenter pattern, although there’s good arguments for preventing model access within the view (presentation tier) which is what MVC does.

    Good article though, MVP or MVC is still much better over jumbled way.

    ( Reply )
  8. PG

    Steve April 14th

    Actually, I think I got my MVC and MVP’s confused. It should be the other way around :/

    ( Reply )
    1. PG

      Wassim April 14th

      MVP stands for Microsoft “Most Valuable Professional” :D

      ( Reply )
      1. PG

        sai April 15th

        sdf

      2. PG

        Neil April 15th

        or Model View Presenter

  9. PG

    jimmy April 14th

    Look into PHP MVC frameworks like CakePHP and CodeIgniter. They pretty much achieve what you’re discussing here.

    ( Reply )
  10. PG

    Wassim April 14th

    Hey Jason

    One thing for sure: there’s no “ennui” reading your article ;-)

    Thanks for the post.

    ( Reply )
  11. PG

    Johan April 14th

    Is printf really the best way to deal with errors?

    ( Reply )
  12. PG

    Jarryd April 14th

    Lol I was hoping I wouldn’t be the only one to pick up this is MVC. Great article.

    ( Reply )
  13. PG

    Derek Reynolds April 15th

    You should definitely mention MVC somewhere in your post. It’s a well documented pattern.

    This serves as a great introduction to this style of development, and people should definitely look more into MVC now that they have their feet wet.

    Great article!

    ( Reply )
  14. PG

    Dave Kennedy April 15th

    I wondered what tiered programming was, as I had never heard that expression. But it is a good article for folk just starting in PHP and still doing the page controller style of programming. The frameworks are great for starting up large projects quickly. But for a smaller projects you could simply use a template engine like smarty.

    ( Reply )
  15. PG

    Gaya April 15th

    Nice article!
    It does have a lot of the principles MVC has to offer.
    For the presentation layers I’d recommend using Smarty though. This keeps the presentation away from the PHP code. Smarty is a nice way for designers to take part in the development and makes you write better business layers.

    ( Reply )
  16. PG

    Gilbert April 15th

    I’d just like to point out that this is not MVC. In this example the presentation tier acts as the controller which is not the case for MVC (the controller and the view are separate).

    I must say I would encourage people to use MVC over this. There are some great frameworks out there (ie. CodeIgniter and CakePHP) which use a MVC structure and force you to structure your code well.

    Anyway nice article. A good introduction to structured programming patterns.

    ( Reply )
  17. PG

    Jonas De Smet April 15th

    Why aren’t you writing your presentation layer more the “template” style:

    Looks a lot nicer and easier for people to read ;-)

    ( Reply )
    1. PG

      Jonas De Smet April 15th

      Looks like my PHP code didn’t render :(

      ( Reply )
  18. PG

    Andri April 15th

    is there any difference with MVC programming?

    ( Reply )
  19. PG

    G F Mueden April 15th

    My old eyes love it when my XL & IE7 can override incoming styles and use a font of my choice. In your programmng, please don’t interfere with its ability to do it. ===gm===

    ( Reply )
  20. PG

    Yoosuf April 15th

    DBP, nice stuff. its really awesome article for a beginner who is looking forward for MVC

    ( Reply )
  21. PG

    Shane Sponagle April 15th

    Great article. :)

    ( Reply )
  22. PG

    Patrick April 15th

    Huhm, nice article für beginners. It shows the right way to code php. It’s another way to explain the MVC-technology – so, it might be a good idea to write this also down – nice and quickly.

    And: There are so many possibile improvements to the code in this article… Why don’t use an own MySQLi-Class to connect to the Database? why don’t use defines for mysql logindata?

    In your code you show, that you have to call in every database-function the mysqli-connect and mysqli-close function. That’s a really bad bad idea. Someone could think, that’s the only way to connect to the database, and that’s not right. Best way, i think: Open MySQL-Connect at the beginning of the script (use an own mysql-connect class), close connection at the end of the script.

    It’s a good, easy to understood beginner tutorial, that’s a fact. But why don’t showing beginners how to code relly right?

    ( Reply )
  23. PG

    Steve April 15th

    Nicely illustrated!

    ( Reply )
  24. PG

    myDevWares April 15th

    Very, very useful tutorial, NetTuts, this will DEFINITELY come in use while developing my latest project.

    I would love to see a post detailing how to use the Smarty template engine, including resources, tools, etc…

    ( Reply )
  25. PG

    awake April 15th

    Nyce…

    what app did you use to create the diagrams in the “why should I care” section?

    ( Reply )
    1. PG

      Jason Lengstorf April 15th

      I actually just used Photoshop. :)

      ( Reply )
  26. PG

    Taylor Satula April 15th

    Well it sure was readible. I dont really do much PHP and totally understood the code. Reading about it directly in the code helped too

    ( Reply )
  27. PG

    Jase April 15th

    MVC is an example of a tiered application, not the other way around.

    And this is not really MVC, but is a standard multi-tiered approach.

    Data and Business Logic are totally separate in this sense, not just some abstract “model”.

    ( Reply )
  28. PG

    SX April 15th

    With this you would still have to create different functions if u wanted to get different data out of the same table or database. You still will end up with lots of different functions.

    ( Reply )
  29. PG

    Diego Machado April 15th

    Great Jason !
    Just learned mysqli and clarified PHP MVC in a row !

    Thanks from Brazil :)

    ( Reply )
  30. PG

    Jason Lengstorf April 15th

    Thanks for all the comments, everyone!

    I didn’t talk about MVC because I wanted to approach the “why” for separating different types of logic rather than asking readers to agree with a particular pattern before deciding whether or not the article was useful. The comments that said I should have mentioned MVC in the article are probably right, though; it wouldn’t have hurt to add that as a “further reading” sort of thing.

    Thanks again for the comments. Feel free to find me on twitter (@jasonatennui), I’d love to chat. :)

    ( Reply )
  31. This is the way good programming should be done!

    ( Reply )
  32. PG

    Artem Daniliants April 17th

    Good introduction if you are new to PHP, but in the long run I suggest using some sort of framework that creates separation for you and forces you into right mindset.

    I personally like Kohana ( http://kohanaphp.com/ ) framework for PHP5.

    P.S. I personally moved away from PHP to Django ( http://www.djangoproject.com/ )

    ( Reply )
  33. PG

    Bryan P April 18th

    The programming structure looks like OO because of the high separation and modularity but its not.

    Why did you choose not to go fully OO?

    ( Reply )
  34. PG

    lnjamadar April 22nd

    very good and useful ..

    ( Reply )
  35. PG

    msyaronlive April 28th

    good sayt for zwaj .msyar.almsyar

    ( Reply )
  36. PG

    Ruben Vincenten May 2nd

    That’s exactly as you should always write your applications… Or you could go further and implement OOP

    ( Reply )
  37. PG

    Mahbub May 3rd

    I’m surprised to see that you didn’t even mention the MVC pattern. It’s exactly the same as you have described.

    ( Reply )
  38. PG

    waseem May 5th

    this is wonderful tutorial .. i read it 3 times and get a fantastic results and sure i put a
    copy of this lesson on my site here

    ( Reply )
  39. PG

    Parbir Sandhu June 19th

    MVC versus Tiered Application programming. There’s a lot of difference between the two. MVC is a basic Application development Pattern whereas Tiered Application design is what an Architect is thinking about – (with boxes and arrows, for modules of functionality) breaking an Application down into tiers of functionality thereby decoupling components into separate independent functional units. For Example – Messaging, using of federated databases, SOA etc
    The MVC is – what the developer codes to, whereas the Tiered approach is more on the lines of what the Architect follows

    Hope I have been able to hold the candle to the above so often repeated comments citing the two to mean the same- wheras they are not.my_2_cents

    ( Reply )
  40. PG

    wqewqeqwe June 20th

    ( Reply )
  41. PG

    Ahmad Shukr July 10th

    Great articles ! Thanks.

    ( Reply )
  42. PG

    albertomarlboro September 17th

    Nice article, very clear and easy 4 understand

    ( Reply )
  43. PG

    Jarod October 28th

    Nice post, I learned something today =]. I must say though, the code (database tier) is a bit confusing when u implement it at the end (with the presentational tier). I sort of got lost when u instated the getDataFromDB() with no parameters in the presentational code. I still am though haha, but i get a wierd feeling I somehow understand it however *lol*. Like I’ve said though, this is cool <3.

    ( Reply )
  44. PG

    sarwara November 21st

    that was very useful post, and its definitely not MVC, there are many differences in the core, and still for all those who think MVC is the wtg, think again, not everything fit everywhere, web development is pretty different field than other fields in many respects. well that was for my two cents, not that I am saying MVC sucks or anything, just that its just another way to achieve it ;)

    I am definitely going to use it in my next project :D

    ( Reply )
  1. Arrow
    Gravatar

    Your Name
    November 21st