It can be intimidating to think of all the operations in the "Spy Master" system. The program has a lot of functionality. It could be overwhelming to start coding this system without some sort of strategic plan.
There are many approaches to complex programming problems. For this particular problem I decided to concentrate on the flow of data through a series of modules. Figure 10.10 shows my overall strategy for the program.
The illustration in Figure 10.10 is sometimes called a state diagram. This kind of illustration is used to identify what particular problems need to be solved and indicate modules which might be able to solve these problems. I began the process by thinking about everything that a data management system should be able to do. Each major idea is broken into a "module." A module often represents a single screen. Often (although not always) each model will be supported by a PHP program.
Obviously, users should be able to get queries from the database. This will be one of the most common tasks of the system. I decided that the "View Query" module should be able to view any query sent to it and display an appropriate result.
The other primary task in a data system is data definition, which includes adding new records, deleting records, and updating information. This kind of activity can be destructive, so it should be controlled using some kind of access system. All data definition is based on the underlying table structure of the database, so it is important to allow the three main kinds of data definition (editing, deletion, and updating) on each table. The "Edit Table" module provides the interface to these behaviors. It shows all the current records in a table and lets the user edit or delete any particular record. It also has a button that allows the user to add a new record to this table. It's important to see that "Edit Table" doesn't actually cause anything to change in the database. Instead, it serves as a gateway to several other editing modules.
If you look back at the state diagram, you'll see the "Edit Table" module leads to three other modules. The "Edit Record" module shows one record and allows the user to edit the data in the record. However, the database isn't actually updated until the user submits changes, so editing a record actually requires a two-step process. After the user determines changes in the "Edit Record" module, program control moves on to the "Update Record" module, which actually processes the request and makes the change to the database.
Adding a record is similar to editing, as it requires two passes. The first module ("Add Record") generates a form that allows the user to input the details of the new record. Once the user has determined the record data, the "Process Add" module does the actual SQL necessary to incorporate the new record in the table.
Deleting a record is actually a simple process. There's no need for any other user input, so it requires only one module to process a deletion request.
The state diagram is very helpful, because it allows you to see an overview of the entire process. More planning is still necessary, however, because the basic state diagram leaves a lot of questions unanswered. For example:
Will the "Edit Table" module have to be repeated for each table?
If so, will we also need copies of all other editing modules?
Is there a way to automate the process?
What if the underlying data structure is changed?
What if I want to apply a similar structure to another database?
How can I allow queries to be added to the system?
It is tempting to write a system specifically to manage the spy database. The advantage of such a system is it will know exactly how to handle issues relevant to the spy system. For example, operationID is a foreign key reference in the agent table, so it should be selected by a drop-down list whenever possible. If you build a specific module to handle editing the agent table, you can make this happen. However, this process will quickly become unwieldy if you have several tables. It would be better to have a "smart" procedure that can build an edit screen for any table in the database. It would be even better if your program could automatically detect foreign key fields and produce the appropriate user interface element (an HTML SELECT clause) when needed. In fact, you could build an entire library of generic routines that could work with any database. That's exactly the approach I chose.
Although the "Spy Master" program is the longest in this book, you'll find that most of it is surprisingly simple. The centerpiece of the system is a file called "spyLib.php." This file is not meant to run in the user's browser at all. Instead, it contains a library of functions that simplify coding of any database. I stored as much of the PHP code as I could in this library. All the other PHP programs in the system make use of the various functions in the library. This approach has a number of advantages:
The overall code size is smaller since code does not need to be repeated.
If I want to improve a module, I do it once in the library rather than in several places.
It is extremely simple to modify the code library so it works with another database.
The details of each particular module are hidden in a module so I can focus on the bigger picture when writing each PHP page.
The routines can be re-used to work with any table in the database.
The routines can automatically adjust to changes in the data structure.
The library can be readily re-used for another project.
Figure 10.11 shows a more detailed state diagram.
As you will see when you begin looking at actual code, most of the PHP programs are extremely simple. They usually just collect data for a library function and send program control off to that function, then print any output produced by the function.