Keeping it Small and Simple

2007.06.12

Building an object model in PHP #1: A database combo

Filed under: Object-oriented programming, PHP Programming — Lorenzo E. Danielsson @ 00:29

These days it seems to be increasingly common to hate PHP. If you look at some of the PHP code that has been written, perhaps one can understand why. But PHP code doesn’t have to look like a mess. In this series I will show you how to evolve an object model in PHP.

It may very well be that PHP sucks, but that is of no concern to me. PHP exists and I am interested in programming. I aim to teach you how it can be used. I assume you can figure out for yourself whether or not PHP is a good tool for whatever task you have.

What we are going to do is develop a fragment of an object model representing HTML elements. I know, it has been done already, and a number of times. Some of the implementations are much better than I could ever hope to accomplish. But we are learning, so we don’t really care about that. We will place ourselves in a possible world where no such model has been developed.

Experts in object-oriented programming know that the best worlds are the ones that are created by intelligent design. Normally this design is done using UML (the Useless Modeling Language), a tool created by a group commonly referred to as “the 666 Amigos”. UML is a part of a plot to take the fun out of programming.

Jokes aside, UML is a useful tool, especially when projects become large. But I am looking through the eyes of a programmer so I will not go into UML. If you are serious about object-oriented programming, then learning UML is not going to hurt you one bit. Go out and buy yourself a book on the subject.

As I am going to try to show off some OO techniques in PHP, I will occasionally take the OO concept too far. I will implement objects for just about everything. When you are back in the real world, you will have to judge how far it makes sense to use objects. It is very possible that in some cases it doesn’t.

A final note: I will be using some features that are only available in PHP5. You can do object-oriented programming in PHP4 as well, but it will look slightly different.

The problem

At this current point in time I’m not really interested in developing any object model at all. My problem is simple: I have been working on a web application for a while and I’m beginning to realize that I am doing a lot of CRYing (Constantly Repeating Yourself). Looking into the code a bit, I have noticed that I have quite a few database lookup tables. In my web application, I usually represent this as combo boxes (if you don’t like the word combo box then you may s/combo box/whatever you like/g).

These combo boxes have a few things in common. They are populated by simple SELECT queries that return two columns: an column that uniquely identifies the row (an ID column) and one that contains some form of textual representation of the row. For example, to populate a combo box showing departments within an organization I might use the following SQL statement:


select id, department from departments;

For people I might use:


select id, concat(firstname, ' ', lastname) as name from friends;

Furthermore I only have MySQL installed on my system. Any time I sell my application I install MySQL for the client. I have heard that there are other database servers out there but I am (at this stage) satisfied with supporting only MySQL. Not a single one of my clients has complained about it so far.

This gives us a starting point for developing a first class.

The combo box

Below is a first implementation of a combo box class.

<?php

class ComboBox {
    private $db;
    private $sql;

    public function __construct($sql) {
        $this->sql = $sql;
        $this->db = mysql_connect("localhost", "dbuser", "n0tap455w0rd");
        mysql_select_db("storage");
    }

    public function __toString() {
        $result = mysql_query($this->sql);
        $html = '<select>';
        while ($row = mysql_fetch_array($result)) {
            $html .= '<option value="' . $row[0] . '">'
                . $row[1] . '</option>';
        }
        $html .= '</select>';
        return $html;
    }
}

?>

As you can see, the ComboBox class currently has two methods: __construct and __toString. Both of these are special (PHP tends to use double underscore for special methods). The first one, __construct is the class constructor, that is the method that is run when a new instance of this class is first created. The __toString is used to convert an instance of this class into a string.

In the constructor we set up a connection to the database as well as store the SQL statement that will be used to populate the combo box. The __toString method simply returns the HTML to generate the combo box. Note that it only returns the HTML as a string. To actually make the combo box appear on a page you would have to echo the string.

There are a number of shortcomings with the ComboBox class as it currently stands. The database connection is hard-coded inside the class. There is absolutely no error-handling done. But at this stage I don’t care. Remember that the current requirement was just to create a re-usable combo box that gets its list items from the result of a database query. And it does just that, as long as we stick to one particular database.

We can test the combo box class with something like the following:

<?php
require_once("./combo.php");
$cb1 = new ComboBox("select id, department from departments");
$cb2 = new ComboBox("select id, concat(firstname, ' ', lastname) as name "
    . "from friends");
?>

<html>
<head>
<title>Testing: Combo box</title>
</head>
<body>
<p>Let's see if we can't generate a combo box or two.</p>
<?= $cb1 ?><br />
<?= $cb2 ?><br />
</body>
</html>

In order to get things working you will have to modify the connection statements in the ComboBox class as well as the SQL statements in the test page. The connection should be to a database that you have on your system and the SQL statements should select from tables in that actual database.

Conclusion

So far we have developed a single class, so we can’t really talk about an object model at all. In the next tutorial things will begin to change as I get a troublesome client who does not want to use MySQL. Also, I find myself wanting to be able to use the combo box in another web application, so there are more reasons to make the class more generic.


Update 2007.06.12: Fixed typo in title.

Advertisements

Blog at WordPress.com.