Intended Audience
Introduction
Who Writes Code Like This?
•  The Procedural Fanatic
•  The Objects Fanatic
•  And Never The Twain Shall Meet
What Are Your Directives?
•  Theoretical Directives
•  Practical Directives
When Is One Approach More Valid?
•  The Case For Procedural
    •  osCommerce
    •  phpMyAdmin
    •  Procedural - Conclusion
•  The Case for Objects
    •  Smarty
    •  FPDF
    •  OO - Conclusion
When Is Each Approach Useful?
Why Are Both Approaches Necessary?
Summary
About The Author

Intended Audience

This tutorial is intended for novice and journeyman PHP programmers who want to learn more about the issues surrounding object oriented versus procedural programming in PHP.

A working knowledge of PHP and a basic familiarity with classes is assumed.

Introduction

"True genius resides in the capacity for evaluation of uncertain, hazardous, and conflicting information." (Winston Churchill)

In PHP, unlike many other languages, you can choose between using an object oriented (OO) or a procedural approach. Most PHP programmers use a procedural approach by default, since web pages themselves operate in a very procedural way (this tag, then this tag, then this tag). Interspersing procedural code with HTML is more straightforward, and so PHP programmers often develop their own style, based on this approach.

If you are new to PHP, procedural programming is probably the only kind of programming you are familiar with. However, if you have been exploring the PHP community for best practices, by now you have probably seen posts in forums and newsgroups about "object bloat". You have probably also seen tutorials on how to write object oriented code in PHP. You may have downloaded libraries that employ classes, and learned to instantiate their objects and use their methods. Yet it is quite possible that you have never really understood when, where, or why it is appropriate to use an object oriented approach.

There is a certain amount of ranting on both sides of the issue, and slogans such as "Objects are bad!" or "Objects are good!" are sometimes heard. This article does not attempt to decide between the two approaches and come up with a single "best practice", but to explore the advantages and disadvantages of each.

Here is an example of a procedural program:

<?php

print "Hello, world.";

?>

Here is an example of an object-oriented program that achieves the same objective:

<?php

class helloWorld {
  function
myPrint() {
    print
"Hello, world.";
  }
}
$myHelloWorld = new helloWorld();
$myHelloWorld->myPrint();

?>


Note that this article will not attempt to define object oriented programming beyond saying that it is programming using classes. If you need a good introduction to the subject of OO, try Google. There are many, many good articles (and a few bad ones) out there.

Who Writes Code Like This?

In order to understand why this issue has become the subject of flame wars, let's examine some extreme examples from both ends of the spectrum. First we'll look at "the Procedural Fanatic" and then at "the Object Fanatic". See if any of this sounds familiar.

The Procedural Fanatic

The Procedural Fanatic was criticized by his computer science teacher for not using a more abstract approach. His argument, "But it works!", didn't improve his grade. Later, he went on to a career writing drivers, file systems, packetizers and other low-level programs, where his focus on speed and terseness gained him recognition.

Extreme examples of the Procedural Fanatic go a step beyond rejecting objects, and criticize abstraction itself. They are always looking for ways to make things faster, and don't care if nobody else can read their code. Often, they consider programming a competitive rather than a team activity. They like to enter obfuscated code contests. Their favorite languages besides PHP are C and Assembler. In the PHP world they might write PECL modules, contributing code that is efficient.

The Objects Fanatic

The Objects Fanatic recently discovered object oriented programming and is eager to put it to use - everywhere! The Objects Fanatic doesn't really understand the performance considerations behind his approach. It sometimes seems that he enjoys abstract design concepts more than actual code. He probably has a career in project management or documentation.

Objects Fanatics are quick to point out to the proceduralists that without abstraction we'd all still be using ones and zeroes. They are known to speak in pseudocode. Extreme examples of Object Fanatics go beyond coding on objects at the expense of performance - they do it at the expense of elegance and even readability. Their favorite language besides PHP is Java or Smalltalk. In the PHP world, they may write PEAR modules, contributing code that is well documented and easy to maintain.

And Never The Twain Shall Meet

Can you understand why forums are chock full of biased viewpoints? Your experiences, and the resulting philosophies you adopt, color your approach to new ideas. As programmers, we must constantly be aware of these prejudices and remain open to learning new things. As computer scientists, we must learn to set these prejudices aside and find the best methods for a given situation.

What Are Your Directives?

Consider for a moment what your directives are when writing a program in PHP. Often these directives are implied, sometimes even assumed. You may adopt the same directives for every project. One I personally strive for is elegance; I won't attempt to define "elegance" here, it may become a separate article. But other, more theoretical directives don't always lend themselves to decisions that are good for the project - the specific project - that is before you. They may, in fact, simply be prejudices.

Theoretical Directives

  • Provide a solution in as few lines of code as possible
  • Think about the problem at the level of the problem

They sound great on first pass, don't they? But what do we mean by, "as few lines as possible"? Do comments count? Should we string lines together separated only by semicolons? How about curly braces? Some people like to give them their own line. According to the mandate above, that's just wrong.

What about "the level of the problem"? Does that mean that for every concept involved in our solution we should create a class? Or maybe we should keep each piece of the problem in separate files, and create a complex file system tree that mirrors the real-world structure. That's it - a file and a class for every thought!

Obviously these generalizations, taken to extremes, become ridiculous. But there are more subtle manifestations. How often have programmers working in a team discovered and inserted a complex, powerful one-liner with no comment, only to baffle their teammates who later have to maintain the code? Conversely, how often have bureaucratic senior programmers run amok, creating interfaces and classes that pinch and restrict not only the implementation programmers below them, but the performance and flexibility of the program itself, when customers later want it to do something more? These are simply subtle manifestations of the same kinds of generalizations mentioned above, working subliminally in the minds of our all-too-human programmers.

Practical Directives

The solution is to look for the practical directives for a project first. What are the goals specific to the project? Here are a few possibilities:

  • Write quickly, release often
  • Make it run as fast as possible
  • Make it easy to maintain, distribute, and extend
  • Publish an API

The first two directives tend to favor a procedural approach, whereas the last two favor an object oriented approach.

When Is One Approach More Valid?

Now let's try and evaluate the practical advantages of each method.

The Case For Procedural

The fundamental argument in favor of procedural programming in PHP is that PHP is an interpreted language. This means that, unlike many languages, it is not compiled down to a binary executable, but is interpreted and executed on the fly. It is a scripting language and that script is stored in plain text. (Except, of course, when it isn't, a lá the Zend compiler tools).

There is also an argument against object oriented programming in PHP 4 and below, and that is that the object functionality in early versions of PHP was not well conceived. To hear Rasmus tell it, support for objects was almost an afterthought. This means that, for PHP 4 and below, objects are not as efficient as they could be. However, this is due to change with the release of PHP 5.

Two popular packages written mostly in procedural code are osCommerce and phpMyAdmin. They came into existence relatively quickly, and run relatively fast. Both packages are closely tied to HTML, mixing HTML and PHP in their code very freely.

osCommerce

osCommerce actually uses a lot of objects, but most of the work is done procedurally. I personally have hacked osCommerce into some very useful custom behaviors for clients - sometimes so useful that I wondered why these custom behaviors weren't part of the base package. However, I should mention that the process was not trivial. Much of the procedural code, because it was not separated out using a templating system, and because it was designed for multiple languages, took a while to get into.

Yet it works, and it works quickly and well for numerous e-commerce sites. osCommerce also provides a forum and a bit of a framework for developing modules and add-ins. As a result, there are many, many useful contributions to the cause.

phpMyAdmin

phpMyAdmin uses only one class directly: the Mimer SQL Validator class, which in the case of phpMyAdmin, depends on the PEAR packages Mail_Mime, Net_DIME and SOAP. This was probably a decision based on convenience: it served their purpose, so they put it in. Everything else seems to be procedural, and again HTML and PHP are interspersed.

phpMyAdmin is a tool I use almost daily. Furthermore, for simple modifications on single tables, I sometimes even encourage my clients to use it as a back-end administration tool. (Obviously, I limit their rights.) phpMyAdmin works extremely well and, considering what it does, it also works fast. I have often considered extending phpMyAdmin in some applications to serve as a back-end administration tool, leveraging some of its new features such as bookmarked queries to give my clients views and editors very quickly and easily. The code base itself must be reasonably easy to maintain as well, as it has evolved persistently with each new release into a more and more useable tool.

Procedural - Conclusion

The procedural aspects of both these packages are well documented and well commented. Providing a framework for developing add-ins also helps the maintainability and extendibility of osCommerce. Neither, however, has anything like an API for extending the package into something else entirely.

It takes a lot of work to turn osCommerce into an accounting package, and a fair amount of work to extend phpMyAdmin into a custom back-end administration tool. Yet what they are designed to do, they do very well indeed.

The Case for Objects

The argument for object oriented programming is all about extensibility and packaging. Simply writing in an object oriented way won't document your code for you, but it may encourage you to document it. And, for purposes of extensibility, you may find yourself writing an API.

PHP 5 promises to make object oriented programming much more pleasant. I like to jokingly refer to it as the "Java 2" release of PHP, because it incorporates so many of the features that work well in Java, including interfaces, an object reference model, and try-catch statements. But even in PHP 4 and below, there have been some excellent uses of PHP's object oriented features.

My favorite is Smarty, a templating system in PHP that helps separate code from content. Another useful example is the free PHP PDF generator written entirely in PHP called FPDF. Both can be used in a way that separates code from content, keeping the HTML code well apart from the PHP code. Most importantly, both can be extended into other useful applications.

Smarty

Smarty is a tool for creating complex forms and template-based sites. Most recently, I built an online testing system that is completely "skinnable" - that is, the look-and-feel of the site can be completely changed without changing any of the underlying functionality. To make the process of creating new "skins" easy for designers, I created a custom tag system that is an extension of the Smarty tag system, so that simply inserting:

[navigation horizontal separated by " | "]

at the top of a page will display a horizontal navigation delimited by bars. Because Smarty already provides very powerful mechanisms for displaying data contained in variables, this process is a simple matter of mapping more complex Smarty tags into simple skin tag directives. More information about this can be found at http://simpletags.sourceforge.net and http://simplequiz.sourceforge.net/.

Because Smarty is packaged as a class, and because its methods are well documented, it makes the process of working with templates incredibly easy to extend. Smarty also provides a layer of protection between all of the variables floating around in the PHP environment, by forcing you to explicitly pass to the Smarty template only the variables you are going to use. This kind of variable ecology helps enforce a secure, reliable working relationship between the designers who create Smarty templates and the programmers who feed them variables.

FPDF

FPDF is a great tool. If you have found yourself frustrated by the shifting API of pdflib and don't want to pay for a well-maintained solution - or if you just don't have access to the extensions your version of PHP can run, as in a shared hosting solution - consider using this free, pure-PHP, PDF generator[1].

The class is well documented, including lots of nice examples of how to lay out and flow text and graphics. On the same online learning site mentioned above I used FPDF to dynamically generate certificates of completion with true type fonts and 300 dpi graphics. The extra few seconds involved in instantiating the class and performing PDF operations in PHP didn't really make much of a difference, since the PDF itself could take minutes to download. In fact, the extra time to dynamically generate and send a PDF is often less than the time it takes for server on a slow connection to send out a static PDF file. It's all relative. Furthermore, because FPDF is class-based, it can be extended. Some methods, in fact, aren't even fully implemented but exist only as a framework and guidance so that you can create, for example, your own header and footer elements in your own subclass.

OO - Conclusion

Both Smarty and FPDF provide well-documented APIs for working with and extending their main class. This is the necessary conclusion of structuring methods and data inside a class in a well thought out way. While some of the same functionality could have been achieved using functions and global variables, it could not easily have been extended. Furthermore, it would be difficult to instantiate multiple instances of this functionality in the way you can instantiate multiple objects. These objects can be useful for keeping track of the style of PDF or HTML document you are sending out, so that you can publish the same data in a variety of formats.

These applications are excellent examples of the power gained by using classes to create a flexible, useful library.

When Is Each Approach Useful?

We have looked at which directives are best served by each approach individually. We have also explored some practical examples of real programs that use each type of programming effectively. But what happens when you have multiple directives?

Here is my advice:

  • Consider your directives.
  • Become aware of your theoretical biases.
  • Test out your assumptions.

Generic benchmarking reports of generic examples in object oriented and procedural fashion tell you very little about what to expect in your own unique application. Instead, find a benchmarking approach that you like, and use it to check whether you are actually fulfilling the directive of writing code that runs fast. Examine the functions that you are writing to see whether they need to share common data. Think whether there would ever be a case for extending them. Consider whether writing a class would be conducive to making your code extendable.

Above all, consider your directives on a scale. Weigh them out. By taking a practical, project-by-project approach to evaluating the usefulness of object oriented versus procedural programming you ensure a sober, informed decision. And remember, with PHP you always have a choice. You can even mix and match.

Why Are Both Approaches Necessary?

Returning to our fanatical procedural and object oriented programmers, we can begin to appreciate their merits.

  • We can thank the object oriented programmer for the utility and extendibility of Smarty and FPDF.
  • We can thank the procedural programmer for the fast, well-working osCommerce and phpMyAdmin.
This appreciation extends deeper as well, into some of the foundations of PHP.

Both PECL and PEAR have received much praise and much criticism. I think that the two projects provide a good illustration of the differences between procedural and object oriented programming.

PECL provides extensions to PHP that are written procedurally in C, designed for speed and terseness. Often, these are ports of existing LGPL software, and many interesting features have been added to PHP over the years using this approach. After all, PHP's foundations are in C.

PEAR contributes some very interesting classes for everything from creating Excel spreadsheets to modifying DNS records. Using PEAR class libraries can save you a lot of time and provide some very interesting functionality that may leave you saying, "I didn't know PHP could do that!"

Summary

Hopefully this article has given you a greater appreciation for the usefulness of each of the two programming approaches, and - more importantly - armed you with enough information and interest to explore these issues in greater detail. I hope that you will think for yourself, examining your project directives, checking out more real-world examples, and taking the good, bad, and ugly comments you sometimes hear about this topic with a grain of salt. Both approaches have their own advantages. So get out there and write some code!


[1] - There is a project under way that creates a PEAR implementation of FDPF.

About The Author

Robert Peake taught programming languages to computer science students at Berkeley before earning his degree in Poetry. He recently resigned as an IT Manager and took up consulting to spend more time with his family and PHP. He lives in Los Angeles with his wife, Valerie, and their two laptops.

Robert can be contacted at robert@peakepro.com.