By Robert Peake
I love classes -- and I don't just mean rooms with uncomfortable desks. When I was studying Electrical Engineering and Computer Science at Berkeley the "Data Structures And Advanced Programming" course was taught entirely in Java 1.1. That's when I first met classes. My code has never been the same.
Back in those days I was writing CGI applications on the web in source-compiled C. My fascination with the potential of the web kept me up through some long dark nights writing C data types called "structures" to accommodate my rudimentary web applications. (For gory details, see the Dialogs project at http://www.robertpeake.com/archives/progra...ogs/index.html).
Lately, I code in PHP.
Strangely enough I find myself facing many of the same issues in PHP that I face in writing poetry (which, incidentally, is what I ended up getting my degree in from Berkeley -- but that's another story). There is a certain feel to poetry that has grown up in academic circles and a certain feel to street poetry (sometimes called "spoken word"). Likewise, coders that have dived into PHP head-first write a different kind of code that coders who stepped through formal training. Not necessarily worse on either count -- just different.
Each group can learn from the other -- about structure and inventiveness; tried-and-true practices and cutting-edge designs; form and fluidity. Today I hope to contribute a few more steps to that ongoing dance.
One of the major oversights I see from coders that learned PHP on the street is a lack of understanding about the power of PHP classes. A recent article (http://www.melonfire.com/community/columns/trog/article.php?id=122) explains to call Java classes to make use of existing Java code. But what about writing your own classes -- not in Java, but in PHP?
Why, after all, would anyone want to go to all that trouble?
I went to that trouble when I wrote the webrings class for distribution on the PHPClasses web site. For purposes of this article, I will use snippets of this code to illustrate the power of classes. Then, I will give you a real-world example. I won't be giving you a lot of code in this article, since the point isn't really to explain the webring class but to use the class to explain classes. If you would like to explore the code itself in greater detail, the complete source code is still available from PHPClasses at http://phpclasses.upperdesign.com/browse.html/package/114.
1. What is a data structure anyway?
Called "structs" for short in C (since everything is called something for short in that character-miserly language) -- structures are simply a place to put data. The difference between a file (or even an SQL database) and a data structure as defined for our purposes is that a file lives outside a program; a data structure live inside. The most common type of data structure in PHP is an array. Other fun types include hashes and keyed arrays. These usually get the job done for putting in and taking out data in simple ways. But what happens when you want to get fancy about the way the data goes in or comes out? Enter structs. Enter classes.
C is a low-level language designed for speed and terseness. It is great for things like drivers where every byte counts, or intense 3D games that squeeze every optimized flop out of your CPU and video card. PHP sacrifices some of this control to be a higher-level language (which doesn't mean it's necessarily more enlightened). This simply means that you can write applications more quickly without having to load in a lot of libraries from other programmers to get the job done. A function that pulls data out of a MySQL database and display them as an HTML table, for example, is standard in PHP4. I can't tell you how much hair I lost designing these kinds of functions from the ground up in C.
The advantage of C being low-level is that you can detail out data structures. This has been a point of snobbery against higher-level languages like PHP and (incidentally) Java. But Java was never designed for speed and detail -- it was designed for portability. And PHP lives on the web, where a sleek GUI is far more important than O-of-1 data access algorithms (http://www.wikipedia.org/wiki/Big_O).
But just because PHP isn't built for structuring data like C doesn't mean it isn't capable of handling some unique data problems. Classes can help create a layer of abstraction (http://www.wikipedia.org/wiki/Abstraction_in_object-oriented_programming) between you and the data you are manipulating to simulate a struct. It won't be as fast, but it can be just as satisfying. I'll show you how.
2. So you want to build a concept
How does a webring work? Simple: it loops. When you get to the end of the links you clicked on, you go right back to the beginning.
Unfortunately there are no functions in PHP that say, "when you get to the end of the data you were looking at please go back to the beginning." Most data types just quit. Sure, you can rewind an array or start your index value back at zero again. But this is thinking in an application-specific way. With classes, you can start thinking conceptually. You can actually build a "loop." I called mine a "loopedArray."
The most important piece of the loopedArray class is this one:
// elementat returns the element at the index of the loopedArray, looping // such that (n*sizeof(loopedArray) + k) returns the same element as k // for all integers k, n. Returns false if loopedArray is empty.
Yes, I know this is a comment block. It is also the crux of the class because it tells you what to expect.
You can call indexes on this array that don't exist -- and not expect an error message. How's that for fancy? And the data you will get back is predictable. Here's an example:
Suppose you want to build a loop with 8 elements in it. What happens when you call loopedArray->elementat(8)? (Remember that an array starts indexing at zero.) According to the comment block, you get the first element. The function starts over at the beginning, simulating a ring-like data structure.
3. From concept to application
The feature most touted in object-oriented design is not the ability to simulate data structures. It's inheritance (http://www.wikipedia.org/wiki/Inheritance_in_object-oriented_programming). The loopedArray class gives us a loop concept for storing data. Now how do we make a specific package to deal with webring URLs? This line:
CODE
class webring extends loopedArray {
that makes it all possible. By extending a class you inherit all the functions and variables of that class. So when I'm writing my webring class I now have access to useful functions like elementat(). All I need to do is write functions to get the urls into the array and functions to access these urls (which are really just redefinitions of the data access functions already at work in loopedArray).
This particular inheritance illustrates another important concept: data independence. I chose to use a file (called webring.urls) to specify all the URLs in the webring. But because the loopedArray class has already done most of the work, it will be very easy for me to instead choose to push and pull this data into and out of a MySQL database, parse out some XML from a web service, or anything else. Furthermore, because I distribute the source code, anyone can modify the webring class to suit their tastes with a minimum of fuss.
The results? Almost a year after publishing the webring class I got this email from a total stranger:
QUOTE
Robert,
I found and downloaded your webring files. I wanted to thank you, they work well. I had downloaded several cgi scripts that I couldn't get working at all.
I like your files because they give me a little better control and flexibility.
Tim Kendziorski
Vice President, Webmaster
Astronomical Society of Nevada
I found and downloaded your webring files. I wanted to thank you, they work well. I had downloaded several cgi scripts that I couldn't get working at all.
I like your files because they give me a little better control and flexibility.
Tim Kendziorski
Vice President, Webmaster
Astronomical Society of Nevada
Tim has since replaced his webring (which was Flash-based and animated and, frankly, cool) with a more comprehensive webring service that provides directory listings, categories, and the like. But his appreciation at the time of my efforts at making the class accessible ("...better control and flexibility") made every line of code well worth it.
4. Conclusion
The PHP community is unique in that it offers great potential for people to share ideas in the form of code. Few languages (since Perl) have generated as much enthusiasm and participation.
More important even than specific applications, ideas (like, "a loop") can be encapsulated in PHP classes. With a well-written guide to using this idea, other programmers can take them and run. (This is a shameless plug for commenting your code.)
Ultimately, the best code is the kind that works. But "working" in a functional sense doesn't always mean that the code will be easy to maintain or even understand by other programmers (or your own self years later). Well-conceived classes can help you on your way not only to writing more elegant code, but to communicating with the greater community at large.
Hopefully this article has provided you with some introduction to the usefulness of PHP classes. I have also tried to intersperse this article with some programming concepts that will help every coder on his or her way without getting too academic. If you want to know more about a particular term, check out the URL in parentheses next to it.
Happy coding!
About The Author
Robert Peake used to teach programming languages at Berkeley before he got his degree in poetry. These days he is a freelance web designer, programmer, and web technology consultant. Robert can be reached via email: robert@peakepro.com.