Tải bản đầy đủ - 0 (trang)
Chapter 18. Processing Web Input with MySQL

Chapter 18. Processing Web Input with MySQL

Tải bản đầy đủ - 0trang

18.1 Introduction

The previous chapter describes how to retrieve information from MySQL and display it in web

pages using various types of HTML constructs such as tables or hyperlinks. That's a use of

MySQL to send information in one direction (from web server to user), but web-based

database programming can also serve to collect information sent in the other direction from

user to web server, such as the contents of a submitted form. If you're processing a survey

form, you might store the information for later use. If the form contains search keywords,

you'd use them as the basis for a query that searches the database for information the user

wants to see.

MySQL comes into these activities in a fairly obvious way, as the repository for storing

information or as the source from which search results are drawn. But before you can process

input from a form, you have to create the form and send it to the user. MySQL can help with

this, too, because it's often possible to use information stored in your database to generate

form elements such as radio buttons, checkboxes, pop-up menus, or scrolling lists:







You can select a set of items from a table that lists countries, states, or provinces and

convert them into a pop-up menu for use in a form that collects address information.







You can use the list of legal values for an



ENUM column that contains allowable



salutations (Mr., Mrs., and so forth) to generate a set of radio buttons.







You can use lists of available colors, sizes, or styles stored in an inventory database to

construct fields for a clothing ordering form.







If you have an application that allows the user to pick a database or table, you can run

a



SHOW DATABASES or SHOW TABLES query and use the resulting names to



create a list element.

By using database content to generate form elements, you lessen the amount of table-specific

knowledge your programs must have and allow them to determine what they need

automatically. A script that uses a database to figure out for itself how to generate form

elements adaptively handles changes to the database. To add a new country, create a new

row in the table that stores the list of countries. To add a new salutation, change the definition

of the



ENUM column. In each case, you change the set of items in a form element by



updating the database, not by modifying the script; the script adapts to the change

automatically, without additional programming.

The first part of this chapter covers the following topics relating to web input processing:







Generating forms and form elements.

One way to use database content for form construction is by selecting a list of items

from a table and using them to create the options in a list element. But metadata can

be used as well. There is a natural correspondence between



ENUM columns and



single-pick form elements like radio button sets or pop-up menus. In both cases, only



one from a set of possible values may be chosen. There is a similar correspondence

between



SET columns and multiple-pick elements like checkbox groups; any or all of



the possible values may be chosen. To construct metadata-based form elements,

obtain the column description from the table information returned by



SHOW



COLUMNS, extract the set of possible values, and use them for the items in the form

element.







Initializing forms using database contents.

In addition to using the database to create structural elements of forms, you can also

use it to initialize form field values. For example, to allow a user to modify an existing

record, retrieve it from the database and load it into an editing form's fields before

sending the form to the user.







Processing input gathered over the Web.

This includes input not only from form fields, but also the contents of uploaded files, or

parameters that are present in URLs. Regardless of where the information comes

from, you'll face a common set of issues in dealing with it: extracting and decoding the

information, performing constraint or validity checking on it, and re-encoding the

information for query construction to avoid generating malformed queries or storing

information inaccurately.



The second part of the chapter illustrates a few ways to apply the techniques developed in the

first part. These include applications that show how to use MySQL to present a web-based

search interface, create paged displays that contain next-page and previous-page links,

implement per-page hit counting and logging, and perform general Apache logging to a

database.

For the Perl, PHP, and Python example scripts discussed in this chapter, look under the apache

directory of the



recipes distribution. For JSP, the scripts are under the tomcat directory;

you should already have installed these in the process of setting up the mcb application

context (Recipe 16.4). Library routines used by the example scripts are located in files found

under the lib directory. Scripts to create the tables used here are located in the tables

directory.

Note that although the scripts in this chapter are intended to be invoked from your browser

after they have been installed, many of them (JSP pages excepted) can also be invoked from

the command line if you wish to see the raw HTML they produce.

To provide a concrete context for discussion, many of the form-processing examples in this

chapter are based on the following scenario: in the lucrative field of "construct-a-cow"

business endeavors, you run an operation that manufactures build-to-order ceramic bovine

figurines, and you want to design an online ordering application that lets customers make



selections for several aspects of the product. For each order, it's necessary to collect several

types of information:







Cow color.

The particular list of colors available at any particular time changes occasionally, so for

flexibility, the values can be stored in a database table. To change the set of colors

that customers can choose from, just update the table.







Cow size.

There is a fixed set of sizes that doesn't change often (small, medium, large), so the

values can be represented as elements of an







ENUM column.



The all-important cow accessory items.

These include a bell, horns, a sporty-looking tail ribbon, and a nose ring. Accessories

can be represented in a



SET column, because a customer may wish to select more



than one of them. In addition, you know from past experience that most customers

order horns and a cow bell, so it's reasonable to use those for the column's default

value.







Customer name and address (street, city, state).

The possible state names are already stored in the



states table, so they can be



used as the basis for the corresponding form element.

Given the preceding discussion, a



cow_order table might be designed like this:



CREATE TABLE cow_order

(

id

INT UNSIGNED NOT NULL AUTO_INCREMENT,

# cow color, figurine size, and accessory items

color

CHAR(20),

size

ENUM('small','medium','large') DEFAULT 'medium',

accessories SET('cow bell','horns','nose ring','tail ribbon')

DEFAULT 'cow bell,horns',

# customer name, street, city, and state (abbreviation)

cust_name

CHAR(40),

cust_street CHAR(40),

cust_city

CHAR(40),

cust_state CHAR(2),

PRIMARY KEY (id)

);

The



id column provides a unique identifier for each record. It's a good idea to have such a



value, and in fact will be necessary when we get to Recipe 18.5, which shows how to use web



forms to edit existing records. For that type of activity, you must be able to tell which record

to update, which is difficult without a unique record identifier.

The list of available colors is maintained in a separate table,



cow_color:



CREATE TABLE cow_color

(

color

CHAR(20)

);

For purposes of illustration, assume that the color table looks like this:



+---------------+

| color

|

+---------------+

| Black

|

| Black & White |

| Brown

|

| Cream

|

| Red

|

| Red & White

|

| See-Through

|

+---------------+

An application can use these tables to generate list elements in an order entry form, making it

unnecessary for the application to have a lot of specialized built-in knowledge about the

available options. The next several sections describe how to do this, and how to process the

input that you obtain when a user submits a form.



18.2 Creating Forms in Scripts

18.2.1 Problem

You want to write a script that gathers input from a user.



18.2.2 Solution

Create a fill-in form from within your script and send it to the user. The script can arrange to

have itself invoked again to process the form's contents when the user submits it.



18.2.3 Discussion

Web forms are a convenient way to allow your visitors to submit information, for example, to

provide search keywords, a completed survey result, or a response to a questionnaire. Forms

are also beneficial for you as a developer because they provide a structured way to associate

data values with names by which to refer to them.



A form begins and ends with



and
tags. Between those tags, you can



place other HTML constructs, including special elements that become input fields in the page

that the browser displays. The



tag that begins a form should include two attributes,

action and method. The action attribute tells the browser what to do with the form

when the user submits it. This will be the URL of the script that should be invoked to process

the form's contents. The



method attribute indicates to the browser what kind of HTTP

request it should use to submit the form. The value will be either GET or POST, depending

on the type of request you want the form submission to generate. The difference between

these two request methods is discussed in Recipe 18.6; for now, we'll always use



POST.



Most of the form-based web scripts shown in this chapter share some common behaviors:







When first invoked, the script generates a form and sends it to the user to be filled in.







The



action attribute of the form points back to the same script, so that when the



user completes the form and submits it, the script gets invoked again to process the

form's contents.







The script determines whether it's being invoked by a user for the first time or

whether it should process a submitted form by checking its execution environment to

see what input parameters are present. For the initial invocation, the environment will

contain none of the parameters named in the form.



This approach isn't the only one you can adopt, of course. One alternative is to place a form in

a static HTML page and have it point to the script that processes the form. Another is to have

one script generate the form and a second script process it.

If a form-creating script wants to have itself invoked again when the user submits the form, it

should determine its own pathname within the web server tree and use that value for the



action attribute of the opening tag. For example, if a script is installed as /cgibin/myscript in your web tree, the tag can be written like this:





Each API provides a way for a script to obtain its own pathname, so you don't have to

hardwire the name into the script. That gives you greater latitude to install the script where

you want.

In Perl scripts, the CGI.pm module provides three methods that are useful for creating



elements and constructing the action attribute. start_form( ) and

end_form( ) generate the opening and closing form tags, and url( ) returns the

script's own path. Using these methods, a script can generate a form like this:



print start_form (-action => url ( ), -method => "POST");



# ... generate form elements here ...

print end_form ( );

Actually, it's unnecessary to provide a



method argument; if you omit it, start_form(

) supplies a default request method of POST.

In PHP, a simple way to get a script's pathname is to use the



$PHP_SELF global variable:



print ("\n");

# ... generate form elements here ...

print ("
\n");

However, that won't work under some configurations of PHP, such as when the



register_globals setting is disabled.[1] Another way to get the script path is to

access the "PHP_SELF" member of the $HTTP_SERVER_VARS array or (as of PHP

4.1) the $_SERVER array. Unfortunately, checking several different sources of information

is a lot of fooling around just to get the script pathname in a way that works reliably for

different versions and configurations of PHP, so a utility routine to get the path is useful. The

following function,



get_self_path( ), shows how to use $_SERVER if it's available

and fall back to $HTTP_SERVER_VARS or $PHP_SELF otherwise. The function thus

prefers the most recently introduced language features, but still works for scripts running

under older versions of PHP:

[1]



register_globals is discussed further in Recipe 18.6.



function get_self_path ( )

{

global $HTTP_SERVER_VARS, $PHP_SELF;

if (isset ($_SERVER["PHP_SELF"]))

$val = $_SERVER["PHP_SELF"];

else if (isset ($HTTP_SERVER_VARS["PHP_SELF"]))

$val = $HTTP_SERVER_VARS["PHP_SELF"];

else

$val = $PHP_SELF;

return ($val);

}



$HTTP_SERVER_VARS and $PHP_SELF are global variables, but must be declared

as such explicitly using the global keyword if used in a non-global scope (such as within a

function). $_SERVER is a "superglobal" array and is accessible in any scope without being

declared as global.

The



get_self_path( ) function is part of the Cookbook_Webutils.php library file

located in the lib directory of the recipes distribution. If you install that file in a directory



that PHP searches when looking for include files, a script can obtain its own pathname and use

it to generate a form as follows:



include "Cookbook_Webutils.php";

$self_path = get_self_path ( );

print ("
\n");

# ... generate form elements here ...

print ("
\n");

Python scripts can get the script pathname by importing the



os module and accessing the



SCRIPT_NAME member of the os.environ object:

import os

print "
"

# ... generate form elements here ...

print "
"

In JSP pages, the request path is available through the implicit



request object that the

JSP processor makes available. Use that object's getRequestURI( ) method as

follows:





<%-- ... generate form elements here ... --%>





18.2.4 See Also

The examples in this section all have an empty body between the opening and closing form

tags. For a form to be useful, you'll need to create body elements that correspond to the types

of information that you want to obtain from users. It's possible to hardwire these elements

into a script, but Recipe 18.3 and Recipe 18.4 describe how MySQL can help you create the

elements on the fly based on information stored in your database.



18.3 Creating Single-Pick Form Elements from Database

Content

18.3.1 Problem

A form needs to present a field that offers the user a set of options but allows only one of

them to be selected.



18.3.2 Solution

Use a single-pick list element. These include radio button sets, pop-up menus, and scrolling

lists.



18.3.3 Discussion

Single-pick form elements allow you to present multiple choices from which a single option can

be selected. Our example involves several sets of single-pick choices:







The list of colors in the



cow_color table. These can be obtained with the following



query:



























mysql> SELECT color FROM cow_color ORDER BY color;

+---------------+

| color

|

+---------------+

| Black

|

| Black & White |

| Brown

|

| Cream

|

| Red

|

| Red & White

|

| See-Through

|

+---------------+

Note that some of the colors contain a



& character, which is special in HTML. This



means they will need HTML-encoding when placed into list elements. (Actually, we'll

perform encoding for all the list elements in the form, but these values illustrate why

it's a good idea to get in that habit.)







The list of legal figurine sizes in the



size column of the cow_order table. The



column is represented as an



ENUM, so the possible values and the default value can

be obtained using SHOW COLUMNS:

















mysql> SHOW COLUMNS FROM cow_order LIKE 'size'\G

*************************** 1. row ***************************

Field: size

Type: enum('small','medium','large')

Null: YES

Key:

Default: medium

Extra:







The list of state names and abbreviations. These are available from the

table:



















mysql> SELECT abbrev, name FROM states ORDER BY name;

+--------+----------------+

| abbrev | name

|

+--------+----------------+

| AL

| Alabama

|

| AK

| Alaska

|

| AZ

| Arizona

|



states













| AR

| CA

| CO

| CT

...



|

|

|

|



Arkansas

California

Colorado

Connecticut



|

|

|

|



The number of choices varies for each of these lists. As shown, there are 3 sizes, 7 colors, and

50 states. The size values are best represented as a set of radio buttons or a pop-up menu; a

scrolling list is unnecessary because the number of choices is small. The set of colors can

reasonably be displayed using any of the single-pick element types; it's small enough that a

set of radio buttons wouldn't take a lot of space, but large enough that you may want to allow

scrolling—particularly if you make additional colors available. The list of states is likely to have

more items than you'd want to present as a set of radio buttons, so it's most suitable for

presentation as a pop-up menu or scrolling list.

I will discuss the HTML syntax for these types of elements, then show how to generate them

from within scripts.







Radio buttons.

A group of radio buttons consists of



elements of type radio, all with

the same name attribute. Each element also includes a value attribute. A label to

display can be given after the tag. To mark an item as the default initial

selection, add a checked attribute. The following radio button group displays the

possible cow figurine sizes, using checked to mark medium as the initially

selected value:



small


/>medium

large







Pop-up menus

A pop-up menu is a list enclosed within



tags, with

each item in the menu enclosed within tags. Each

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 18. Processing Web Input with MySQL

Tải bản đầy đủ ngay(0 tr)

×