Tutorials Home

Web Application Tutorials in PHP

Developing a functional rapid prototype in under 100 lines of code

1/17/2006

Functional Prototyping

We have all been there: the requirements were signed by the client with excitement, we deliver the product and the client's idea was nothing like what was delivered. Most of our clients just can't understand what the product will be like from the requirements documents. For some reason, they just aren't able to determine how it is really going to play out from a series of UML and use case diagrams, can you believe it? Many web site creators have been creating web based mock-ups to be able to paint some of the requirements visually to allow the client to react yielding more accurate specs. Most of these mockups are visual requirements with something tangible and sometimes even functional. Something the client can look at and play with. But if we take it one step further, functional prototypes can truly show off the specs even clearer. Functional prototypes can increase the productivity of the software development process immensely. If many of the requirements are spelled out in the prototype, the client can have a visual concept of what they will see when the product is developed. The problem with this concept is having your developers build a system before the requirements are accepted and running the chance of spending too much time developing something that may change drastically in the future.

As our development processes evolve to be more efficient, some truly great practices have be born, one very common to us web developers that we hold dearly to our heart is known as MDA. The Model Driven Architecture, is something that web developers have found to increase the time of application development by leaps and bounds. With the dreams of hit-ting the magical red game show button and instantly having all of your system requirements turn into functional code, rapid functional prototyping is very much a reality in the PHP world.

Successful software projects usually have a strong prototype that the client can see and even interact with. I.d say in the past few years that the most amount of time I spent during the design stages of a web project is focusing on the data model. This is the core component to most web applications and can make or break the software. The data model holds a lot of information about our applications, it has a list of fields and knows which ones are required and which aren.t, it knows how much data it should have for each field, and it also knows what entities in our application have relationships to one another. So, if the database knows so much about our application, wouldn.t it be nice if we could load up some software that would develop a functional application based on the data model? Something that includes forms for working with the data, an html table to view all the records in the table and a way to process the data from the forms into the database, this is after all what these mockups look like. Or is it just that easy?

Prototyping Essentials

Developing a prototype that a client can interact with can be a painstaking experience, it usually involves a lot of copying and pasting and creating static web pages that are very frus-trating to work with. Functional prototypes that are automatically generated from an existing data model can save an enormous amount of time in creating the mock-ups and are incredi-bly easy to modify. A prototype that can change with your data model, the model that holds many of the requirements, can allow for quick turn around on changes and modifications. Often the development team can work directly with the client or project manager and make the requirement changes to the live prototype allowing for a hands-on process with the cli-ent. The development team can implement much of the requirements in the database and update the model as they evolve with the prototype showing the evolution in real time. The client can get early access to a system that mimics the requirements and the beginning phases of the development process can happen in a much more rapid timeline allowing for higher performance and productivity from the development team. This quicker turn around will make the client much happier and allowing you and your team to move through the process very quickly. It.s a win-win situation.

Model-Driven Architecture

When designing a web application, commonly we tend to start with the data model design, this allows the developer to have a concrete grasp on what entities lie in the system and how they relate to one another. The model-driven architecture, which is controlled by the OMG, a community on standardizing practices for object oriented programming, is designed for object oriented programming, but can map very well to PHP programming practices. This approach to software design is a method for developing software based on a platform-independent model, commonly a relational database or an XML file in the PHP world. The MDA approach allows for the practice of automatic code generation, allowing the software to build itself based on a common model. With this approach, we can easily generate this functional prototype very easily and allow it to change as the requirements become more and more specified. The concepts are fairly simple when looking at it from a high level, the data model maps directly in a one to one fashion to the object model. For example, if we have an application that is meant to act as a resource management system, in this application we would most likely have a table that acts as an inventory of our resources. This table would then map directly to a class with all of the member attributes mapped directly to the table in the database. You can see a comparison of the database table to the mapped object in List-ing 1.

From this example we see a table in a database on the left called Resource and it has a few fields, on the right we see a class that looks very much like the table we created in the data-base and has the same set of fields. With this one-one mapping we can quickly create an en-tire set of classes that match our entities in our data model.

In the next few sections of this article, we will show you how to create your object model and the functional web applications using many well-developed PEAR packages.

Stage Left, Enter PEAR

The goal of PEAR is to offer a collection of high quality peer-reviewed libraries that PHP developers can utilize in their applications to save time with creating both basic and ad-vanced common features such as user authentication systems, database abstraction and XML processing. As I would sure hope that many readers of this article are already familiar with the basic PEAR packages, and for those of you who are not familiar with the full gamut, I highly suggest that you peruse the package list to see what is available. Many of these pack-ages are well-developed due to the peer-review process the PEAR Group members have set forth and can help increase productivity. For the purpose of this article we will focus on some of the Database and HTML libraries.

Our saving grace for this wonderful magic button application is the DB_DataObject pack-age. This package has many purposes: it offers a code generator, a SQL builder, as well as an object oriented approach to handling data from a database. The truly wonderful feature is the class generator as it pushes us to implementing a Model-Driven-Architecture and brings us one step closer to a world with the magic game show button. Since DB_DataObject is an extension to the beloved PEAR::DB class, we can hookup to just about any one of the popular relational databases that are used in many PHP-based applications. Packaged in with the DB_DataObject classes is a script called generateTables.php. This script requires an ini file that has your database connection string in it. The DSN, or Data Source Name, is a string that allows the DB_DataObject class to connect to your database. For example, if you were connecting to a MySQL database, the string would look like this:

mysql://username:password@example.com:3306/mydatabase

So let.s see what the entire ini file will look like:

[DB_DataObject] database = mysql://username:password@localhost:3306/mydb class_path = /www/html/myproj/myclasses config_path = /www/html/myproj/config

Once you have configured your ini file, your object oriented application will be born. It.s as simple as running the following command:

php /pear/DB/DataObject/createTables.php /www/html/myproj/myproj.ini

To see what one of these generated classes might look like, refer to Listing 2.

This generated code is a class that extends the DB_DataObject class. This example shows that I have a class called Resource with a few attributes. The parent class gives this generated class life, providing many sql based methods such as insert, delete, update, etc. This is also helpful for those who are inexperienced in sql development; you can simply work with the sql wrapper methods and not use any sql code. It also has generated a method called staticGet directly in the generated class, this is something that we will use later on and can be very helpful. What is also nice about the code generator, is the ability to add methods and attributes to the class and then rerun the generator with out loosing the custom code. So once I have designed my database I can begin to generate my classes and build my object model. Now if you are not an object oriented programmer, don.t be feared by the use of ob-jects, we can still use them in a procedural style.

So that was fairly easy, I designed and implemented my database and then ran a script that generated my classes.

The Data Model

As I mentioned earlier, all of the code generation was accomplished by designing my data-base first. The MDA approach shows us how important this step is. Designing a fully nor-malized data model allows us to have a well designed object model due to the one to one mapping. If something changes in the requirements phase, we can simply make the adjust-ment to the database and then rerun the code generation script. No coding needed!

The database holds information such as whether the field is required or not by the use of a nullable or non-nullable field setting. It also knows how much data and of what data type the field should be based on the data type and size specification. It can also hold in-formation about our entity relationships based on the foreign key constraints in the data model. Our forms that are generated will know what to validate and what not to validate as well as what type of html form element to use. Having all of the specifications set in the very early stages of our software develop process will allow us to automatically generate this pro-totype and allow it to be functional!

The Prototype

Now that we have the plumbing built, I.d like to be able to begin with the visual ele-ments of the prototype so I need to begin to build the interface. For displaying of the data model we are going to use the PEAR package known as Structures_DataGrid, or SDG for short. SDG is a library that was based off of a control in the .NET framework known as the DataGrid control. I am the author and maintainer of this package, so I understand it.s po-tential due to the modularity that is built into this package. I created this class to mimic Mi-crosoft.s DataGrid control that I learned to love so quickly in my C# programming experi-ences. Having the ability to bind a control to a data source and generating a fully functional table is so useful to the web development community. This PEAR package allows a PHP developer to show their dataset in a web page or in a multitude of other formats such as a spreadsheet or an XML file fairly simply. It also can use any common data format such as an array, or result from a PEAR::DB query, but what we are concerned with is our recently generated DataObjects. We can see how this is done with the code that we need to create shown in listing 3.

With these few lines of code, I have now built the basics to my prototype. Since I did not specify any parameters in the constructor, it will default to output the data in an HTML ta-ble, but by specifying an output option, the datagrid will be rendered in the specified format. If you have some data that you added to your database, you will see that what is generated is not pretty in anyway, but we were able to create a viewer to the database in just a few simple lines of code. Now if you really feel that you should spruce it up a bit, you do have a few op-tions. With SDG you have the ability to define the columns as well as assign a style sheet and assign some html attributes to give it a custom look and feel. Since SDG is modular, it will allow for different input and output types with the use of drivers. I can modify the output, known as the renderer class, to add my html attributes. To see how this is done, take a look at Listing 4.

Now my table has a grey header and a style sheet to control the design. The easiest way to control the look and feel for the datagrid is to use style sheets, but to illustrate the example, I have included how to enter in the html attributes directly.

One of the really helpful features of SDG is the paging features. With direct integration with PEAR.s Pager package, we can specify how many records should show on a page. And just like the renderer class, I can customize the pager.s output by defining all of the options that I want and how it should look. So let.s limit our datagrid to 20 records per page, you will see this done in Listing 5.

As you can now see, I added the number 20 to the constructor of the datagrid and added a line at the bottom to print out the paging string. Since SDG uses the existing PEAR::Pager package and not a custom pager class, you can use the options that Pager offers to customize the paging results or define your own implementation of the Pager classwith the use of the setPager method. If you really want to get fancy with the SDG package you can create your own custom renderer and data source drivers and plug them in very easily.

The Form Builder

The quintessential piece to our puzzle is the PEAR::DB_DataObject_FormBuilder package. Obviously, by its name, the goal of this package is to generate an HTML form based on a DataObject. As I mentioned earlier, our data model holds so much information about our software. Since most of the data model.s meta-data is now in our generated DataObjects we can now generate our forms using this information. In Listing 6 you can see an example of how this might be done.

From this example, we see something very similar to the example with Structures_DataGrid, we connected the FormBuilder class with our DataObject and rendered the output. I also have the values for this record pre-populated assuming that I accessed this page by clicking on a record from the viewer. You can see that I got the data by using the staticGet method; I defined the column .id. and the value for this column and DB_DataObject automatically populated the class attributes with the appropriate data. FormBuilder will then generate an HTML form based on the attributes and their meta-data. It knows which fields are required and which aren.t. So if we take a look at our output, we notice that it is fairly basic but al-ready has some nice features such as form validation. But, it would be nice to have drop-down boxes for our foreign keys and maybe a textarea box for the long description, in List-ing 7 you can see how to do this.

Here you see how I added some FormBuilder variables to the Resource class to make our forms a bit nicer. I was able to specify the [format_id] field to be displayed as the term .Format. and also specified the description field to be a textarea box. With the Format class I was also able to specify the value to show for the foreign key relationship. However, to make the relationships work, I will need to define these since the DB_DataObject genera-tion script does not automatically generate any meta-data about my relationships. So let.s create a file called mydb.links.ini:

[resource] format_id = format:id

This ini file that we created looks very similar to an ini file that is generated along with our Class files. You will see that a file called mydb.ini, where .mydb. is the name of my data-base, is automatically generated and contains a listing of the tables and their fields. With this links.ini file, you can specify all of your relationships allowing the FormBuilder package to convert all foreign key relationships into select boxes.

So now we want to make our form functional by saving the data to the database. This is a very easy next step and you can see how this is done in Listing 8.

So now we have our prototyped forms that show us what data is required and what is op-tional, and what options we may have based on foreign key relationships for certain fields with the use of drop-downs. This form of instant prototyping is completely functional with all of the features you might expect to see in a full fledged application and in some instances can be used as an application rather than a prototype. The reason I suggest the use of this as a prototype and not an application is due to the server load since everything is generated during every visit. This issue might be solved with a caching implementation, but with all of these classes combined, the application may not scale as well under heavy use.

Prototyping 0-60

Utilizing these PEAR classes allowed us to easily create a functional prototype with very few lines of code, it can easily be done in less than 50 lines. It allows us to easily modify the un-derlying data model and see the changes in an instant fashion. All of the packages that we discussed in this article allow for further extension and customization above and beyond what was discussed. Both the DataGrid and FormBuilder packages have endless possibilities with customizations and custom modules to plug-in. This technology can allow for a rapid prototyping process to easily be implemented and can truly enhance the software develop-ment process and allow for a higher level of productivity and increased project turn around.

Last Updated: Monday, March 3, 2008 at 10:20pm

Get Firefox!