Chapter 3. Servers, Databases, and the Web

Most of this book will be about the client side, as people think of Ajax as something that works specifically in the browser. Ajax definitely needs server support to work, though. So far, we’ve looked at the standards and technology that form the backbone of an Ajax web application, and how these applications moved away from the traditional web site model. Now, it’s time to turn our attention to the server side of things.

Servers still hand out all of the requested data to the client, so we cannot always focus on the client side. It is important to understand the different web servers, server-side scripting languages, and databases that are available to developers. How will you know which of these to choose? Well, the old saying “there is a place for everything, and everything has its place” has real merit here.

I cannot tell you which web server is better, or what language you should use, or which database is the best. Those are choices each developer must make. To make that process a little easier, I will provide information on all of these choices and how they relate to Ajax web applications, with the hope that you will be able to back up with hard facts whatever choice you make.

The fact is (and this is a good thing, really) that unlike on the client side, where you have to use XHTML or HTML, CSS, JavaScript, the Document Object Model (DOM), and so forth with no choice in the matter, on the server side you have many good choices to explore and vastly more opportunities to work with the tools you like and to avoid the ones that seem inconvenient.

Tip

If you want to jump into client-side implementation, skip ahead to Chapter 4. You can always return to the server side of the conversation.

The Web Server

Only two servers are widely used on the Web today: the Apache HTTP Server from the Apache Software Foundation (http://httpd.apache.org/) and Internet Information Services (IIS) from Microsoft (http://www.iis.net/). At the most rudimentary level, both of these HTTP servers function in the same basic way, as shown in Figure 3-1. A client browser requests information from the server in the form of an HTTP request. The server responds to the request by sending an appropriate response, usually in the form of an XHTML document, an image, a raw text file, or some other type of document. If the request is bad, the server’s response is in the form of an error.

The typical model for an HTTP server

Figure 3-1. The typical model for an HTTP server

According to the July 2009 Netcraft Web Server Survey (http://news.netcraft.com/archives/2009/07/28/july_2009_web_server_survey.html), Apache had a 51.12 percent market share, whereas Microsoft had 23.99 percent (this is a combination of all servers using Personal Web Server, both PWS and PWS-95, and IIS, both IIS and IIS-W). This doesn’t automatically mean that Apache is better than IIS. For one thing, Apache has been around longer than IIS, giving Apache an edge since it’s already been integrated into a lot of systems. For another, Apache is open source software, and it is free. IIS only comes prebundled with the server versions of Windows and cannot be downloaded separately. Finally, Apache runs on pretty much every operating system out there—Windows, Mac OS X, and all flavors of Linux and Unix. IIS runs only on Windows.

But what is really important when it comes to comparing different software applications is looking at their features. Table 3-1 examines the features available with Apache and IIS.

Table 3-1. Web server features

 

Basic authentication

https

Virtual hosting

CGI

FastCGI

Servlet

SSI

[a]
 

Apache HTTP Server

Yes

Yes

Yes

Yes

Yes

Yes[a]

Yes

IIS

Yes

Yes

Yes

Yes

No

No

Yes

[a] Apache HTTP Server can integrate seamlessly with Apache Tomcat to provide servlet support.

Now, although security features such as authentication and https are important for a web server, because the topic is Ajax web applications our focus should be on what the web server can do for dynamic interaction. This is where CGI, FastCGI, servlets, and SSI come into play. All provide ways for the HTTP server to provide dynamic content back to the client.

CGI

The Common Gateway Interface (CGI) has been around forever. Well, since 1993 anyway. This was how dynamic content was served in the beginning, by accessing a program (usually written in Perl) that generated the requested content. The one problem with this technology is that it can overwhelm a web server if too many requests hit the server. This is because every CGI request generates a new copy of the program to be executed. How do we get around this dilemma? There are two ways, really. The first is to bone up on a compiled language such as C or Pascal. Compiled languages terminate faster, thus reducing the chances of server overload. The second way is through FastCGI.

FastCGI

FastCGI is a variation of CGI designed to reduce the load on the web server created by CGI’s multiple-process model. Instead of generating a process for each CGI request, FastCGI creates a persistent process that can handle many requests at one time. It does this by having the process use a multithreading technique that allows it to poll different connections virtually at the same time.

Unfortunately, as with CGI, FastCGI sees its best performance when the program is written in a high-level language such as C or C++. Yes, you can use it with any scripting language, and you can use it with frameworks such as Ruby on Rails and Django. I simply do not see the Web moving in this direction, though. Because Ruby on Rails, Django, and others (as you will see later in the chapter) can also use embedded interpreters, and because there are other methods of delivering dynamic content from the server, this is not as likely to pick up much steam. Remember that both of the major web servers do or will support FastCGI, so there is no reason to choose one over the other because of this technical factor.

Tip

The embedded-interpreter alternative to FastCGI is through Apache’s compiled modules. These include modules such as mod_perl, mod_php, mod_python, and mod_ruby, though others are also available. The downside to using these modules is that there is no separation between the web server and the web application.

Servlets

If CGI or FastCGI is not your cup of tea, another dynamic content approach is servlets, Java’s answer to the dynamic content problem. A servlet is a Java object that listens on the server for requests and sends the necessary response back to the client. You can create these servlets automatically when you’re developing using JavaServer Pages (JSP).

Servlets require a web engine, commonly called a web container, to provide an environment for the Java code to run in conjunction with the web server. Examples of some available web containers are:

Chapter 5 of Java Enterprise in a Nutshell, Second Edition (O’Reilly), by Jim Farley et al., gives a good history of servlets and more information on how to implement them. Servlets respond fairly quickly to requests to the server for dynamic content, and they make a good environment for developing Ajax web applications.

SSI

The final option available to the developer for providing dynamic content is the Server Side Include (SSI). SSI was used mainly in the beginning to add the content that was needed on every, or almost every, page while being able to maintain the content section in one place. For a web server to recognize that there was SSI content, a different file extension (.shtml) was used, which invoked the web server’s parser. For example:

<HTML>
    <HEAD>
        <TITLE>A SSI Example</TITLE>
    </HEAD>
    <BODY>
        <!--#include virtual="header.html"-->
        <P>
        An SSI example shown firsthand.
        </P>
        <!--#include virtual="footer.html"-->
    </BODY>
</HTML>

SSI, as shown here, was the precursor to the type of server-side includes web developers are accustomed to today. It brought to the Web the ability to embed programming languages directly within the HTML.

Following this first SSI were more advanced server-side languages that eventually developed into object-oriented server-side scripting. These scripting languages are what’s being used today, and you have heard of all of them, I’m sure. Among them are Active Server Pages (ASP), PHP, JSP, Python, and Ruby. There are others, of course, but these deserve a closer look, as they are leading the server-side charge with Ajax.

Server-Side Scripting

Server-side scripting in the early days of web development was done with C, Pascal, or Perl for a CGI script. In the cases of C and Pascal, this was not even really scripting in the traditional sense, as these CGI “scripts” were compiled programs. They did what developers needed them to do: crank out dynamic content quickly. In fact, many CGI programs are still written in C, and they work faster and better than any true scripting language. MapServer (http://mapserver.gis.umn.edu/) is a good example of one of these.

Scripting languages hold one distinct advantage over their compiled brethren: they have better portability. Think about a compiled language on a Windows system, or a Linux system, for that matter. If I wrote a program for Windows 2000, I relied on the DLLs for that operating system when I compiled my program. If I want to port that program to Windows Vista, I may have to do a lot of work to make sure all of the DLLs are compatible on the new system. Worse still, I may need to modify my code for it to compile correctly on the new system. This is true for the *NIXs as well. They all have libraries that are not compatible with one another, making portability a chore.

With scripting languages, on the other hand, once the interpreter for the language in question has been ported to the operating system I want to port to, the script will move to the new system without needing any modifications. That is the beauty of scripting languages, and it’s why they are used so heavily in the Web 2.0 environment.

Before we go any further, I want to point out that of the languages I will be detailing next, I do not believe any particular one is better than another. They all have their pros and cons. I am not saying I do not have a favorite; I do. I am just not going to say, “You have to pick X because it is the best.”

ASP/ASP.NET

Microsoft introduced ASP in December 1996 with the distribution of IIS 3.0, and it was Microsoft’s solution for dynamic content for the Web. ASP uses the idea of built-in objects to allow for easier web site construction, for common needs such as Response, Request, and Session, among others. The most common scripting language used for ASP is Microsoft’s VBScript, though other languages could be used as well (JScript comes to mind). Since ASP is an SSI interpreted technology, it uses delimiters to separate scripting code from straight markup, as shown here:

<%
' Hello world in ASP.
Response.write "Hello world."
%>

As far as using ASP for Ajax, it can function fine as the server-side language that produces the dynamic content for the client. The biggest downsides to ASP are that it is slow due to its interpreted nature, and that Microsoft has abandoned it for a newer version.

In January 2002, Microsoft unveiled its latest version (version 4) of ASP, calling it ASP.NET. ASP.NET is a completely different type of scripting language than ASP (now called “classic” ASP). It is compiled into DLLs that reside on the server, offering major speed increases over its predecessors. Like classic ASP, ASP.NET can be written in many different languages, including C#, VB.NET, and JScript.NET. Because it is compiled, these languages use what Microsoft calls a Common Language Runtime (CLR) to interpret the different languages into a common bytecode that then gets compiled into a DLL.

Microsoft took a page out of its Windows development environment when designing ASP.NET, giving it a GUI environment for developing web pages. Unfortunately, the first two versions of ASP.NET (1.0 and 1.1) did not produce standards-compliant HTML and JavaScript using their built-in controls. ASP.NET version 2.0 addressed these issues when it came out in November 2005. The controls now produce standards-compliant XHTML, and there is also better support for CSS.

Warning

Although the newest version of the .NET Framework (which is downloadable in service packs for Windows XP and Vista) is 3.5 SP1, do not confuse the numbers. The 3.5 Framework still uses the 2.0 version of the CLR – essentially the same ASP.NET, Windows Forms, and ADO.NET that come with the 2.0 Framework. It is presumed that the next version of the Framework, .NET 4.0, will come with a new version of the CLR. At that point, though the 4.0 Framework will run side by side with earlier ones, you will have to learn a new model.

Developing an Ajax application with ASP.NET was a little tricky in its first versions, basically because of the inherent fun of attaching JavaScript calls to events on elements, among other things. Now, however, Microsoft has Ajax.NET (formerly called Atlas), a package that has ready-to-use client- and server-side scripts. Other options for Ajax support with ASP.NET range from open source to commercial products. You can get a better list of available third-party libraries and extensions in Michael Mahemoff’s book, Ajax Design Patterns (O’Reilly), or by searching his Wiki at http://ajaxpatterns.org/.

PHP

PHP is the recursive acronym for PHP: Hypertext Preprocessor. Rasmus Lerdorf developed it in 1994, and at that time it was called Personal Home Page Tools, but Zeev Suraski and Andi Gutmans rewrote it in 1997. That version of PHP (PHP/FI) led to another rewrite of the PHP core, called the Zend engine. PHP 5 is the current version of PHP and it uses the Zend II engine.

Much like other interpreted languages, PHP uses delimiters to separate scripting code from straight markup, as shown here:

<?php
// Hello world in PHP.
echo 'Hello world.'
?>

PHP, like most other server-side scripting languages being used, is object-oriented, starting with the release of PHP 5. Yes, there was class support in PHP 4, but it did not have any other object-oriented features. PHP also has a huge library of standard functions, which makes it faster to develop with. Plus, if you search on the Web, you’ll find thousands of PHP scripts that cover just about every programming problem imaginable.

PHP is touted as a language that is easy to learn and makes developing dynamic content quick and painless. It supports most major databases and runs with all major web servers, on most major operating systems. PHP is, in a word, portable. Ajax web development is simple with PHP as the backend of an application—both as the language itself and, as you will see in our discussion of the Zend Framework later in this chapter, within a framework.

Python

Guido van Rossum created Python in 1990, not as a scripting language but as a general-purpose programming language. Python 2.1 came out in 2002 and is significant not just because it combined Python 1.6.1 and Python 2.0 into a single release, but because Python 2.1 was the first version of Python to fall under a new license owned by the Python Software Foundation. At the time of this writing, Python 2.5.1 is the stable production version of the software.

Python fills the role of a scripting language often, from the Web to databases and even to games. Though it may fill this role, Python is more of a compiled language, like Java, where the source code is compiled into a bytecode format that an interpreter can then read. This makes Python very portable, as the bytecode is operating system-independent. What makes it such a good scripting language is its clean and simple language structure, seen here:

# Hello world in Python
print "Hello world."

Because of its interpreted nature, certain Python applications can be slower than true compiled languages. This does not deter it from excelling as the backend of an Ajax web application, however.

Ruby

The first version of Ruby, created by Yukihiro “Matz” Matsumoto, was released to the public in 1995. It was created as a language that reduces the grunt work that programmers often must do in application development. Ruby’s syntax is somewhat similar in nature to Python’s, or perhaps Perl’s, as shown in the following code snippet. As an interpreted language, Ruby is slower in execution speed than the compiled languages and some of the interpreted languages.

# Hello world in Ruby
puts "Hello world."

What makes Ruby unique is the way it treats its data. Every single piece of data in Ruby is treated as an object; even what other languages would consider primitive types (integers, Booleans, etc.). Functions in Ruby are methods of some object. Even methods outside the scope of an object are considered methods of the object main.

Ruby in itself is not an ideal scripting language for use with Ajax, but when it is the base of a framework such as Ruby on Rails (more on this later in this chapter), it can be a developer’s dream. With Rails, developers require less code to get tasks done, and it has almost built-in support for Ajax calls. This makes it a great fit for building Ajax web applications.

Java

The Java programming language was released in 1996 at Sun Microsystems. Like ASP.NET and Python, Java is not a true compiled language. Instead, it is a language that is compiled into bytecode and then interpreted. Java looks heavily like C and C++, and it takes a lot of their models and structures. The big difference between these languages is that Java does not have the idea of pointers. Java has seen many versions and changes since its initial release. The current version of Java is Java SE 6, which was released in fall 2006.

Because of Java’s use of bytecode, developers have created Java Virtual Machines (JVMs) that run on basically every major operating system. Instead of the Java language itself, what interests a web developer is JSP and servlets. Here we see an example of JSP:

<!-- Hello world in Java Server Pages -->
<%@ page language='java' %>
<%="Hello world." %>

This is an example of a Java servlet:

// Hello world in a Java servlet
import java.io.*;
import javax.servlet.*;
import java.servlet.http.*;

public class HelloWorld extends HttpServlet {
    public void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter output = response.getWriter( );
        output.println("Hello world.");
        output.close( );
    }
}

Both are designed to create dynamic responses to a client request. JSP functions just like classic ASP did—scripting commands are embedded within the XHTML markup for the page. Servlets, as you read earlier in the chapter, are the interface that the client makes requests to, and these interfaces are written in Java. Both of these options for using Java execute quickly and provide a good server base for an Ajax web application.

Databases

Databases allow web applications to store information in a systematic way, and retrieve that information later through the use of a structured query. Before database use became popular on the Web, plain text files were used to store this information. This was slower, not because of read and write access to the files, but because it was difficult to query information contained in the files in a timely manner. Besides being faster for querying, databases also allow many clients to access and save information concurrently. This is very important in the case of web applications, as there is always the potential for hundreds of people to be accessing the application at any one time.

Databases are becoming more sophisticated over time, and they are now meeting the demands of the Internet like never before. As they begin to natively support XML, they will increase the speed of Ajax web applications even more than they do today. This is good news, because these web applications are not going to go away, and data storage needs will become greater and greater.

Oracle

Oracle has been around for a long time. In 1979, Relational Software, Inc. (RSI) introduced a relational database system called Oracle V2. The product has changed a lot since then, having been rewritten in C and having added a host of enhancements, including transactions, stored procedures and triggers, support for PL/SQL, a native JVM, XML capabilities, cluster support, and grid computing. The current version of Oracle is 10gR2.

Oracle (http://www.oracle.com/) is known for its stability and reliability under a heavy workload, and it is deployed often in data warehousing environments because of this. In 1999, Oracle became more Internet-ready, with Oracle 8i, and has since added more enhancements to meet the Internet’s increasing use as a platform. Oracle also is very scalable, having multiple editions to support a wide range of requirements.

The major issue with using Oracle on the Web is its inherently high price, with Oracle’s Enterprise Edition costing in the tens of thousands of dollars per processor. This is a deterrent for companies looking for cheaper solutions to their database-driven Internet applications. Despite the high costs, though, Oracle leads the commercial database market.

Microsoft SQL Server

The original version of Microsoft SQL Server (http://www.microsoft.com/sql/) was a product of collaboration among Microsoft, Sybase, and Ashton-Tate. They set out to create a database product for the OS/2 operating system, and released SQL Server 1.0 around 1989. It was not until Microsoft SQL Server 6.0 that Microsoft built a product without direction from Sybase. The current version is Microsoft SQL Server 2005.

Microsoft SQL Server supports all of the features of relational databases, and adds additional support through its version of SQL called Transact-SQL (T-SQL). Like Oracle, Microsoft SQL Server is scalable, with different editions of the database for different needs. The major limitation to Microsoft SQL Server is that it runs only on Windows, which limits its penetration into the database market.

IBM DB2

IBM DB2 (http://www.ibm.com/db2/) was most likely the first database to use SQL. Named System Relational (System R) when it was released in 1978, IBM DB2 probably goes back to the early 1970s, when IBM was working on a relational model it called SEQUEL (Structured English Query Language). The term SEQUEL was already trademarked, so IBM was forced to rename the database, this time to SQL (Structured Query Language). The name has been the same since.

For years, IBM DB2 was available only on IBM’s mainframes, but throughout the 1990s, IBM slowly began to port the database to other platforms, and now you can find it on many operating systems. Pricing for IBM DB2 is comparable to that for Microsoft SQL Server, costing only in the thousands of dollars per processor.

The current version of the database is IBM DB version 9, and it is the first relational database to natively store XML, according to IBM. This support adds to IBM DB2’s ability to handle requests from Ajax web applications.

Open Source Databases: MySQL and PostgreSQL

Free software implementations of cross-platform relational databases began to spring up in the mid-1990s and have begun to threaten the dominance of larger proprietary giants such as Oracle, IBM, and Microsoft, especially for web applications. The two most popular of these are MySQL (http://www.mysql.com/) and PostgreSQL (http://www.postgresql.org/). Both are freely available to download and use. The popularity of these databases has forced other companies to make free versions of their software available. Among them are Oracle 10g Express Edition, IBM DB2 Express-C, and Microsoft SQL Server Express Edition (formerly MSDE).

MySQL AB released MySQL in 1995; PostgreSQL has an older history, having been released to the public in 1989. At the time of this writing, the current versions of these open source databases are MySQL 5.0 and PostgreSQL 8.2. Both support transactions, stored procedures and triggers, views, and a host of other features.

Some features unique to MySQL are its use of multiple storage engines, commit grouping, and unsigned INTEGER values. MySQL supports MyISAM, InnoDB, BDB, and other storage engines, which allows developers to choose whichever engine is most effective for the application’s needs. With commit grouping, MySQL gathers transactions from concurrent connections to the database and processes them together, thereby increasing the number of commits per second. By permitting INTEGER type values to be unsigned, MySQL allows for its different database types to have a greater range of values per type, which can save on database size, depending on the implementation.

PostgreSQL has support for XML and Extensible Stylesheet Language Transformation (XSLT) via an add-on called XPath Extensions, which has a GPL license. MySQL will add support for XML functions with the release of MySQL 5.1, which at the time of this writing is still in beta. The XML support enables these databases to work well with the growing demands of Ajax web applications.

Nonrelational Database Models

There are other types of database models besides relational databases. They include:

  • Flat file

  • Hierarchical

  • Dimensional

  • Object

  • Network

Flat file databases are simply plain-text files that contain records (generally one record per line), which separate fields with a fixed width, whitespace, or some special character. There are no structural relationships in the flat file data model, and a flat file database consists of a separate file for every table of data. Implementations of this model include comma-separated value (CSV) files, dBASE, and Microsoft Excel, among others. These don’t tend to work very well for anything more than the simplest of web applications, though they can be useful as an export format when users want to extract data from your application.

Hierarchical databases use a tree-like structure of one-to-many relationships to organize data. Information is repeated using parent-child relationships in which each parent may have many children, but each child will have, at most, one parent. A “table” will contain the lists of all attributes for a specific record, where the attributes can be thought of as “columns.” Examples of some hierarchical databases are Adabas, MUMPS, Caché, Metakit, and Berkeley DB. Many “native XML” databases also have hierarchical foundations.

Dimensional databases store key data entities as different dimensions instead of in multiple 2D tables (the relational databases we are used to). These databases really just offer an extension to relational databases by providing a multidimensional view of the data. You can implement dimensional databases in multidimensional databases or in relational databases that use a star or snowflake schema.

Tip

Multidimensional schemas for use in relational databases are an interesting topic, but they are outside the scope of this book. The star schema is more popular than the snowflake schema, but you can find good information on both. Principles and Implementations of Datawarehousing by Rajiv Parida (Laxmi Publications) and The Art of SQL by Stéphane Faroult and Peter Robson (O’Reilly) are good places to start for information on database schemas. Other resources include Advanced Topics in Database Research by Keng Siau (Ed.) (Idea Group Publishing) and Oracle Essentials: Oracle Database 10g, Third Edition, by Rick Greenwald et al. (O’Reilly).

Object databases represent information in the form of objects, essentially in the same way as objects are used in object-oriented programming. When the data set is complex and high performance is essential, this type of database could be the right choice. You’ll most often find them applied in areas such as engineering, molecular biology, and spatial applications. Languages such as C++, C#, and Java have created a resurgence in object databases because of their object-oriented nature. Implementations of object databases are Perst and db4o (db4objects).

Network databases create a lattice structure whereby each record in the database can have multiple parents and multiple children. This model was introduced in 1969 and grew until the early 1980s, with the publication of an ISO specification that had no effect in the industry. Network databases were eventually pushed aside by the growth of relational databases, and now they rarely exist.

Getting Data Into and Out of Relational Databases

Ajax is about programming on the client and on the server, as I have already discussed. Though this book focuses primarily on the client end of an Ajax application, it still includes some server-side scripting examples. Part of that is interfacing with the database. For good or for bad, as an Ajax developer you must understand at least the basics of database development, unless you are lucky enough to have a database administrator on the project that can do this stuff for you. Even then, it is a good idea to understand how databases can work for you.

Tip

Because most web applications are built using relational databases, this section focuses on working with that common model. There isn’t room in this book to provide a full tutorial, but if you haven’t worked with relational databases before, this section should at least give you some idea of what they do and how they might store data for your applications.

The first thing a developer needs to learn when developing a database is how to create tables. More than that, a developer must learn how to build tables efficiently and in a relational manner. For the following examples, let’s assume that we have been tasked with developing a database based on tabular data that had been kept in a spreadsheet containing a list of books in a personal collection.

The spreadsheet includes the following columns:

  • Title of the Book

  • Author(s) of the Book

  • Publishing Date

  • Publisher

  • ISBN-10

  • ISBN-13

  • Number of Pages

  • Original Price of Book

  • Type of Book

  • Category of Book

  • Bought New/Used or Gift

That should be enough to get us started. Obviously, if this were a real-world application, we would have a much more comprehensive list of columns to work from.

I have always found it easiest to look at a data set and determine what can be separated into look-up and cross-reference tables before tackling the main tables—you may find a different method easier. Looking at the columns in the spreadsheet, it immediately becomes clear to me that I can create several columns as look-up tables, mainly the Type of Book, Category of Book, and Bought New/Used or Gift columns. Let’s look at how we can create these tables in a MySQL database.

Tip

Look-up tables are useful tables that store records that are common and will be used often, defining an ID for each unique record that the main tables will use instead of the record itself. This can greatly conserve disk space and speed up the execution of SQL queries on tables.

Here is the basic SQL syntax to create a new table:

CREATE TABLE table_name (
    column_name-1    datatype    [modifiers],
    column_name-2    datatype    [modifiers],
    ...
);

We will make the Type of Book column into a table called book_type, with ID and description fields using the following SQL query:

CREATE TABLE book_type (
    type_id     TINYINT        NOT NULL PRIMARY KEY,
    type_dsc    VARCHAR(15)    NOT NULL,
    UNIQUE KEY _types_key_1 (type_dsc)
);

This query uses the CREATE TABLE SQL syntax, which will vary from database to database, making it important to review the documentation for whatever database you are working on. We will create the other look-up tables in much the same way. We will make the Category of Book column into a table called book_category, with ID and description fields, and the Bought New/Used or Gift column into a table called book_acquired, with ID and description fields, using the following SQL query:

CREATE TABLE book_category (
    cat_id     TINYINT        UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    cat_dsc    VARCHAR(40)    NOT NULL,
    UNIQUE KEY _cat_key_1 (cat_dsc)
);

CREATE TABLE book_acquired (
    acq_id     TINYINT        UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    acq_dsc    VARCHAR(20)    NOT NULL,
    UNIQUE KEY _acq_key_1 (acq_dsc)
);

Looking further at our original spreadsheet, we could separate a couple of other columns into their own tables. These are not really look-up tables, which is why I did not create them with the look-up tables in the preceding code. The first is a table that can hold all of the unique publishers that exist. This could technically be considered a look-up table, but considering how large this table could get, it must not be viewed as such. We will create it in the same way as the look-up tables, however, calling the table book_publishers, with ID and description fields. The difference will be in the data type used for the ID in this table. Instead of a TINYINT, we will use a MEDIUMINT:

CREATE TABLE book_publishers (
    pub_id     MEDIUMINT      UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    pub_dsc    VARCHAR(60)    NOT NULL,
    UNIQUE KEY _pub_key_1 (pub_dsc)
);

The last column we will separate out is the Author(s) of the Book column. This table, which we will call book_authors, will actually require another table to tie the data to our main table. This other table will be a cross-reference table, and we need it for books that have more than one author; we’ll call it book_author_title_xref. The book_authors table will contain ID and name fields, and the book_author_title_xref table will contain ID, title ID, and author ID fields:

CREATE TABLE book_authors (
    auth_id    MEDIUMINT      UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    auth_nm    VARCHAR(60)    NOT NULL,
    UNIQUE KEY _auth_key_1 (auth_nm)
);

CREATE TABLE book_author_title_xref (
    title_id   BIGINT       NOT NULL REFERENCES book_titles (title_id),
    auth_id    MEDIUMINT    NOT NULL REFERENCES book_authors (auth_id),
    UNIQUE KEY _auth_title_key_1 (title_id, auth_id)
);

All that is left now is to create a table with the remaining columns that we will call book_titles:

CREATE TABLE book_titles (
    title_id     BIG_INT        UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    title_dsc    VARCHAR(100)   NOT NULL,
    pub_dte      VARCHAR(20)    NULL,
    pub_id       MEDIUMINT      NOT NULL REFERENCES book_publishers (pub_id),
    isbn_10      VARCHAR(13)    NOT NULL,
    isbn_13      VARCHAR(18)    NOT NULL,
    num_pages    SMALLINT       NULL,
    orig_price   FLOAT(2)       NULL,
    type_id      TINYINT        NOT NULL REFERENCES book_type (type_id),
    cat_id       TINYINT        NOT NULL REFERENCES book_category (cat_id),
    acq_id       TINYINT        NOT NULL REFERENCES book_acquired (acq_id),
    UNIQUE KEY _title_key_1 (isdn_10, isdb_13),
    KEY _title_key_2 (title_dsc, pub_id, pub_dte)
);

The hard part is done—creating a database that has good indexing and relational tables yet conserves space wherever possible is a tall order, and should really be considered an art. A database expert could do better, and for a larger project I recommend seeking design assistance, but for our purposes this will suffice.

Now, we need to consider how to get functionality out of our database with just the basic functions of Create, Read, Update, and Delete (CRUD). You can create new records in tables with the INSERT statement, read them using the SELECT statement (become friends with this statement, as you will use it most often), update them using the UPDATE statement, and delete them using the DELETE statement. These four commands will accomplish everything necessary in an application.

The first thing we need to do with our new database is put some records in our tables, especially the look-up tables. To accomplish this, we will use the INSERT SQL statement, which has a basic syntax of:

INSERT INTO table_name    (column_name-1, column_name-2, ..., column_name-n)
VALUES
    (value-1, value-2, ..., value-n);

To insert records into our database, we will execute the following SQL statements:

INSERT INTO book_type (type_dsc) VALUES ('Hard Cover'),
INSERT INTO book_type (type_dsc) VALUES ('Paperback'),

INSERT INTO book_category (cat_dsc) VALUES ('Computer'),
INSERT INTO book_category (cat_dsc) VALUES ('Fiction'),
INSERT INTO book_category (cat_dsc) VALUES ('Nonfiction'),

INSERT INTO book_acquired (acq_dsc) VALUES ('Bought New'),
INSERT INTO book_acquired (acq_dsc) VALUES ('Bought Used'),
INSERT INTO book_acquired (acq_dsc) VALUES ('Given As Gift'),

Let’s assume the book_title, book_publishers, and book_authors (and book_author_title_xref) tables have been populated with the following data.

book_title

1

Head Rush Ajax

March 2006

1

0-596-10225-9

978-0-59-610225-8

446

39.99

2

3

1

2

The Historian

June 2005

2

0-316-01177-0

978-0-316-01177-8

656

25.95

1

1

1

3

3 Nights in August

April 2005

3

0-618-40544-5

978-0-618-40544-2

256

25.00

1

2

1

4

Ajax Design Patterns

June 2006

1

0-596-10180-5

978-0-59-610180-0

655

44.99

2

3

1

5

CSS: The Definitive Guide

November 2006

1

0-596-52733-0

978-0-59-652733-4

536

44.99

2

3

1

6

The Iliad

November 1998

4

0-14-027536-3

978-0-14-027536-0

704

15.95

3

2

2

7

Chicka Chicka Boom Boom

August 2000

5

0-689-83568-X

978-0-689-83568-1

32

7.99

3

4

3

book_publishers

1

O’Reilly Media

2

Little, Brown and Company

3

Houghton Mifflin

4

Penguin Classics

5

Aladdin Picture Books

book_authors

book_author_title_xref

1

Brett McLaughlin

1

1

2

Elizabeth Kostova

2

2

3

Buzz Bissinger

3

3

4

Michael Mahemoff

4

4

5

Eric Meyer

5

5

6

Homer

6

6

7

Bill Martin, Jr.

7

7

8

John Archambault

8

8

Note especially the columns with numbers in them. These act as keys, or ways that one table can reference data in another. As we query the database to extract data, the queries will use these keys to create joins across multiple tables.

To get records from the database, we execute SELECT statements that have this basic syntax:

SELECT
    columns
FROM
    tables
WHERE
    predicates

To get a list of books published by O’Reilly, we execute the following SELECT statement:

SELECT
    t.title_dsc,
    p.pub_dsc,
    t.isbn_10
FROM
    book_titles t INNER JOIN book_publishers p ON t.pub_id = p.pub_id
WHERE
    p.pub_dsc = 'O'Reilly Media';

It takes practice to learn all of the nuances of how to most efficiently pull data from tables, and here is where a database administrator can effectively come to the aid of a developer. There are many things to consider when writing a SELECT statement. You should refer to books specific to the database you are using for more information on this.

Deleting records from a table is straightforward using the following syntax:

DELETE FROM table_name WHERE predicates;

To, say, remove records from the book_category table you would execute the following DELETE statements:

DELETE FROM book_category WHERE cat_dsc = 'Science Fiction';

Sometimes records simply need to be updated, and you can use the following syntax for such cases:

UPDATE
    table_name
SET
    column = expression
WHERE
    predicates;

To update records in the book_category table you would execute the following UPDATE statements:

UPDATE
    book_category
SET
    cat_dsc = 'Science Fiction & Fantasy'
WHERE
    cat_dsc = 'Science Fiction';

These are the basics of tables and queries in a relational database, and they will get a developer through most of what he will encounter when programming an Ajax application. As applications become more complex, their scope increases in size or the number of users increases; then the developer must take other measures to improve database performance and execution.

Tip

For a more thorough introduction to SQL, and MySQL in particular, check out MySQL in a Nutshell by Russell Dyer (O’Reilly).

Having SELECT statements (or INSERT, UPDATE, and DELETE, for that matter) inline in your code is fine when the code isn’t used frequently in an application. For scripts that are static with the exception of a few parameters, you will probably see performance gains if you switch these inline SQL statements to stored procedures.

Stored procedures have the benefit of being compiled by the database and stored in it, making the execution plans for the script already resident to the database. The database already knows how to execute the script, making the execution that much quicker. The other advantage to using stored procedures instead of inline statements is that all of the data logic can be in one place in the application. This not only facilitates application maintenance, but also allows code reuse in places that need the same SQL statement on different pages.

Tip

For much more on stored procedures, see MySQL Stored Procedure Programming by Guy Harrison and Steven Feuerstein (O’Reilly).

You can learn much more about SQL and databases if you want, but this introduction should help you understand some of what writing an Ajax application encompasses.

Interfacing the Interface

Covering all of the tools available on the backend of an Ajax application is one thing, but showing how they interact with a client is another. Server-side scripting has changed, not so much in how the developer codes with the language, but in what the client needs or expects to get back from the server. Take, for instance, Example 3-1, which shows the typical server response from a client submitting a form.

Example 3-1. A typical server response to a form submit

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html401/loose.dtd">
<HTML>
    <HEAD>
        <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
        <TITLE>Example 3-1. A typical server response to a form submit.</TITLE>
    </HEAD>
    <BODY BGCOLOR="WHITE">
        <H1>Query Results</H1>
            <TABLE>
                <TR><TH>Book Name</TH></TR>
<?php
require('db.inc'),
if (!($conn = @mysql_connect($host, $username, $password)))
    die('Could not connect to the database.'),
$author = mysql_real_escape_string(isset($_POST['authorName']) ?
    $_POST['authorName'] : ''),
if (!@mysql_select_db($db, $conn))
    die('Could not select database.'),
$sql = 'SELECT book_id, book_nm FROM books, authors WHERE books.author_id '
    .'= authors.author_id';
if (isset($author))
    $sql .= " AND authors.author_nm = $author'";
$sql .= ' ORDER BY book_nm';
if ($result = @mysql_query($sql, $conn)) {
    while ($row = @mysql_fetch_assoc($result)) {
?>
            <TR><TD><?= $row['book_nm']; ?></TD></TR>
<?php
    }
    mysql_free_result($result);
    mysql_close($conn);
} else {
?>
            <TR><TD>There were no results for the specified query.</TD></TR>
<?php
}
?>
        </TABLE>
    </BODY>
</HTML>

First, note how this example uses PHP as the server-side scripting language and MySQL as the database. This book’s examples will generally follow this design, not because I believe these are better than the other languages and databases I’ve outlined, but simply because I find them easy to use, especially for demonstration purposes. In this example, the server processes the data posted to it and then creates a response in the form of a full HTML document. What makes this bad in an Ajax application sense is that the browser must load all of the content for the page again. If images, CSS, and JavaScript were included in this file, they would all have to be downloaded again as well. This is why the classic style of building web pages is not ideal for application building. Compare this with Example 3-2, which shows how a typical Ajax response would be generated.

Example 3-2. A typical Ajax response to a form submit

<?php
/**
 * Example 3-2.  A typical Ajax response to a form submit.
 */
/**
 * The generic db.inc library, containing database connection information such as
 * username, password, server, etc., is required for this example.
 */
require('db.inc'),

/* Output the XML Prolog so the client can recognize this as XML */
$xml = <<< PROLOG
<?xml version="1.0" encoding="iso-8859-1"?>
PROLOG;

/* Is there a connection to the database server? */
if (!($conn = @mysql_connect($host, $username, $password)))
    $xml .= '<error>Could not connect to the database.</error>';

$author = mysql_real_escape_string(isset($_POST['authorName']) ?
    $_POST['authorName'] : ''),

/* Could the database be selected? */
if (!@mysql_select_db($db, $conn))
    $xml .= '<error>Could not select database.</error>';

$sql = 'SELECT book_id, book_nm FROM books, authors WHERE books.author_id '
      .'= authors.author_id';
/* Was the parameter /authorName/ passed to this script? */
if (isset($author))
    $sql .= " AND authors.author_nm = '$author'";
$sql .= ' ORDER BY book_nm';

/* Are there results from the query? */
if ($result = @mysql_query($sql, $conn)) {
    $xml .= '<results>';
    /* Loop through the records */
    while ($row = @mysql_fetch_assoc($result))
        $xml .= "<result>{$row['book_nm']}</result>";
    /* Were there any records to loop through? */
    if (!@mysql_num_rows($result))
        $xml .= '<result>There were no results for the specified query.</result>';
    $xml .= '</results>';
    /* Free the mysql result */
    mysql_free_result($result);
    mysql_close($result);
} else
    $xml .= '<results>'
           .'<result>There were no results for the specified query.</result>'
           .'</results>';

/*
 * Change the header to text/xml so that the client can use the return
 * string as XML
 */
header("Content-Type: text/xml");
echo $xml;
?>

Notice that in this example, the only thing returned with the response is an XML document with the data necessary to be shown on the page, sent in the form of XML. The client will parse this response as needed so that it will appear as though the application just changed content without having to refresh everything. The server will also not kill the page with the die( ) function, leaving the client to decide what to do with an error.

This is how server-side applications need to react. Each client request should expect only a minimal amount of data sent back to it. This forces the browser to download less data per request, and speed up the application as a whole. We will see in Chapter 4 how the client makes its requests and manipulates responses, and Chapter 5 will go into more detail on client-side data parsing. For now, we should content ourselves with understanding what is expected of the server side of an Ajax web application, and find ways to increase this performance. This side of the application does all the “dirty work,” and the quicker and more efficiently it does this, the better our Ajax web applications will perform.

Frameworks and Languages

Frameworks have been getting a lot of press lately, as those such as Ruby on Rails have gained the notice of more and more professionals in the industry. The truth is, however, that frameworks have been around for a while—longer with some languages than others. But what exactly is a framework? In the simplest terms, a framework is a set of components (interfaces and objects) that are put together to solve a particular problem.

Frameworks are built to ease the burden of writing all of the low-level coding details that go along with programming an application. An important feature of frameworks is that they should work on a generic level so that they are suited for a multitude of applications. On the Web and the desktop, frameworks allow developers to concentrate on the application’s requirements and on meeting deadlines, instead of on the mundane but necessary components that make applications run.

With our focus on Ajax web development, it is important to understand the differences among the various frameworks on the Web, not just within a given language, but among languages as well. Earlier in the chapter, we focused on ASP/ASP.NET, PHP, Python, Ruby, and Java, so the frameworks we discuss here will correspond with these languages. Some of these frameworks follow the Model-View-Controller (MVC) design pattern discussed in Chapter 2, and others are just a whole lot of functionality bundled together. Your choice of framework will depend on how structured you want to be.

The .NET Framework

The Microsoft .NET Framework (http://msdn.microsoft.com/netframework/) is positioned to be the development platform for all new Windows applications, on the Web as well as the desktop. Because of this strategy, it is built as part of the Windows operating system and not as a separate component, as all other frameworks are. And although Microsoft was specifically looking at its flagship Windows operating systems when it designed the .NET Framework, it built the framework to theoretically be a portable language.

As we discussed in the section “ASP/ASP.NET,” earlier in this chapter, instead of .NET languages being compiled into machine-level instructions, they are first compiled into a common bytecode and then into a DLL. That is a high-level description of the architecture, but we should delve into it further, and Figure 3-2 does just that.

The .NET Framework architecture

Figure 3-2. The .NET Framework architecture

When a .NET project is built, each specific .NET language has its own compiler that can interpret the language syntax. These compilers rely on a Common Language Specification (CLS) to govern the rules the languages must live by. They also rely on the Common Type System (CTS), which defines operations and types that the .NET languages share. Finally, the .NET language compilers utilize the Framework Class Library (FCL), a set of more than 600 classes that encapsulates everything from file manipulation to graphics rendering to database interaction. Taking all of these layers of the .NET Framework together, the compilers then compile the code into the bytecode that is called the Common Intermediate Language (CIL).

This CIL is what programmers generally referred to in .NET as assemblies. When the web server requests an assembly, the CLR is invoked. Within the CLR is where components such as the Just-In-Time (JIT) compiler, garbage collector, and security run. The CLR is the platform-specific part of the .NET Framework, and it compiles the CIL into the operating system’s machine code. The CIL and CLR together are referred to as the Common Language Infrastructure (CLI).

The .NET Framework is good for its large library of built-in classes that cover most of what you would need when building an Ajax web application. Plus, developers have their choice of languages to use for programming, allowing different people to be comfortable with their code and generally more productive. On the downside, because of their CLR, .NET applications tend to require more system resources than similar applications that directly access system resources. Also, the FCL has a rather large learning curve.

All in all, the .NET Framework is not a bad environment to work in once you know the classes that Microsoft has provided for you. When you throw in Microsoft Visual Studio for development, programming times are reduced thanks to the GUI for designing and building individual pages in an application that it provides. The large available class library and the GUI for designing site pages allow more rapid deployment of Ajax web applications than traditional coding.

Ruby on Rails

Ruby on Rails (RoR or just Rails), which David Heinemeier Hansson developed while he was working on Basecamp (http://www.basecamphq.com/), is a web-based project collaboration tool. It is an open source framework that is based on the MVC pattern, and you can find it at http://www.rubyonrails.org/. It is considered to be a full-stack framework, meaning that all the components in the framework are integrated, so you don’t have to set anything up manually.

Ruby on Rails’ marketing claims that a web programmer can develop 10 times faster than a programmer working from scratch without Rails. How can this be possible? Easily, if the libraries the framework provides are easy to use and are written so that they integrate well with one another. This is just what Rails does, and these libraries are set up to work within the MVC pattern.

Read the articles and blogs on Ruby on Rails, and almost all of them will talk about the ActiveRecord library. ActiveRecord makes communicating with a database just plain easy, something anyone trying to build a database-driven web application wants to hear. ActiveRecord acts as the model of the MVC pattern. Rails also has the Action Pack, which consists of two libraries: ActionController and ActionView. ActionController takes care of the pattern’s controller needs, and ActionView handles the view.

Ruby on Rails allows a web developer to focus on what he needs to: the application’s functionality. All of the details of database queries, hashing, caching, forms, tags, and even Ajax itself are taken care of, leaving you free to program that functionality your boss has been hoping for. Hurting Rails right now is its lack of examples (due to its fledgling nature), incomplete or limited documentation, and lack of support from web hosts and third-party software. For anyone willing to jump right into development with both feet, though, Rails is the framework of choice. I can’t say it enough; Ajax web development with Ruby on Rails is just plain easy.

Java Frameworks

Some frameworks in Java have been around longer than the frameworks in other languages, though even Java has its youngsters. These frameworks are usually designed for the Java J2EE platform, though frameworks for other platforms also exist. The common ground for these frameworks is that almost all of them follow the MVC design pattern. They all use different techniques to get the job done, but the overall data flow within these applications remains basically the same.

Too many Java frameworks are available today to review them all. I’ve chosen to highlight Jakarta Struts, Spring, and Tapestry. And before you complain too much about my choices, you should be aware that I am not a Java programmer, nor will I ever claim to be, so I am not playing favorites here.

Jakarta Struts

Jakarta Struts (http://struts.apache.org/), or just Struts, was created by Craig McClanahan and donated to the Apache Software Foundation (ASF) in 2000. It was designed to model the MVC design pattern, through the extension of Java servlets. Struts was designed for applications to be built by people with different skill sets. The view of a Struts framework can be any number of XML, JSP, and JavaServer Faces (JSF), whereas the model supports both JavaBeans? and Enterprise JavaBeans (EJB).

Struts has a tag library that holds a large set of functionality, as well as built-in form validation. Plus, it is well documented (check out Chuck Cavaness’s Programming Jakarta Struts from O’Reilly), and its popularity has led to it having a mature code base. But it is starting to see new challenges, not just in other languages, but with lighter-weight MVC frameworks built with Java as well.

Spring

Rod Johnson wrote the Spring framework, which you can find at http://www.springframework.org/, and released it to the public in 2002, with version 1.0 being released in March 2004. When it was first being designed, its developers were not thinking of the MVC design pattern. They were instead trying to develop a framework in response to what they felt was poor design on the part of Jakarta Struts. In the end, though, Spring did wind up with an MVC architecture.

Spring is quickly growing out of its reputation as a “lightweight” framework, but not because it is getting bloated with code. It now merely has so much functionality that it is hard to think of it as anything other than a robust framework. Spring has gained popularity because it integrates so well with other things besides the Java Enterprise platform. What may hurt Spring the most is that as a framework, it has almost become too flexible, and it does not have a central controller.

Tapestry

Tapestry (http://tapestry.apache.org/) is an MVC-patterned framework built on the Java Servlet API that Howard M. Lewis Ship created. It was designed to allow for easy component building and the approach of dividing web applications into individual pages created on these components. Tapestry’s core philosophy is “the simplest choice should be the correct choice.” This is driven by four key principles: simplicity, consistency, efficiency, and feedback.

Tapestry is a young framework, but it has the philosophy and MVC design that are driving many Ajax web applications. It is only a matter of time before it becomes a more mature framework and sees the popularity that other Java frameworks have enjoyed.

Python Frameworks

Just like all of the other server-side scripting languages out there today, Python has its share of frameworks. And like all languages, these frameworks differ in how they are designed. Some follow the MVC design pattern strictly, some follow it loosely, and some do not follow it at all.

Django

Django (http://www.djangoproject.com/) is a loosely based MVC framework developed by Adrian Holovaty, Simon Willison, Jacob Kaplan-Moss, and Wilson Miner. Django was designed for heavily content-driven web applications, such as news sites, blogs, and forums. Because of this, Django is very good at database communication, specifically CRUD. It also has an excellent built-in administrator interface.

When I say loosely based MVC I am echoing what Django’s developers stated: that they “feel like the design of Django has to feel right, and [they] will not be bound to a particular design pattern.” As a result, the controller in a typical MVC framework is the “view” in Django, and the view is instead called the “template.” Even though Django is not a true MVC framework, it still functions very well with Ajax web applications that require rapid creation and robust database controls.

Zope

Zope, which stands for “Z Object Publishing Environment,” is well known as the driving force behind the most popular open source Content Management System (CMS) available on the Web: Plone (http://plone.org/). Created and owned by the Zope Corporation, Zope (found at http://www.zope.org/) is nonetheless an open source product, and is the collaboration of many different people across the Internet. Zope has two stable branches released to the public: Zope 2 and Zope 3.

Zope 2 is the code base that most programmers are familiar with, as it is behind many open source CMSs and ERP5 (http://www.erp5.com/), an open source Enterprise Resource Planning (ERP) package. The problem with Zope 2 is that a lot of “magic” code must go along with every distribution. Zope 2 also does a poor job of separating business logic from the presentation layer.

Zope 3 is a rewrite of Zope that attempts to fix the problems that exist in Zope 2 while keeping true to the roots that make Zope popular. It is taking a different approach, though, mixing components of various origins to create a faster, stronger, and more reliable Ajax web development framework.

PHP Frameworks

Being one of the most popular server-side scripting languages on the Web, PHP has a large number of frameworks to choose from. Some of these frameworks are modeled after a generic MVC design pattern, some are modeled after frameworks in different languages, and some have their own unique structure suited for more specific needs. Whatever the design pattern is, PHP frameworks take the already simple-to-use PHP language and make it even easier and faster to develop web applications.

CakePHP

CakePHP was created in 2005 at a time when Ruby on Rails was seeing a huge boost in popularity. It has seen heavy development since then and is now a robust MVC framework with an active developer community. Ever since CakePHP was released as stable with version 1.1.15.5144 on May 21, 2007, it has shown that it has the capabilities to compete with all of the other frameworks out there.

CakePHP, which you can find at http://www.cakephp.org/, has a solid foundation, with modules built on top that add all of the functionality a developer looks for when building an application. It handles database interactions, provides all the Ajax support you need, and includes built-in validation as well as security, session, and request handling. With documentation that is thorough and easy to follow, CakePHP is easy to use and ideal for Ajax web applications.

Zoop

Zoop, which stands for “Zoop Object Oriented PHP,” is a framework comprising many different components and using other projects for added functionality. Zoop has been in development and production since 2001 and has been used in many production environments.

Zoop takes advantage of other projects, such as Smarty (http://smarty.php.net/) and PEAR modules (http://pear.php.net/), showcasing its ability to be extensible and versatile. Zoop’s truly unique feature is its GUI controls, something rarely seen in PHP, which give the developer easy access to widgets and a framework in which to build new controls. Zoop is designed with the developer in mind, making application building simple and efficient through the tools that it provides.

Zend

The Zend Framework (http://framework.zend.com/) is newer than most, but provides some excellent functionality with the components already created. Unlike other frameworks, Zend is built on the true spirit of PHP: delivering easy-to-use and powerful functionality. It does this not through a true design pattern, but rather through the use of separate components for different functionalities.

That is not to say it doesn’t follow MVC patterns. Zend does have components for building MVC applications: Zend_View and Zend_Controller. Currently, though, the developer must implement a “model” for the framework. And though it still lacks some functionality, it already contains many useful components, including Database, JavaScript Object Notation (JSON), Logging, Mail, PDF, RSS and Atom feeds, and web services (Amazon, Flickr, and Yahoo!).

This framework looks very promising as it continues to grow toward a stable release. When this happens, it may be the framework of choice for building Ajax web applications.

What Good Are Frameworks?

The title of this section speaks for itself. I have described some of the frameworks that are available for different scripting languages, but just what good are they? Are they more than just a popular buzzword that has been floating around? The answer, in a word, is yes!

Frameworks are designed to solve recurring problems in application development. So, instead of just trying to explain their usefulness, I will show you.

One of the problems developers face with any web application is providing dynamic data to the client. This is solved by the interaction of the server-scripting language with a database of some kind. Let’s take another look at Example 3-2:

<?php
/**
 * Revisiting Example 3-2.
 */

/**
 * The generic db.inc library, containing database connection information such as
 * username, password, server, etc., is required for this example.
 */
require('db.inc'),

/* Output the XML Prolog so the client can recognize this as XML */
$xml = <<< PROLOG
<?xml version="1.0" encoding="iso-8859-1"?>
PROLOG;

/* Is there a connection to the database server? */
if (!($conn = @mysql_connect($host, $username, $password)))
    $xml .= '<error>Could not connect to the database.</error>';

$author = mysql_real_escape_string(isset($_POST['authorName']) ?
    $_POST['authorName'] : ''),

/* Could the database be selected? */
if (!@mysql_select_db($db, $conn))
    $xml .= '<error>Could not select database.</error>';

$sql = 'SELECT book_id, book_nm FROM books, authors WHERE books.author_id '
      .'= authors.author_id';
/* Was the parameter /authorName/ passed to this script? */
if (isset($author))
    $sql .= " AND authors.author_nm = '$author'";
$sql .= ' ORDER BY book_nm';

/* Are there results from the query? */
if ($result = @mysql_query($sql, $conn)) {
    $xml .= '<results>';
    /* Loop through the records */
    while ($row = @mysql_fetch_assoc($result))
        $xml .= "<result>{$row['book_nm']}</result>";
    /* Were there any records to loop through? */
    if (!@mysql_num_rows($result))
        $xml .= '<result>There were no results for the specified query.</result>';
    $xml .= '</results>';
    /* Free the mysql result */
    mysql_free_result($result);
    mysql_close($conn);
} else
    $xml .= '<results>'
           .'<result>There were no results for the specified query.</result>'
           .'</results>';

/*
 * Change the header to text/xml so that the client can use the return
 * string as XML
 */
header("Content-Type: text/xml");
echo $xml;
?>

This is a common technique for querying a database. Here are the steps involved:

  1. Connect to the MySQL server.

  2. Choose the database to use.

  3. Build and execute the query on the database.

  4. Fetch the resulting rows from the database.

  5. Loop through the records.

  6. Free the results.

  7. Close the connection to the MySQL Server.

I admit that all of these code checks are probably a little bit over the top. It would be fine to just fall through and have one generic catch at the end to alert the client that an error occurred. After all, the client doesn’t need to know exactly what happened; it is the server’s job to log errors and send only meaningful information back.

But here is the question you should think about when looking at the code in Example 3-2: would you code a database interaction that way? Chances are, you wouldn’t. You might not follow the same steps, adding or deleting them as necessary. This is where frameworks give the developer such an advantage. When developers use a framework, they are committing to always coding a specific task or problem in the same way. If there is more than one developer, all of the code will be basically the same. This is a wonderful advantage if someone else ever needs to debug your code.

Example 3-3 shows how the Zend Framework could solve this problem. It is a pretty straightforward and simple means to database interaction, which is why I chose this framework for the example.

Example 3-3. Database interaction using the Zend Framework

<?php
/**
 * Example 3-3.  Database interaction using the Zend Framework.
 */

/**
 * The Zend framework Db.php library is required for this example.
 */
require_once('Zend/Db.php'),
/**
 * The generic db.inc library, containing database connection information such as
 * username, password, server, etc., is required for this example.
 */
require('db.inc'),

/* Output the XML Prolog so the client can recognize this as XML */
$xml = <<< PROLOG
<?xml version="1.0" encoding="iso-8859-1"?>
PROLOG;

/* Get the parameter values from the query string */
$author = mysql_real_escape_string(isset($_POST['authorName']) ?
    $_POST['authorName'] : ''),
/* Set up the parameters to connect to the database */
$params = array ('host' => $host,
                 'username' => $username,
                 'password' => $password,
                 'dbname' => $db);
try {
    /* Connect to the database */
    $db = Zend_Db::factory('PDO_MYSQL', $params);
    /* Create a SQL string */
    $sql = sprintf('SELECT book_id, book_nm FROM books, authors '
                  .'WHERE books.author_id = authors.author_id %s ORDER BY '
                  .'book_nm', (isset($author)) ? " AND authors.author_nm =
                  '$author'" : ''),
    /* Get the results of the query */
    $result = $db->query($sql);
    /* Are there results? */
    if ($rows = $result->fetchAll( )) {
        $xml .= '<results>';
        foreach($rows in $row)
            $xml .= "<result>{$row['book_nm']}</result>";
        $xml .= '</results>';
    }
} catch (Exception $e) {
    $xml .= '<error>There was an error retrieving the data.</error>';
}

/*
 * Change the header to text/xml so that the client can use the return
 * string as XML
 */
header("Content-Type: text/xml");
echo $xml;
?>

In this case, the framework saves only a few lines of code; there is no great advantage or disadvantage with that. Let’s take another look at the steps involved with this code:

  1. Set up the parameters for the database server.

  2. Create an instance of Zend_Db_Adapter.

  3. Properly format the query string.

  4. Execute the query on the database.

  5. Fetch the resulting rows from the database.

  6. Loop through the records.

The difference between the two lists is not what I want you to focus on. The point here is that these will be the same steps any developer working on the application will take, because the framework has a structure for database interaction.

Whatever the task in an application, by using a framework, you ensure consistency and efficiency in tackling that task. This is what frameworks are all about: consistently and effectively providing solutions to problems in a structured manner. Once you have that, building an Ajax web application becomes simple—which is how it ought to be.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset