So far in this chapter we've described how to implement stateful applications using sessions, but we have not discussed when you should or should not use them. Sessions allow some kinds of applications to be developed that otherwise would be difficult to implement on the Web. However, because HTTP is a stateless protocol, building a stateful application can present problems and restrictions. Avoiding the need to maintain state information is often a desirable goal. In this section, we list some reasons sessions are used and some reasons to avoid them.
Sessions can be used in web database applications for several reasons. Many traditional database applications use sessions to help control user interaction, while other applications use sessions to reduce server processing.
In a stateless environment, an application may need to repeat a computationally expensive or slow operation. An example might be a financial calculation that requires many SQL statements and calls to mathematics libraries before displaying the results on several web pages. An application that uses a session variable to remember the result exposes the user, and the server, to the cost of the calculation only once.
Often a web database application needs to present a series of screens in a controlled order. One style of application (known as a wizard) guides a user through what would otherwise be a complex task using a sequence of screens. Wizards are sometimes used for complex configurations, such as some software installations, and often alter the flow of screens based on user input.
Many web database applications validate data before creating or updating a row in the database, preventing erroneous data from being saved. Sessions can keep the intermediate data, so that incomplete data can be corrected when errors are detected. Earlier in this chapter, we used sessions to improve the interaction between the phonebook entry form and its validation script. In the case study, the fields entered by the user are held in an array as a session variable until the validation is successful.
Another example where intermediate results can be used is when a database application collects and validates data for a single row over several fill-in forms. We show you an example in Chapter 19 for the ordering process of our online winestore.
Sessions can be used to personalize a web site by tracking a user's preferences. For example, a user might specify a background color, layout preferences, or their interests. This information is then saved in the session store, and can be accessed by all scripts to personalize the application. In addition, the information might be saved in a database when the user logs out and restored later when they log in again.
The reasons to avoid sessions focus mainly on the stateless nature of HTTP. HTTP provides many features that enhance the performance and robustness of web browsing, and these are often limited by the requirements of a stateful application.
In an application that uses sessions, each HTTP request needs to be processed in the context of the session variables to which that request belongs. The state information recorded as the result of one request needs to be available to subsequent requests. Most applications that implement sessions store session variables at the web server. Once a session is created, all subsequent requests must be processed on the web server that holds the session variables. This requirement prevents such applications from using HTTP to distribute requests across multiple servers and therefore can't easily scale horizontally to handle large numbers of requests.
One way for a web database application to allow multiple web servers is to store session variables in the database tier. This approach is described in Appendix F, where we provide a PHP and MySQL implementation of a database-tier session store.
When a server that offers session management processes a request, identifying and accessing session variables introduces unavoidable overhead. The session overhead results in longer processing times for requests, which affects the performance and capacity of a site. While sessions can improve application performance (for example, a session can keep the result of an expensive operation) the gains may be limited and outweighed by the extra processing required.
You can configure PHP session management to store session variables in memory, however as the amount of memory used by the web server grows, a system may need to move portions of memory to disk through an operation known as swapping. Swapping memory in and out of disk storage is slow and can severely degrade the performance of a server. Servers that use files?such as the default PHP session management?incur the cost of reading and writing a file on disk each time a session is accessed.
Sessions can also cause synchronization problems. Because HTTP is stateless, there is no way of knowing when a user has really finished with an application. Other network applications can catch the fact that a connection has been dropped and clean up the state that was held on behalf of that user, even if the user did not use a logout procedure (such as typing exit or clicking on a logout button).
In the Telnet application, a user makes a connection to a system over the Internet. However, unlike HTTP, the TCP/IP connection for Telnet is kept for the length of the session, and if the connection is lost?say, if the client's PC crashes or the power is lost?the user is logged out of the remote system. With a session over the Web, the server doesn't know about these events and has to make a decision as to how long to keep the session information. In the case of PHP session management, a garbage collection scheme is used; garbage collection is discussed in the next section.
Because HTTP is stateless, browsers allow users to save URLs as a list of bookmarks or favorite sites. The user can return to a web site at a later date by simply selecting a bookmarked URL. Web sites that provide weather forecasts, stock prices, and even search results from a web search engine are examples of the sites a user might want to bookmark. Consider the URL for a fictional site that provides stock prices:
The URL encodes a query that identifies a particular stock, and presumably, the script stockprice.php uses the query to display the current stock price of the company. The URL can be bookmarked because it contains all that is needed to generate the stock price page for the given company code.
Bookmarking can fail when sessions are used in the script that's bookmarked. For example, if a user bookmarks a session-based stock price page and comes back in a week, the session that stored the company details is unlikely to still exist, and the script fails to display the desired company's stock price.
When you develop an application, you need to be aware that users frequently bookmark pages that use sessions. To deal with this, you need to gracefully handle a user unexpectedly arriving at a page when their session has been destroyed. For example, you might check if a session variable is set and, if not, you might redirect the user to the log in page. We show you how to do this in Chapter 11.
Sessions can provide a way for an intruder to break into a system. Sessions can be open to hijacking; an intruder can take over after a legitimate user has logged into an application. There is much debate about the security of session-based applications on the Web, and we discuss some issues of session security in Chapter 11.