Showing posts with label MySQL. Show all posts
Showing posts with label MySQL. Show all posts

Tuesday, August 11, 2009

Installing and Configuring Apache

pache is an open-source Web server. A Web server delivers the files on the Web site to the visitor who wants to see the Web pages.

In most cases, you want to get Apache from the Web and install it yourself. Although Apache may already be installed on your computer (because most Linux distributions and Mac OS X include Apache), it’s unlikely to be the latest version. Or Apache may not have been installed with the options you need. Because of this, you’re often better off installing Apache yourself.

Selecting a Version of Apache

Apache is currently available in two versions: Apache 1.3 and Apache 2. Apache 2 is the newer version, released in April 2002. Apache 2 is not sup­ ported on Windows 9x installations; it requires Windows NT/2000/XP.

Many Linux distributions come with Apache 2 installed. However, as of this writing, the PHP Web site cautions against using Apache 2 with PHP in a pro­ duction environment. Check the Web page for the current status of PHP with Apache 2 at www.php.net/manual/en/install.apache2.php#install. apache2.unix.

At this time, the current versions are

Apache 2.0.47

Apache 1.3.28

Try to install the most current Apache version so that your Apache server includes all the latest security and bug fixes. New features are no longer being added to Apache 1.3, but bugs are still being fixed and security issues are being addressed. New versions of Apache 1.3 continue to be released but on a less frequent basis than for Apache 2.

Installing Apache

Apache can be downloaded and installed on your Web server for free. It’s available for almost every operating system, including Windows, Linux, many flavors of Unix, and Mac.

On Linux/Unix

To install Apache on Linux and Unix, you download the source code, compile it, and install it. This sounds daunting but is much easier than it sounds.

Before installing
Before installing Apache, check the following requirements:

Disk space: You may need as much as 50MB of disk space while installing. Apache will probably use 10MB after installation, although the amount varies depending on the options used and modules installed.

C compiler: Your computer has an ANSI-compliant C compiler installed.
GNU C (gcc) is a good choice.

Installing
To install Apache from source files, follow these steps:

1. Point your Web browser to httpd.apache.org, the Apache home
page.

2. Click the From a Mirror link under Download on the left side of
the page.

3. Scroll down to the Mirror section.

A specific mirror is selected for you. If you don’t want to use this mirror, select another. Or if you have problems downloading from this mirror, return to this page and select another.

4. Scroll further down the same page to the section for Apache 2 or for Apache 1.3, whichever you want to install. Locate and highlight the file you want to download.

For instance, at this time, the most recent version of Apache 1.3 for
Linux is apache-1.3.28.tar.gz.

5. Click the latest version to download it.

6. Select the option to save the file.

7. Navigate to where you want to save the source code (for example,
/usr/src). Then click Save.

8. After the download, change to the download directory (for example,
cd-/usr/src).

You see a file named apache-, followed by the version name and tar.gz. This file is called a tarball because it contains many files com­ pressed into the tarball file by a program called tar.

Be sure you’re using an account that has permission to write into
/usr/src, such as root.

9. Verify the downloaded file to be sure it hasn’t been tampered with. To verify the file, follow these steps:

a. Download two files from www.apache.org/dist/httpd/: One file to download is named KEYS. The second file is named with the same file name, including version number, as the source, but the filename ends in .asc.

b. Type one of the following lines, depending on which version of PGP
is installed on your computer:

pgp <KEYS
gpg --import KEYS

Several lines of output are displayed.

c. Type one of the following lines, with the correct version number.

pgp apache-1.3.28.tar.gz.asc
gpg --verify apache-1.3.28.tar.gz.asc

You should see something similar to the following:

Good signature from user “Sander Striker”

This is what you are looking for. Several messages will probably be displayed, but the preceding message is the important one. You might also see a message stating that the relationship between the key and the signer of the key cannot be verified. This is okay.

If you don’t get a message that the signature is good, the file might have been tempered with and may be dangerous. In this case, repeat the process starting with Step 1 and select a different mirror to download from.

10. Unpack the tarball.

The command to unpack the tarball for version 1.3.28 is the following:

gunzip -c apache-1.3.28.tar.gz | tar -xf –

A new directory called apache-1.3.28 is created with several subdirec­
tories containing all the files that you just unpacked from the tarball.

11. Change to the new directory that was created when you unpacked the tarball.

For example, you can use a command like the following:

cd apache-1.3.28

12. Type the configure command.

The configure command consists of ./configure followed by all the necessary options. If you can use all the default options, you can use configure without any options. However, to use Apache with PHP as a module, use the configure command as follows:

./configure --enable-module=so

One of the more important installation options you may want to use is prefix, which sets a different location where you want Apache to be installed. By default, Apache is installed at /usr/local/apache or usr/local/apache2. You can change the installation location with the following line:

./configure -–prefix=/software/apache

You can see a list of all the available options by typing the following line:

./configure -–help

This script may take a while to finish running. As it runs, it displays output. When the script is done, the system prompt is displayed. If configure encounters a problem, it displays a descriptive error message.

13. Type the following command:

make

This command builds the Apache server. It may take several minutes to finish running. As it runs, it displays messages telling you what it’s doing. There may be occasional longer pauses as it completes some action. When it’s finished, it returns to the system prompt. If it has a problem, it displays a descriptive error message.

14. Type the following command:

make install

This command installs the Apache software in the proper locations, based on the configure command you used in Step 11.

15. Start the Apache Web server.

See the following section, “Starting and Stopping Apache,” for details.

16. Type the URL for your Web site (for example, www.mysite.com or
localhost) into a browser to test Apache.

If all goes well, you see the Apache message telling you that Apache is working.

Starting and stopping Apache
A script named apachectl is available to control the server. By default, the script is stored in a subdirectory called bin in the directory where Apache is installed. Some Linux distributions may put it in another directory.

The script requires a keyword. The most common keywords are start, stop, and restart. The general syntax is as follows:

path/apachectl keyword

For example, if Apache was installed in the default directory, type the follow­
ing line to start Apache:

/usr/local/apache/bin/apachectl start

Starting Apache
The apachectl script starts the Apache server, which then runs in the back­ ground, listening for HTTP requests. By default, the compiled Apache server is named httpd and is stored in the same directory as the apachectl script, although you can change the name and location when you install Apache. The
apachectl script serves as an interface to the compiled server, called httpd.

You can run the httpd server directly, but it’s better to use apachectl as an interface. The apachect1 script manages and checks data that httpd commands require. Use the apachectl script to start Apache with the fol­ lowing command:

/usr/local/apache/bin/apachectl start

The apachectl script contains a line that runs httpd. By default, apachectl
looks for httpd in the default location — /usr/local/apache/bin or
/usr/local/apache2/bin. If you installed Apache in a nonstandard loca­ tion, you may need to edit apachectl to use the correct path. Open apachectl and then search for the following line:

HTTPD=’/usr/local/apache2/bin/httpd’

Change the path to the location where you installed httpd. For example, the new line might be this:

HTTPD=’/usr/mystuff/bin/httpd’

After you start Apache, you can check whether Apache is running by looking at the processes on your computer. Type the following command to display a list of the processes that are running:

ps –A

If Apache is running, the list of processes includes some httpd processes.

Getting information from Apache
You can use options with the httpd server to obtain information about Apache. For instance, you can find out what version of Apache is installed by changing to the directory with httpd and typing

httpd -v

Or, probably, ./httpd –v. You can find out what modules are installed with
Apache by typing the following:

httpd -l

To see all the options that are available, type the following:

httpd -h

Restarting Apache
Whenever you change the configuration file, the new directives take effect the next time Apache starts. If Apache is shut down when you make the changes, you can start Apache as described earlier in “Starting Apache.” However, if Apache is running, you can’t use start to restart it. Using start results in an error message saying that Apache is already running. You can use the following command to restart Apache when it’s currently running:

/usr/local/apache2/bin/apachectl restart

Although the restart command usually works, sometimes it doesn’t. If you restart Apache and the new settings don’t seem to be in effect, try stopping Apache and starting it again. Sometimes this solves the problem.

Stopping Apache
To stop Apache, use the following command:

/usr/local/apache/bin/apachectl stop

You can check to see that Apache is stopped by checking the processes that are running on your computer by using the following command:

ps –A

The output from ps should not include any httpd processes.

On Windows

You can install Apache on almost any version of Windows, although Windows
NT/2000/XP are preferred.

Installing
To install Apache, follow these steps:

1. Point your Web browser to httpd.apache.org, the Apache home
page.

2. Click the From a Mirror link under Download on the left side of
the page.

3. Scroll down to the Mirror section.

A specific mirror is selected for you. If you don’t want to use this mirror, select another. Or if you have problems downloading from this mirror, return to this page and select another.

4. Scroll further down the same page to the section for Apache 2 or for Apache 1.3, whichever you want to install. Locate and highlight the line for Win 32 Binary (MSI installer).

For instance, at this time, the most recent version of Apache 1.3 for
Windows is apache_1.3.28.

5. Click the filename to download it.

6. Select the option to save the file.

7. Navigate to where you want to save the installer. This should be a tem­
porary directory, such as a download directory. Then click Save.

After the download is complete, you see a file in the download location containing all the files needed. The file is named apache, followed by the version number and win32-x86-no_src.msi. For the current version, the file is named apache_1.3.28-win32-x86-no_src.msi.

8. Double-click the downloaded file.

The Apache installation wizard begins, and a welcome screen is displayed.

9. Click Next.

The license agreement is displayed.

10. Select I Accept the Terms in the License Agreements and then
click Next.

If you don’t accept the terms, you can’t install the software. A screen of information about Apache is displayed.
11. Click Next.

A screen is displayed asking for information.

12. Enter the requested information and then click Next.

The information requested is

• Domain Name: Type your domain name, such as MyFineCompany.com. If you’re installing Apache for testing pur­ poses and plan only to access it from the same machine where it’s installed, you can enter localhost.

• Server Name: Type the name of the server where you’re installing Apache, such as www.MyFineCompany.com or s1.mycompany.com. If you’re installing Apache for testing pur­ poses and plan only to access it from the same machine where it’s installed, you can enter localhost.

• E-mail Address: Type the e-mail address that you want to receive e-mail message about the Web server, such as WebServer@ MyFineCompany.com.

• Run Mode: Select whether you want Apache to run as a service, starting automatically when the computer boots up, or whether you want to start Apache manually when you want to use it.
In most cases, you want the first choice — to run Apache as a service.

The installation type screen is displayed.

13. Select an installation type and click Next.

In most cases, you should select Complete. Only advanced users who understand Apache well should select Custom.

A screen showing where Apache is to be installed is displayed.

14. Select the directory where you want Apache installed and click Next.

You see the default installation directory for Apache, usually C:\Program Files\Apache Group. If this is okay, click Next. If you want Apache installed in a different directory, click Change and select a different directory, click OK, and click Next.

A screen is displayed that says the wizard is ready to install Apache.

15. Click Install.

If you need to, you can go back and change any of the information you entered before proceeding with the installation.

A screen displays the progress while Apache is being installed. When the installation is complete, a screen is displayed saying that the wizard has successfully completed the installation.

16. Click Finish to exit the installation wizard.

Apache is installed on your computer based on your operating system. If you install it on Windows NT/2000/XP, it is automatically installed as a service that automatically starts when your computer starts. If you install it on Windows 95/98/Me, you need to start it manually or set it up so that it starts

automatically when your computer boots. See the next section, “Starting and stopping Apache,” for more information.

Starting and stopping Apache
When you install Apache on Windows NT/2000/XP, it’s automatically installed as a service and started. It’s ready to use. You can test it by typing your Web site name (or localhost) into your browser window. You see a welcome Web page that reads, “If you can see this, it means that the installation of the Apache Web server software on this system was successful.” On Windows
95/98/Me, you have to start Apache manually, using the menu.

Apache installs menu items for stopping and starting Apache during installa­ tion. You can find this menu at Start➪Programs➪Apache HTTP Server➪ Control Apache Server.

The menu you use to start and stop Apache provides the following menu items:

Start: Used to start Apache when it is not running. If you click this item when Apache is running, you see an error message saying that Apache has already been started.

Stop: Used to stop Apache when it is running. If you click this item when Apache is not running, you see an error message saying that Apache is not running.

Restart: Used to restart Apache when it is running. If you make changes to Apache’s configuration, you need to restart Apache before the changes become effective.

Getting information from Apache
Sometimes you want to know information about your Apache installation, such as the version that’s installed. You can get this information from Apache by opening a command prompt window (Start➪Programs➪Accessories➪ Command Prompt), changing to the directory where Apache is installed
(such as, cd C:\Apache), and accessing Apache with options. For example, to find out which version of Apache is installed, type the following in the command prompt window:

Apache –v

To find out what modules are compiled into Apache, type

Apache –l

You can also start and stop Apache directly, as follows:

Apache -k start
Apache -k stop

You can see all the options available by typing the following:

Apache -h

On Mac

Installing Apache on the Mac is very similar to installing Apache on Unix/Linux. You download the source code and compile it. To install Apache on the Mac, follow these steps:

1. Download the source code, save it in a directory, and change to the directory where the downloaded file is saved.

Follow Steps 1–8 of the directions for Unix/Linux.

You will see a file named httpd, followed by the version name and tar.gz, such as, httpd-1.3.28.tar.gz. This file is the tarball — a single file that contains all the files needed, compressed into one file.

2. Unpack the tarball by using a command similar to the following:

gnutar -xzf /httpd_1.3.28.tar.gz

After unpacking the tarball, you see a directory called httpd_1.3.28. This directory contains several subdirectories and many files.

3. Use a cd command to change to the new directory created when you unpacked the tarball (for example, cd httpd_1.3.28).

4. Type the following command:

./configure --enable-module=most --enable-shared=max

This command may take some time to run.

5. Type the following command to build the Apache server:

make

This command may take a few minutes to run. It displays messages while it is running, with occasional pauses for a process to finish running.

6. Type the following command to install Apache:

sudo make install

7. Start the Apache Web server.

See the section, “Starting and Stopping Apache,” under Unix/Linux for details.

8. Type the URL for your Web site (for example, www.mysite.com or
localhost) into a browser to test Apache.

If all goes well, you see a Web page telling you that Apache is working.

Configuring Apache

When Apache starts, it reads information from a configuration file. If Apache can’t read the configuration file, it can’t start. Unless you tell Apache to use a different configuration file, it looks for the file conf/httpd.conf in the direc­ tory where Apache is installed.

Changing settings

Apache behaves according to commands, called directives, in the configura­ tion file. You can change some of Apache’s behavior by editing the configura­ tion file and restarting Apache so that it reads the new directives.

The configuration file is a text file containing commands called directives. Apache behaves according to the directives in this file. In most cases, the default settings allow Apache to start and run on your system. However, you may need to change the settings in some cases. Some reasons you might want to change the settings are

Installing PHP: If you install PHP, you need to configure Apache to rec­ ognize PHP programs. How to change the Apache configuration for PHP is described in Appendix B.

Changing your Web space: Apache looks for Web page files in a specific directory and its subdirectories, often called your Web space. You can change the location of your Web space.

Changing the port where Apache listens: By default, Apache listens for file requests on port 80. You can configure Apache to listen on a different port.

To change any settings, edit the file httpd.conf. On Windows, you can access this file through the menu at Start➪Programs➪Apache HTTPD Server➪Configure Apache Server➪Edit the Apache httpd.conf File. When you click this menu item, the httpd.conf file is opened in Notepad.

The httpd.conf file has comments (beginning with #) that describe the directives, but you should be sure you understand their function before changing any. All directives are documented on the Apache Web site.

When adding or change file path/names, use forward slashes, even when the directory is on Windows. Apache can figure it out. Also, path/names don’t need to be in quotes unless they include special characters. A colon (:) is a special character; the underscore (_) and hyphen (-) are not. For instance, to indicate a Windows directory, you would use something like the following:

“c:/temp/mydir”

Remember to restart Apache after you change any settings. The settings don’t go into effect until Apache is restarted. Sometimes using the restart command doesn’t work to change the settings. If the new settings don’t seem to be in effect, try stopping the server with stop and then starting it with start.

Changing the location of your Web space

By default, Apache looks for your Web page files in the subdirectory htdocs in the directory where Apache is installed. You can change this with the DocumentRoot directive. Look for the line that begins with DocumentRoot, such as the following:

DocumentRoot “C:/Program Files/Apache Group/Apache/htdocs”

Change the file path/name to the location where you want to store your Web page files. Don’t include a forward slash ( / ) on the end of the directory path. For example, the following might be your new directive:

DocumentRoot /usr/mysrver/Apache2/webpages

Changing the port number

By default, Apache listens on port 80. You might want to change this, for instance, if you are setting up a second Apache server for testing purposes. The port is set by using the Listen directive as follows:

Listen 80

With Apache 2, the Listen directive is required. If no Listen directive is included, Apache 2 won’t start.

You can change the port number as follows:

Listen 8080

Remember to restart Apache after you change any directives.

Installing PHP with Apache

lthough PHP runs on many platforms, I describe installing it on
Unix/Linux/ Mac and Windows, which includes the majority of Web sites on the Internet. PHP runs with several Web servers, but these instructions focus mainly on Apache and Internet Information Servers (IIS) because together they power almost 90 percent of the Web sites on the Internet. If you need instructions for other operating systems or Web servers, see the PHP Web site (www.php.net).

This section provides installation instructions for PHP 5. If you’re installing an earlier version, there are some small differences, so read the file install.txt provided with the PHP distribution.

Installing PHP on Unix/Linux/Mac
with Apache

On Unix/Linux

You can install PHP as an Apache module or as a stand-alone interpreter. If you’re using PHP as a scripting language in Web pages to interact with a data­ base, install PHP as an Apache module. PHP is faster and more secure as a module. I don’t discuss PHP as a stand-alone interpreter in this book.

You install PHP by downloading source files, compiling these files, and installing the compiled programs. This process isn’t as technical and daunt­ ing as it sounds. I provide step-by-step instructions in the next few sections. Read all the way through the steps before you begin the installation procedure.

For Linux users only: PHP for Linux is available in an RPM as well as in source files. It might be in RPM format on your distribution CD. However, when you install PHP from an RPM, you can’t control the options that PHP is installed with. For instance, you need to install PHP with MySQL support enabled, but the RPM may not have MySQL support enabled. MySQL is

popular, so many RPMs enable support for it, but it is out of your control. Also, an RPM usually enables all the most popular options, so an RPM might enable options that you don’t need. Consequently, the simplest and most effi­ cient way to install PHP could be from the source. If you’re familiar with RPMs, feel free to find an RPM and install it. RPMs are available. However, I
am providing steps for source code installation, not RPMs.

Before installing
Before beginning to install PHP, check the following:

The Apache module mod_so is installed. It usually is. To display a list of all the modules, type the following:

httpd –l.

You might have to be in the directory where httpd is located before
the command will work. The output usually shows a long list of modules. All you need to be concerned with for PHP is mod_so. If mod_so is not loaded, Apache must be reinstalled using the enable-module=so option.

The apxs utility is installed. apxs is installed when Apache is installed.
You should be able to find a file called apxs. If Apache were installed on Linux from an RPM, apxs might not have been installed. Some RPMs for Apache consist of two RPMs: one for the basic Apache server and one for Apache development tools. Possibly the RPM with the development tools, which installs apxs, needs to be installed.

Apache version is recent. See Appendix C for information about Apache versions.

To check the version, type the following:

httpd --v

You might have to be in the directory where httpd is located before the command will work.

Installing
To install PHP on Unix/Linux with an Apache Web server, follow these steps:

1. Point your Web browser to www.php.net, the PHP home page.

2. Click Downloads.

3. Click the latest version of the PHP source code, which is version 5.0.0 as of this writing.

The file you are about to download contains many files compressed into one file — a tarball.

A dialog box opens.

4. Select the option to save the file.

A dialog box opens that lets you select where the file will be saved.

5. Navigate to where you want to save the source code (for example,
/usr/src). Then click Save.

6. After the download, change to the download directory (for instance,
cd-/usr/src).

You see a file named php-, followed by the version name and tar.gz.

7. Unpack the tarball. The command for PHP version 5.0.0 is

gunzip -c php-5.0.0.tar.gz | tar -xf –

A new directory called php-5.0.0 is created with several subdirectories.

8. Change to the new directory that was created when you unpacked the tarball. For example:

cd php-5.0.0

9. Type the configure command.

Use one of the two following configure commands:

./configure --with-mysql=DIR --with-apxs
./configure --with-mysqli=DIR --with-apxs

Use mysql if you’re using MySQL 4.0 or earlier; use mysqli if you’re using MySQL 4.1 or later. DIR is the path to the appropriate MySQL directory. When using with-mysql, use the path to the directory where mysql is installed, for instance:

--with-mysql=/user/local/mysql

When using with-mysqli, use the path to the file named mysql_
config.

If you’re using Apache 2, use the option with-apxs2. (See Appendix C
for information on using Apache 2.)

You will see many lines of output. Wait until the configure command has completed. This might take a few minutes. If the configure command fails, it provides an informative message. Usually, the problem is missing software. You see an error message indicating that xyz software can’t be
found or that xyz version 5.6 is required but xyz version 4.2 is found. You need to install or update the software that PHP needs.

If the apxs utility isn’t installed in the expected location, you see an error message indicating that apxs couldn’t be found. If you get this message, check the location where apxs is installed (find / -name apxs) and include the path in the with-apxs option of the configure

command: —with-apxs=/usr/sbin/apxs or /usr/local/apache/ bin/apxs. If you’re using Apache 2, the option is —with-apxs2=/usr/ sbin/apxs.

10. Type make.

You will see many lines of output. Wait until it is finished. This might take a few minutes.

11. Type make install.

On Mac OS X

With the release of PHP 4.3, you can install PHP on Mac OS X as easily as on
Unix/Linux. You install PHP by downloading source files, compiling the
source files, and installing the compiled programs. This process isn’t as tech­ nical and daunting as it might appear. I provide step-by-step instructions in the next few sections. Read all the way through the steps before you begin the installation procedure to be sure that you understand it all clearly and have everything prepared so you don’t have to stop in the middle of the installation.

Before installing
If you want to use PHP with Apache for your Web site, Apache must be installed. Most Mac OS X systems come with Apache already installed. For more information on Apache, see Appendix C.

Before beginning to install PHP, check the following:

The Apache version is recent: See Appendix C for a discussion of Apache versions. To check the version, type the following on the com­ mand line:

httpd --v

You might have to be in the directory where httpd is located before the command will work.

As of this writing, PHP with Apache 2 is still considered experimental. For use on production Web sites, it might be better to use Apache 1.3 than Apache 2. See Appendix C for a discussion of Apache versions. Keep updated on the status of PHP with Apache 2 by checking the PHP Web site at www.php.net/manual/en/install.apache2.php.

The Apache module mod_so is installed. It usually is. To display a list of all the modules, type the following:

httpd –l.

You might have to be in the directory where httpd is located before the command will work. The output usually shows a long list of modules. All you need to be concerned with for PHP is mod_so. If mod_so is not loaded, Apache must be reinstalled.

The apxs utility is installed. apxs is normally installed when Apache is installed. To determine whether it’s installed on your computer, you should look for a file called apxs, usually in the /usr/sbin/apxs direc­ tory. If you can find the file, apxs is installed; if not, it’s not.

The files from the Developer’s Tools CD are installed. This CD is sup­ plemental to the main Mac OS X distribution. If you can’t find the CD, you can download the tools from the Apple Developer Connection Web site at developer.apple.com/tools/macosxtools.html.

Installing
To install PHP on Mac, follow these steps:

1. Point your Web browser to www.php.net, which is the PHP home
page.

2. Click Downloads.

3. Click the latest version of the PHP source code, which is version 5.0.0 as of this writing.

A dialog box opens.

4. Select the option to save the file.

A dialog box opens that lets you select where the file is to be saved.

5. Navigate to where you want to save the source code (for example,
/usr/src), and then click Save.

6. After the download, change to the download directory (for example,
cd-/usr/src).

You see a file named php-, followed by the version name and tar.gz. This file is contains several files compressed into one file. The file might have been unpacked by the StuffIt Expander automatically so that you see the directory php-5.0.0. If so, skip to Step 8.

7. Unpack the tarball.

The command to unpack the tarball for PHP version 5.0.0 is

tar xvfz php-5.0.0.tar.gz

A new directory called php-5.0.0 is created with several subdirectories.

8. Change to the new directory that was created when you unpacked the tarball.

For example, you can use a command like the following:

cd php-5.0.0

9. Type the configure command:

The configure command consists of ./configure followed by all the necessary options. The minimum set of options is as follows:

• Location options: Because the Mac stores files in different loca­ tions than the PHP default locations, you need to tell PHP where files are located. Use the following options:

--prefix=/usr
--sysconfdir=/etc
--localstatedir=/var
--mandir=/usr/share/man

• zlib option: --with-zlib

• Apache option: If you are installing PHP for use with Apache, use the following option: --with-apxs or --with-apxs2.

Therefore, the most likely configuration command that you should use is

./configure --prefix=/usr --sysconfdir=/etc
--localstatedir=/var --mandir=/usr/share/man
--with-apxs –-with-zlib

You also need to use an option to include MySQL support. Use one of the following options:

--with-mysql=DIR
--with-mysqli=DIR

Use mysql if you’re using MySQL 4.0 or earlier; use mysqli if you’re using MySQL 4.1 or later. DIR is the path to the appropriate MySQL directory. When using with-mysql, use the path to the directory where mysql is installed, as follows:

--with-mysql=/user/local/mysql

When using with-mysqli, use the path to the file named
mysql_config.

You can type the configure command on one line. If you use more than one line, type a \ at the end of each line.

You will see many lines of output. Wait until the configure command has completed. This may take a few minutes.

If the apxs utility isn’t installed in the expected location, you see
an error message, indicating that apxs could not be found. If you get this error message, check the location where apxs is installed
(find / -name apxs) and include the path in the with-apxs option of the configure command: --with-apxs=/usr/sbin/apxs.

You might need to use many other options, such as options for the data­ base that you’re using or options that change the directories where PHP is installed. These configure options are discussed in the section, “Installation Options,” later in this Appendix.

10. Type make.

You will see many lines of output. Wait until it is finished. This might take a few minutes.

11. Type sudo make install.

Installation Options

The previous sections give you steps to quickly install PHP with the options needed for the applications in this book. However, you might want to install PHP differently. For instance, all the PHP programs and files are installed in their default locations, but you might need to install PHP in different loca­ tions. Or you might be planning applications using additional software. You can use additional command line options if you need to configure PHP for your specific needs. Just add the options to the command shown in Step 13 of the Unix/Linux installation instructions or Step 9 in the Mac installation
instructions. In general, the order of the options in the command line doesn’t matter. Table B-1 shows the most commonly used options for PHP. To see a list of all possible options, type ./configure —help.

Configuring Apache for PHP

You must configure Apache to recognize and run PHP files. An Apache config­ uration file, httpd.conf, is on your system, possibly in /etc or in /usr/ local/apache/conf. You must edit this file before PHP can run properly.

Follow these steps to configure your system for PHP:

1. Open the httpd.conf file so you can make changes.

2. Configure Apache to load the PHP module.

Find the list of LoadModule statements. Look for the following line:

LoadModule php5_module libexec/libphp5.so.

If this line isn’t there, add it. If a pound sign (#) is at the beginning of the line, remove the pound sign.

3. Configure Apache to recognize PHP extensions.

You need to tell Apache which files might contain PHP code. Look for a section describing AddType. You might see one or more AddType lines for other software. Look for the AddType line for PHP, as follows:

AddType application/x-httpd-php .php

If you find it with a pound sign (#) at the beginning of the line, remove
the pound sign (#). If you don’t find this line, add it to the AddType state­ ments. This line tells Apache to look for PHP code in all files with a .php extension. You can specify any extension or series of extensions.

4. Start (if it is not running) or restart (if it is running) the Apache httpd server.

You can start or restart the server by using a script that was installed on your system during installation. This script might be apachectl or httpd.apache, and might be located in /bin or
/usr/local/apache/bin. For example, you might be able to start the server by typing apachectl start, restart it by using apachectl restart, or stop it by using apachectl stop. Sometimes restarting is not sufficient; you must stop the server first and then start it.

On Windows

PHP runs on Windows 98/Me and Windows NT/2000/XP. It does not run on
Windows 3.1. Windows 95 is no longer supported as of PHP 4.3.0.

To install PHP 5 on Windows with MySQL support, you download a Zip file that contains all the necessary files for PHP, The following steps show how to install PHP on Windows:

1. Point your Web browser at www.php.net.

2. Click Download.

3. Go to the Windows Binaries section. Click the download link for the Sip package for the most recent version of PHP (as of this writing, 5.0.0).

4. Click the link for a mirror Web site from which to download the file and choose the site closest to your location.

A dialog box opens.

5. Select the option to save the file.

A dialog box opens that lets you select where the file will be saved.

6. Navigate to where you want the file to be downloaded. This should be a temporary location, such as a download directory. Then click Save.

After the download is complete, you see a file in the download location containing all the files needed. The file is named php, followed by the version number and win32.zip. For the current version, the file is named php5.0.0-Win32.zip-.

7. Extract the files from the .zip file into the directory where you want
PHP to be installed, such as c:\php.

If you double click the .zip file, it should open in the software on your computer that extracts files from .zip files, such as WinZip or PKZIP. Select the menu item for extract and select the directory into which the files are to be extracted. C:\php is a good choice for installation because many configuration files assume that’s where PHP is installed, so the default settings are more likely to be correct.

It’s best not to install PHP in a directory with a space in the path, such as in Program Files/PHP. It sometimes causes problems.

You now have a directory with several subdirectories that contain the files that you need.

8. Copy the file required for MySQL to the PHP main directory.

The file is located in the ext subdirectory in the directory where PHP is installed. Copy one of the following files, depending on which version of MySQL you’re using:

ext\php_mysql.dll (for MySQL 4.0 or earlier)
ext\php_mysqli.dll (for MySQL 4.1 or later)

Copy the two files into the main PHP directory, such as c:\php.

Another file is required for MySQL support, named libmysql.dll. This file should already be located in the main PHP directory. If it isn’t there, you need to find it and copy it there. If it’s not in your PHP directory, it’s usually installed with MySQL, so find it in the directory where MySQL was installed, perhaps in a bin subdirectory, such as c:\mysql\bin.

Occasionally PHP needs DLL files that it can’t find. When this happens, PHP displays an error message when you run a PHP program, saying
that it can’t find a particular DLL. You can usually find the DLL in the ext
subdirectory and copy it into the main PHP directory.

9. Configure your Web server.

The next section provides instructions for configuring your Web server.

10. Configure PHP.

Follow the directions in the section later in this chapter.

Configuring Your Web Server for PHP

Your Web server needs to be configured to recognize PHP scripts and run them. Follow the steps in the section for your Web server:

Configuring Apache

You must edit an Apache configuration file, called httpd.conf, before PHP
can run properly To configure Apache for PHP, follow these steps:

1. Open httpd.conf for editing.
You might be able to edit it by choosing Start➪Programs➪Apache
HTTPD Server➪Configure Apache Server➪Edit Configuration.

If Edit Configuration isn’t on your Start menu, find the httpd.conf file on your hard disk, usually in the directory where Apache is installed, in a conf subdirectory (for example, c:\program files\Apache group\ Apache\conf). Open this file in an editor, such as Notepad or WordPad.

2. Set up a nickname for the directory where PHP is installed.

A ScriptAlias statement is used to set up a name for the directory where PHP is installed. Look for ScriptAlias statements in the httpd.conf file. You might see some for other software. If you don’t see one for PHP, add the following:

ScriptAlias /php/ “c:/php/”

The first argument is the name, and the second is what it represents. In this statement, the name /php/ is used to mean c:/php/. Notice that Apache prefers forward slashes. Also, note that the directory path with a special character (the colon) in it is enclosed in double quotes.

3. Configure Apache to run PHP when it encounters a file that is a PHP
program.

An Action statement is used to tell Apache to run PHP when it encoun­ ters a file that is a PHP program. If you don’t find an Action statement for PHP, add the following:

Action application/x-httpd-php /php/php-cgi.exe

Prior to PHP 5, the PHP interpreter was named php.exe. If you’re installing an earlier version of PHP, the line should end with php.exe, rather than php-cgi.exe. If you find an action line for PHP in your httpd.conf file, be sure that it uses the correct PHP interpreter name for the version of PHP that you’re installing.

Notice that the Action statement uses the name defined in the ScriptAlias statement. It locates php-cgi.exe in /php/, which means c:/php/. If you change the ScriptAlias statement to say c:/php27/, the Action statement would then look for php-cgi.exe in c:/php27.

4. You need to tell Apache which files are PHP programs.

Look for a section describing AddType. This section might contain one or more AddType lines for other software. The AddType line for PHP is

AddType application/x-httpd-php .php

Look for this line. If you find it with a pound sign (#) at the beginning of the line, remove the pound sign. If you don’t find the line, add it to the list of AddType statements. You can specify any extension or series of extensions.

This line tells Apache that files with the .php extension are files of the type application/x-httpd-php. Apache then looks at the Action statement from Step 2 and knows that files of this type should be run using the program /php/php.exe.

5. Start (if it is not running) or restart (if it is running) Apache.

You can start it as a service on Windows NT/2000 by choosing Start➪ Programs➪Apache HTTPD Server➪Control Apache Server and then selecting Start or Restart.
Or you can start it on Windows 98/ME by choosing Start➪Programs➪
Apache Web Server➪Management.

Sometimes restarting Apache is not sufficient; you must stop it first and then start it. In addition, your computer is undoubtedly set up so that Apache will start whenever the computer starts. Therefore, you can shut down and then start your computer to restart Apache.

Configuring IIS

To configure IIS to work with PHP, follow these steps:

1. Enter the IIS Management Console.

You should be able to enter by choosing Start➪Programs➪ Administrative Tools➪Internet Services Manager or Start➪Settings➪ Control Panel ➪Administrative Tools➪Internet Services Manager.

2. Right-click your Web site (such as Default Web Site).

3. Select Properties.

4. Select the Home Directory tab.

5. Click the Configuration button.

6. Choose the App Mappings tab.

7. Click Add.

8. In the Executable box, type the path to the PHP interpreter: for exam­
ple, type c:\php\php-cgi.exe.

9. In the Extension box, type .php.

This will be the extension that is associated with PHP scripts.

10. Select the Script Engine check box.

11. Click OK.

Repeat Steps 6–10 if you want any additional extensions, in addition to
.php, to be processed by PHP, such as .phtml.

Configuring PHP

PHP uses settings in a file named php.ini to control some of its behavior. PHP looks for php.ini when it begins and uses the settings that it finds.
If PHP can’t find the file, it uses a set of default settings.

The default location for the php.ini file is one of the following unless you
change it during installation:

Windows: The system directory, depending on the Windows version, as follows:

• Windows 98/Me/XP: windows

• Windows NT/2000: winnt

Unix/Linux/Mac: /usr/local/lib

If the php.ini file isn’t installed during installation, you need to install it now. A configuration file with default settings, called php.ini-dist, is included in the PHP distribution. Copy this file into the appropriate location, such as the default locations mentioned above, changing its name to php.ini.

If you have a previous version of PHP installed (such as PHP 4.3), make a backup copy of the php.ini file before you overwrite it with the php.ini file for PHP 5. You can then see the settings you are currently using and change the settings in the new php.ini file to match the current settings.

To configure PHP, follow these steps.

1. Open the php.ini file for editing.

2. Activate mysql or mysqli support.

Look for a list of extensions. Find the line for mysql (if you’re using MySQL 4.0 or earlier) or for mysqli (if you’re using MySQL 4.1 or later), as follows:

;extension=php_mysql.dll
;extension=php_mysqli.dll

Notice the semicolon (;) at the beginning of the lines. To activate the extension, remove the semicolon. If the extension line isn’t in your php.ini file, add it.

3. Only if you’re using PHP with the IIS Web server, turn off force redi­
rect. Find the line:

;cgi.force_redirect = 1

You need to remove the semicolon so that the settings is active, and also change the 1 to 0. After the changes, the line looks as follows:

cgi.force_redirect = 0

4. Save the php.ini file.

5. You might need to restart the Apache server before the new settings go into effect.

In general, the remaining default settings allow PHP to run okay, but you might need to edit some of these settings for specific reasons. I discuss settings in the php.ini file throughout the book when I discuss a topic that might require you to change settings. For example, PHP error-handling actions can be changed by settings in the php.ini file. The possible settings for error handling and their effects are discussed in Chapter 4.

Installing MySQL

lthough MySQL runs on many platforms, I describe how to install it on
Linux, Unix, Windows, and Mac, which together account for the major­ ity of Web sites on the Internet. Be sure to read the instructions all the way through before beginning the installation.

MySQL can be installed most easily from binaries — precompiled, ready-to- install packages. Binaries are available for most operating systems: Linux, Windows, Mac, FreeBSD, many flavors of Unix, and others. If such a package is available for your operating system, use it. Only install MySQL from source if it’s totally necessary, such as when there’s no binary for your operating system or you need some functionality that’s not compiled into the binaries (for example, a different character set).

If you have trouble starting the MySQL server after installing it, check the error log for useful information. The error log is located in the data directory and has the extension .err.

On Windows

In most cases, when you download and install MySQL, the server is started automatically. If it isn’t or if you need to stop and start it for another reason, you can start it manually using the WinMySQLadmin utility that is installed with MySQL, as I describe in the upcoming section, “Starting the MySQL server.” You can also use WinMySQLadmin to set up MySQL so that it starts every time your computer starts.

Downloading and installing MySQL

To install MySQL on Windows, follow these steps:

1. Point your Web browser to www.mysql.com, the MySQL home page.

2. Click the Production version number link.

Look for the section under the heading Database Server. As of this writ­
ing, the production release is 4.0.17.

MySQL 4.0.x is supported by PHP 4 or 5. Support for MySQL 4.1.x is pro­
vided beginning with PHP 5.

3. Scroll down the screen until you come to the Windows Downloads heading.

4. Click the download link for the Windows binary labeled Windows 95/
98/NT/2000/XP/2003. This binary includes an installer. A dialog box opens.
5. Select the option to save the file.

A dialog box opens that lets you select where you want the file saved.

6. Navigate to where you want to save the file (for example,
c:\downloads). Then click Save.

After the download, you see a Zip file in the download location (for example, c:\downloads) containing the MySQL files. The file is named mysql-, followed by the version number and -win.zip — for instance, mysql-4.0.17-win.zip.

7. Use your favorite Zip utility to unzip the files and save them in a tem­
porary location (for example, c:\downloads\mysql).

Two popular Zip utilities are PKZIP at www.pkware.com and WinZip at
www.winzip.com.

8. Navigate to the temporary directory where the unzipped files are stored. Then double-click setup.exe.

Note: If you’re installing from a Windows NT/2000/XP system, be sure that you’re logged into an account with administrative privileges.

The opening screen shown in Figure A-1 is displayed.

9. Click Next.

The license is displayed.

10. Click the I Agree button to continue.

You see a screen showing the directory where MySQL will be installed.

11. If you want to install MySQL in the default directory, c:\mysql, click Next. If you want to install MySQL in a different directory, click Browse, select a directory, and click OK; then click Next.

You see a screen in which you can choose the type of installation.

12. Select Typical and then click Next.

The installation of MySQL begins. A message appears when the installa­
tion is complete.

The server might or might not have been started during installation. If it is running, you should see a traffic signal in your system tray (bottom of your screen) with a green light showing. If it isn’t running, check out the next section.

Starting the MySQL server

You can start and stop your server manually, although you’re more likely to want the MySQL server to be running whenever your computer is running. To see how to set up MySQL so that it starts when the computer boots up, see the next section.

On Windows 98/Me
You can start and stop your server with WinMySQLadmin, a program that was installed with MySQL. The WinMySQLadmin program is responsible for displaying the traffic signal in your system tray. If the traffic signal is displayed, WinMySQL is running. If the traffic signal is not in your tray, you need to start WinMySQLadmin.

If WinMySQLadmin is not running, you might be able to start it from your Startup menu: Choose Start➪Programs➪Startup➪WinMySQLadmin. If you can’t find it on your Startup menu, use Windows Explorer to navigate to the bin directory in the directory where MySQL is installed (for example, c:\ mysql\bin) and double-click WinMySQLadmin. When it’s started, you should be able to see the traffic signal in your system tray.

To start or stop the MySQL server by using WinMySQLadmin, follow these steps:

1. Right-click the traffic signal in your system tray.

You see a short menu.

2. Select your operating system: Windows 9x.

3. To start or stop, click either Start the Server or Stop the Server.

4. Exit WinMySQLadmin by right-clicking in the WinMySQLadmin
window and then clicking Hide Me.

On Windows NT/2000/XP
You can start your MySQL server directly by navigating to the bin subdirec­ tory in the directory where MySQL is installed (such as c:\mysql\bin) and then double-clicking the file mysqld.exe.

The above procedure might not work if the WinMySQLadmin program isn’t running (if there is no traffic signal on your system tray). In this case, you can either start the WinMySQL program by double-clicking it or start the MySQL server with a DOS Window console. If you are having problems, it is often useful to start the server with a console because some helpful error mes­ sages will be displayed.

To start the MySQL server with a console, follow these steps:

1. Open a command prompt window.
For instance, choose Start➪Programs➪Accessories➪Command Prompt.

2. Change to the bin directory for MySQL.

For instance, CD c:\mysql\bin.

3. Type mysqld —console.

A message is displayed telling you that the server started. The window remains open and ready to receive any more messages from the server. Don’t close the window.

You might be able to stop the server using WinMySQLadmin if it is running
by right clicking the traffic signal, selecting Win NT from the menu displayed, and then clicking Stop the Server. If this doesn’t work, you can use the follow­ ing steps:

1. Open a command prompt window.
For instance, choose Start➪Programs➪Accessories➪Command Prompt.

2. Change to the bin directory for MySQL.

For instance, CD c:\mysql\bin.

3. Type mysqladmin -u root –p shutdown.

The -u is followed by an account name — in this case, root, which was installed when MySQL was installed. If you use the -p, you will be prompted for a password. Unless you installed a password, you shouldn’t need one, so leave out the -p.

Setting up the server to start when the computer starts

In most cases, you want to set up your MySQL server so that it is running whenever your computer is running.

On Windows 98/Me
If you want to set up your MySQL server so that it starts every time your computer starts, start WinMySQLadmin as I describe in the previous section and then follow these steps:

1. Click the my.ini Setup tab.

2. Click Create ShortCut on Start Menu in the bottom-left corner of the screen.

3. Exit WinMySQLadmin by right-clicking in the WinMySQLadmin
window and then choosing Hide Me.

On Windows NT/2000/XP
To set up the MySQL server so that it starts every time the computer boots, set it up as a service. The installation procedure might have set it up as a ser­ vice. You can check whether MySQL is a service as follows:

1. Open the services window at Start➪Settings➪Control Panel➪
Administrative Tools->Services.

A window showing a list of all the services opens.

2. Scroll down the list to see whether MySQL is listed.

If it is not, it is not set up as a service. See how to set it up as a service later in this section.

3. Select the Startup Type.

It should say Automatic. If it doesn’t, do the following:

1. Right click the entry for MySQL.

2. Choose Properties from the menu that is displayed.

3. Select Automatic from the Startup Type drop-down list in the middle of the window.

4. Click OK.

If MySQL was not shown in the list of services, you can set it up as a service as follows:

1. Open a command prompt window.
For instance, choose Start➪Programs➪Accessories➪Command Prompt.

2. Change to the bin directory for MySQL.

For instance, CD c:\mysql\bin.

3. Type mysqld —install.

A message is displayed telling you the service was successfully installed.

If you need to remove the MySQL server from the services list, such as when you are about to upgrade to a newer version, follow the steps 1 and 2 above. For step 3, type mysqld —remove.

On Linux/Unix

Using RPM (Linux only)

MySQL can be installed on Linux using RPM. Although RPM stands for Red Hat Package Manager, RPM is available on most flavors of Linux, not just Red Hat. Using RPM is the easiest way to install on Linux. If installing from an RPM file doesn’t work for you, try using a ready-to-install package called a binary, which is also easy to install; for installation instructions, see the section,

“From binary files.” If neither of these methods works for you, you can always install MySQL from source files. To do this, follow the instructions in the sec­ tion, “From source files.”

You can download the RPM file using the following instructions. However, the RPM file might already be on the CD that your Linux operating system came on. Installing the RPM file from a CD saves you the trouble of downloading (you can skip Steps 1–9 in the following list), but if the version of MySQL on your CD is not the most recent, you might want to download an RPM file anyway.

To install MySQL on Linux from an RPM file, follow these steps:

1. Point your Web browser to www.mysql.com, the MySQL home page.

2. Click the Production version number link.

Look in the list on the right side of the screen, labeled MySQL Products. Look for the section under the heading Database Server. As of this writ­ ing, the production release is 4.0.17.

3. Scroll down the screen until you come to the Linux x86 RPM Downloads heading.

This section lists several downloads for Linux.

4. Click the download link for the standard server. This should be the first entry.

A dialog box opens.

5. Select the option to save the file.

A box opens that lets you select where you want to save the file.

6. Navigate to where you want to save the RPM (for example, /usr/src/
mysql). Then click Save.

7. Repeat Steps 5–7 to download the RPM file for Client Programs into the same download location.

8. Change to the directory where you saved the download.

For instance, type cd /usr/src/mysql. You see two files in the directory — one file named MySQL-server-, followed by the version number and .i386.rpm, and a second file named similarly with client embedded in its name. For example: MySQL-4.0.15-0.i386.rpm and MySQL-client-4.0.15-0.i386.rpm.

9. Install the RPM by entering this command:

rpm -i listofpackages

For instance, using the example in Step 10, the command would be this:

rpm -i MySQL-server-4.0.17-0.i386.rpm MySQL-client-
4.0.17-0.i386.rpm

This command installs the MySQL packages. It sets the MySQL account and group name that you need, and creates the data directory at /var/ lib/mysql. It also starts the MySQL server and creates the appropriate entries in /etc/rc.d so that MySQL starts automatically whenever your computer starts.

You need to be using an account that has permissions to successfully run the rpm command, such as a root account.

10. To test that MySQL is running okay, type this:

bin/mysqladmin --version

You should see the version number of your MySQL server.

From binary files

Ready-to-use, compiled binary files are available for several flavors of Linux and Unix. If none of the flavors work for your Linux/Unix machine, you can install MySQL from source files, but it’s better to use a binary if at all possi­ ble. As of this writing, MySQL binary files were available for the following fla­ vors of Unix, but more could be made available at any time:

Solaris

HP-UX

AIX

SCO

SGI Irix

Dec OSF

QNX

BSDi

OpenBSD

FreeBSD

To install a binary file version of MySQL on Linux or Unix, follow these steps:

1. Point your Web browser to www.mysql.com, the MySQL home page.

2. Click the Production version number link.

Look in the list on the right side of the screen, labeled MySQL Products. Look for the section under the heading Database Server. As of this writ­ ing, the production release is 4.0.17.

3. Scroll down the screen until you come to the heading for Linux or for your version of Unix (for example, Solaris Downloads).

Each section lists several downloads for that operating system.

4. Locate the correct package for your version of operating system.

For Linux, you probably want the Intel libc6 binary version. For Unix, select the correct version of the Unix system — for example, Solaris 9 (SPARC, 64-bit).

5. Click the download link for the standard version for your operating system.

A dialog box opens.

6. Select the option to save the file.

A box opens that lets you select where you want to save the file.

7. Navigate to where you want to install MySQL. Then click Save.

The standard location is /usr/local; it’s best to use this location if possible.

8. After the download is complete, change to the download directory —
for instance, cd-/usr/local.

You see a file named mysql-, followed by the version number, the name of the operating system, and .tar.gz — for instance, mysql-4.0.17- sun-solaris2.9-sparc.64bit-tar.gz. This file is a tarball.

9. Create a user and group ID for MySQL to run under by using these commands:

groupadd mysql
useradd -g mysql mysql

The syntax for the commands might differ slightly on different versions of Unix, or they might be called adduser and addgroup.

Note: You must be using an account that is authorized to add users and groups.

10. Unpack the tarball by typing this:

gunzip -c filename | tar -xvf –

For example:

gunzip -c mysql-4.0.17-sun-solaris2.9-sparc-64bit.tar.gz | tar -xvf –

Note: You must be using an account that is allowed to create files in
/usr/local.

11. Create a link to the new directory so that you can refer to it by a shorter name, rather than its current, difficult-to-type name. Type the following:

ln -s newdirectoryname mysql

For example:

ln -s mysql-4.0.17-sun-solaris2.9-sparc-64bit mysql

Now you can refer to the directory as mysql, instead of by its long name.

12. Change to the new directory by typing cd mysql.

You should see several subdirectories, including /bin and /scripts.

13. Add the path to the bin directory (for example, /usr/local/mysql/ bin) to your system path so that the MySQL programs can be accessed by any programs that need to access MySQL.

You should do this by editing the file that sets the system variables when your computer starts up.

14. Type the following:

scripts/mysql_install_db

This command runs a script that initializes your MySQL databases.

15. Make sure that the ownership and group membership of your MySQL
directories are correct. Set the ownership with these commands:

chown -R root /usr/local/mysql
chown -R mysql /usr/local/mysql/data chgrp -R mysql /usr/local/mysql

These commands make root the owner of all the MySQL directories except data and make mysql the owner of data. All MySQL directories belong to group mysql.

16. Set up your computer so that MySQL starts automatically when your machine starts by copying the file mysql.server from /usr/local/ mysql/support-files to the location where your system has its startup files.

17. To test MySQL, you can start your server manually, without restarting your computer, by typing the following:

bin/safe_mysqld --user=mysql &

18. To test that MySQL is running okay, type

bin/mysqladmin --version

You should see the version number of your MySQL server.

From source files

Before you decide to install MySQL from source files, check for binary files for your operating system. MySQL binary files are precompiled, ready-to-install packages for installing MySQL. MySQL binary files are very convenient and reliable.

You install MySQL by downloading source files, compiling the source files, and installing the compiled programs. This process sounds terribly technical and daunting, but it’s not. Read all the way through the following steps before you begin the installation procedure.

To install MySQL from source code, follow these steps:

1. Point your Web browser to www.mysql.com, the MySQL home page.

2. Click the Production version number link.

Look in the list on the right side of the screen, labeled MySQL Products. Look for the section under the Database Server heading. As of this writ­ ing, the production release is 4.0.17.

3. Scroll to the bottom of the screen to the Source Downloads heading.

This section lists several downloads.

4. Locate the tarball version and click the download link next to it.

A dialog box opens.

5. Select the option to save the file.

A box opens that lets you select where the file will be saved.

6. Navigate to where you want to install MySQL and then click Save.

The standard location is /usr/local. It is best to use the standard loca­
tion if possible.

7. After the download is complete, change to the download directory —
for instance, cd-/usr/local.

You see a file named mysql-, followed by the version number and
.tar.gz. — for instance, mysql-4.0.17.tar.gz. This file is a tarball.

8. Create a user and group ID for MySQL to run under by using the fol­
lowing commands:

groupadd mysql
useradd -g mysql mysql

The syntax for the commands might differ slightly on different versions of Unix, or they might be called adduser and addgroup.

Note: You must be using an account that is authorized to add users and groups.

9. Unpack the tarball by typing

gunzip -c filename | tar -xvf –

For example:

gunzip -c mysql-3.23.44.tar.gz | tar -xvf –

You see a new directory named mysql-version — for instance,
mysql-4.0.15.

You must be using an account that is allowed to create files in
/usr/local.

10. Change to the new directory.

For instance, type cd mysql-4.0.17.

11. Type the following:

./configure --prefix=/usr/local/mysql

You see several lines of output. The output will tell you when configure is done. This might take some time.

12. Type make.

You see many lines of output. The output will tell you when make is done. make might run for some time.

13. Type make install.

make install will finish quickly.

Note: You might need to run this command as root.

14. Type the following:

scripts/mysql_install_db.

This command runs a script that initializes your MySQL databases.

15. Make sure that the ownership and group membership of your MySQL
directories are correct. Set the ownership with these commands:

chown -R root /usr/local/mysql
chown -R mysql /usr/local/mysql/data chgrp -R mysql /usr/local/mysql

These commands make root the owner of all the MySQL directories except data and make mysql the owner of data. All MySQL directories belong to group mysql.

16. Set up your computer so that MySQL starts automatically when your machine starts by copying the file mysql.server from /usr/local/ mysql/support-files to the location where your system has its startup files.

17. To test MySQL, you can start your server manually, without restarting your computer, by typing the following:

bin/safe_mysqld --user=mysql &

18. To test that MySQL is running okay, type:

bin/mysqladmin --version

You should see the version number of your MySQL server.

On Mac

You can download MySQL using a Mac OS X 10.2 (Jaguar) PKG binary package. If your operating system is OS X 10.1 or earlier, you can’t use this package.
You will need to download a tarball and install MySQL from source code, as described in the previous section.

1. Point your Web browser to www.mysql.com, the MySQL home page.

2. Click the Production version number link.

Look in the list on the right side of the screen, labeled MySQL Products. Look for the section under the heading Database Server. As of this writ­ ing, the production release is 4.0.17.

3. Scroll down the screen to find the section with the heading Mac OS Package Installer Downloads.

This section lists several downloads.

4. Locate the standard version and then click the download link next to it.

A dialog box opens.

5. Select the option to save the file.

A box opens that lets you select where the file will be saved.

6. Navigate to where you want to install MySQL and then click Save.

The standard location is /usr/local. It is best to use the standard loca­
tion if possible.

7. After the download is complete, change to the download director —
for instance, /usr/local.

You see a package named mysql-standard, followed by the version number and dmg, such as mysql-standard-4.0.17.dmg. If the down­ loaded file does not have the extension .dmg, change the filename to give it the .dmg extension.

8. Create a user and a group named mysql for MySQL to run under. In
most newer Mac versions, this user and group already exist.

9. Mount the disk image by double-clicking its icon in the Finder.

10. Double-click the package icon to install the MySQL PKG.

The package installer will run and install the package. It installs MySQL
in the directory /usr/local/mysql-, followed by the version number. It also installs a symbolic link /usr/local/mysql/ pointing to the direc­ tory where MySQL is installed. It also initializes the database by running the script mysql_install_db, which creates a MySQL account called root.

11. You might need to change the owner of the mysql directory.

The directory where MySQL is installed (for example, /usr/local/
mysql-4.0.17) should be owned by root. The data directory (such as,
/usr/local/mysql-4.0.17/data) should be owned by the account mysql. Both directories should belong to the group mysql. If the user and group are not correct, change them with the following commands:

sudo chown -R root /usr/local/mysql-4.0.17
sudo chown -R mysql /usr/local/mysql-4.0.17/data sudo chown -R root /usr/local/mysql-4.0.17/bin

12. Start the MySQL server using the following commands:

cd /usr/local/mysql sudo ./bin/mysqld_safe
if necessary, enter your password
Press Ctrl-Z
bg
Press Ctrl-D or type exit

This starts the server manually, meaning you must start the MySQL server every time you restart your computer. To have your server start every time the computer is started, you need to install the MySQL Startup Item, which is included in the installation disk image in a sepa­ rate installation package. To install the Startup Item, double-click the MySQLStartupItem.pkg icon.

To stop the MySQL server, change to the bin subdirectory in the directory where MySQL is installed and type

mysqladmin –u root –p shutdown

The -p causes mysqladmin to prompt you for a password. If the account doesn’t require a password, don’t include -p.

Configuring MySQL

MySQL reads a configuration file when it starts up. If you use the defaults or an installer, you probably don’t need to add anything to the configuration file. However, if you install MySQL in a nonstandard location or want the databases to be stored somewhere other than the default, you might need to edit the configuration file.

The file is named my.ini or my.cnf. It’s located in your system directory (such as WINNT) if you are using Windows and in /etc on Linux/Unix/Mac. The file looks something like the following:

[mysqld] basedir=D:/mysql4 datadir=D:/mysql4/data
#port=3306

The basedir line tells the MySQL server where MySQL is installed. The datadir line tells the server where the databases are located. The # at the beginning of the last line makes the line inactive. You could remove the # and change the port number to tell the server to listen for database queries on a different port.

Ten PHP Gotchas

guarantee that you will do all the things that I mention in this chapter. It’s not possible to write programs without making these mistakes. The trick
is to find out how to recognize them, roll your eyes, say, “Not again,” and then fix them. One error message that you will see many times is

Parse error: parse error in c:\test.php on line 7

This is PHP’s way of saying, “Huh?” It means it doesn’t understand some­ thing. This message helpfully points to the file and the line number where PHP got confused. Sometimes it’s directly pointing at the error, but some­ times PHP’s confusion results from an error earlier in the program.

Missing Semicolons

Every PHP statement ends with a semicolon (;). PHP doesn’t stop reading a statement until it reaches a semicolon. If you leave out the semicolon at the end of a line, PHP continues reading the statement on the following line. For instance, consider the following statement:

$test = 1 echo $test;

Of course, the statement doesn’t make sense to PHP when it reads the two lines as one statement, so it complains with an error message, such as the annoying

Parse error: parse error in c:\test.php on line 2

Before you know it, you’ll be writing your home address with semicolons at the end of each line.

Not Enough Equal Signs

When you ask whether two values are equal in a comparison statement, you need two equal signs (==). Using one equal sign is a common mistake. It’s per­ fectly reasonable because you have been using one equal sign to mean equal since the first grade when you discovered that 2 + 2 = 4. This is a difficult mis­ take to recognize because it doesn’t cause an error message. It just makes your program do odd things, like infinite loops or if blocks that never execute. I’m continually amazed at how long I can stare at

$test = 0;
while ( $test = 0 )
{
$test++;
}

and not see why it’s looping endlessly.

Misspelled Variable Names

This is another PHP gotcha that doesn’t result in an error message, just odd program behavior. If you misspell a variable name, PHP considers it a new variable and does what you ask it to do. Here’s another clever way to write an infinite loop:

$test = 0;
while ( $test == 0 )
{
$Test++;
}

Remember: To PHP, $test is not the same variable as $Test.

Missing Dollar Signs

A missing dollar sign in a variable name is really hard to see, but at least it usually results in an error message so that you know where to look for the problem. It usually results in the old familiar parse error:

Parse error: parse error in test.php on line 7

Troubling Quotes

You can have too many, too few, or the wrong kind of quotes. You have too many when you put quotes inside of quotes, such as

$test = “<table width=”100%”>”;

PHP will see the second double quote (“) — before 100 — as the ending double quote (“) and read the 1 as an instruction, which makes no sense. Voilà! Another parse error. The line must be either

$test = “<table width=’100%’>”;

or

$test = “<table width=\”100%\”>”;

You have too few quotes when you forget to end a quoted string, such as

$test = “<table width=’100%’>;

PHP will continue reading the lines as part of the quoted string until it encoun­
ters another double quote (“), which might not occur for several lines. This is one occasion when the parse error pointing to where PHP got confused is not pointing to the actual error. The actual error occurred some lines previ­ ously, when you forgot to end the string.

You have the wrong kind of quotes when you use a single quote (‘) when you meant a double quote (“) or vice versa. The difference between single and double quotes is sometimes important, and I explain it in Chapter 6.

Invisible Output

Some statements, such as the header statement, must execute before the pro­ gram produces any output. If you try to use such statements after sending output, they fail. The following statements will fail because the header mes­ sage isn’t the first output:

<html>
<?php
header(“Location: http://company.com”);
?>

<html> is not in a PHP section and is therefore sent as HTML output. The fol­
lowing statements will work:

<?php
header(“Location: http://company.com”);
?>
<html>

The following statements will fail:

<?php
header(“Location: http://company.com”);
?>
<html>

because there’s one single blank space before the opening PHP tag. The blank space is output to the browser, although the resulting Web page looks empty. Therefore, the header statement fails because there is output before it. This
is a common mistake and difficult to spot.

Numbered Arrays

PHP believes the first value in an array is numbered zero (0). Of course, humans tend to believe that lists start with the number one (1). This funda­ mentally different way of viewing lists results in us humans believing an array isn’t working correctly when it’s working just fine. For instance, consider the following statements:

$test = 1;
while ( $test <= 3 )
{
$array[] = $test;
$test++;
}
echo $array[3];

Nothing is displayed by these statements. I leap to the conclusion that there’s something wrong with my loop. Actually, it’s fine. It just results in the follow­ ing array:

$array[0]=1
$array[1]=2
$array[2]=3

And doesn’t set anything into $array[3].

Including PHP Statements

When a file is read in using an include statement in a PHP section, it seems reasonable to me that the statements in the file will be treated as PHP state­ ments. After all, PHP adds the statements to the program at the point where I include them. However, PHP doesn’t see it my way. If a file named file1.inc contains the following statements:

if ( $test == 1 )
echo “Hi”;

and I read it in with the following statements in my main program:

<?php
$test = 1;
include (“file1.inc”);
?>

I expect the word Hi to appear on the Web page. However, the Web page actu­
ally displays this:

if ( $test == 1 ) echo “Hi”;

Clearly, the file that is included is seen as HTML. To send Hi to the Web page,
file1.inc needs to contain the following statements:

<?php
if ( $test == 1 )
echo “Hi”;
?>

Missing Mates

Parentheses and curly brackets come in pairs and must be used that way. Opening with a ( that has no closing ) or a { without a } will result in an error message. One of my favorites is using one closing parenthesis where two are needed, as in the following statement:

if ( isset($test)

This statement needs a closing parenthesis at the end. It’s much more diffi­ cult to spot that one of your blocks didn’t get closed when you have blocks inside of blocks inside of blocks. For instance, consider the following.

376 Part V: The Part of Tens

while ( $test < 3 )
{
if ( $test2 != “yes” )
{
if ( $test3 > 4 )
{
echo “go”;
}
}

You can see there are three opening curly brackets and only two closing ones. Imagine that 100 lines of code are inside these blocks. It can be difficult to spot the problem — especially if you think the last closing bracket is closing the while loop, but PHP sees it as closing the if loop for $test2. Somewhere later in your program, PHP might be using a closing bracket to close the while loop that you aren’t even looking at. It can be difficult to trace the problem in a large program.

Indenting blocks makes it easier to see where closing brackets belong. Also, I
often use comments to keep track of where I am, such as

while ( $test < 3 )
{
if ( $test2 != “yes” )
{
if ( $test3 > 4 )
{
echo “go”;
} // closing if block for $test3
} // closing if block for $test2
} // closing while block

Confusing Parentheses and Brackets

I’m not sure whether this is a problem for everyone or just a problem for me because I refuse to admit that I can’t see as well as I used to. Although PHP has no trouble distinguishing between parentheses and curly brackets, my eyes are not so reliable. Especially while staring at a computer screen at the end of a ten-hour programming marathon, I can easily confuse ( and {. Using the wrong one gets you a parse error message.

Ten Things You Might Want to Do Using PHP Functions

ne of the strongest aspects of PHP is its many built-in functions. In this chapter, I list the PHP functions that I use most often. I describe some of
them elsewhere in this book, some I only mention in passing, and some I don’t mention at all. These aren’t all the functions, by any means. There are many hundreds of functions in the PHP language. For a complete list of all the func­ tions, see the PHP documentation at www.php.net.

Communicate with MySQL

PHP has many functions designed specifically for interacting with MySQL. I describe the following MySQL functions thoroughly in this book, particularly in Chapter 8:

mysql_connect(); mysql_select_db(); mysql_fetch_array()
mysql_close(); mysql_num_rows(); mysql_query()

The following functions could be useful, but I either don’t discuss them or discuss them only briefly in earlier chapters:

mysql_insert_id(): For use with an AUTO-INCREMENT MySQL column.
This function gets the last number inserted into the column.

mysql_fetch_row($result): Gets one row from the temporary results location. The row is put into an array with numbers as the keys. It’s the same as mysql_fetch_array($row,MYSQL_NUM).

mysql_affected_rows($result): Returns the number of rows that were affected by a query — for instance, the number of rows deleted or updated.

mysql_num_fields($result): Returns the number of fields in a result.

mysql_field_name($result, N): Returns the name of the row indi­ cated by N. For instance, mysql_field_name($result,1) returns the name of the second column in the result. The first column is 0.

If you use any of the above functions with MySQL 4.1, the function’s names are slightly different. Rather than beginning with mysql_, the function names begin with mysqli_.

Send E-Mail

PHP provides a function that sends e-mail from your PHP program. The format is

mail(address,subject,message,headers);

These are the values that you need to fill in:

address: The e-mail address that will receive the message.

subject: A string that goes on the subject line of the e-mail message.

message: The content that goes inside the e-mail message.

headers: A string that sets values for headers. For instance, you might have a headers string as follows:

“From: member-desk@petstore.com\r\nbcc: mom@hercompany.com”

The header would set the From header to the given e-mail address, plus send a blind copy of the e-mail message to mom.

The following is an example of PHP statements that you can use in your script to set up and send an e-mail message:

$to = “janet@valade.com”;
$subj = “Test”;
$mess = “This is a test of the mail function”;
$headers = bcc:techsupport@mycompany.com\r\n
$mailsend = mail($to,$subj,$mess,$headers);

Sometimes you might have a problem with your e-mail. PHP has a configura­ tion setting that must be correct before the mail function can connect to your system e-mail software. The default is usually correct, but if your e-mail doesn’t seem to be getting to its destination, check the PHP configuration
mail setting by looking for the following in the output of phpinfo():

Sendmail_path (on Unix/Linux) SMTP (on Windows)

It might be set incorrectly. You can change the setting by editing the php.ini
file. Look for the following lines:

[mail function]
; For Win32 only. SMTP = localhost

; For Win32 only.
sendmail_from = me@localhost.com

; For Unix only.
;sendmail_path =

Windows users need to change the first two settings. The first setting is where you put the name of your outgoing mail server. However you send
e-mail — LAN at work, a cable modem at home, an ISP via a modem — you send your mail with an SMTP server, which has an address that you need to know.

If you send directly from your computer, you should be able to find the name of the outgoing mail server that you’re using in your e-mail software. For instance, in Microsoft Outlook Express, choose Tools➪Accounts➪Properties and then select the Servers tab. Look for the name of your outgoing mail server. If you can’t find its name, you can ask your e-mail administrator for the name. If you use an ISP, you can ask the ISP. The name is likely to be in a format similar to the following:

mail.ispname.net

The second setting is the return address that is sent with all your e-mail. Change the setting to the e-mail address that you want to use for your return address, as follows:

sendmail_from = Janet@Valade.com

The third setting is for Unix users. The default is usually correct. If it doesn’t work, you need to talk to your system administrator about the correct path to your outgoing mail server. This usually refers to Linux as well.

Don’t forget to remove the semicolon at the beginning of the lines. The semi­ colon makes the line into a comment, so the setting isn’t active until you remove the semicolon.

Use PHP Sessions

The functions to open or close a session follow. I explain all these functions in Chapter 9.

session_start(); session_destroy()

Stop Your Program

Sometimes you just want your program to stop, cease, and desist. There are two functions for this: exit() and die(). Actually, these are two different names for the same function. Exit is probably accurate, but sometimes it’s just more fun to say die. Both functions will print a message when they stop if you provide one. The format is

exit(“message string”);

When exit executes, the message string is output.

Handle Arrays

Arrays are very useful in PHP, particularly for getting the results from data­ base functions and for form variables. I explain the following array functions elsewhere in the book, mainly in Chapter 7:

array(); extract(); sort(); asort();
rsort(); arsort(); ksort(); krsort();

Here are some other useful functions:

array_reverse($varname): Returns an array with the values in reverse order.

array_unique($varname): Removes duplicate values from an array.

in_array(“string”,$varname): Looks through an array $varname for a string “string”.

range(value1,value2): Creates an array containing all the values between value1 and value2. For instance, range(‘a’,’z’) creates an array containing all the letters between a and z.

explode(“sep”,”string”): Creates an array of strings in which each item is a substring of string, separated sep. For example, explode(“ “,$string) creates an array in which each word in
$string is a separate value. This is similar to the split function in Perl.

implode(“glue”,$array): Creates a string containing all the values in
$array with glue between them. For instance, implode(“, “,$array) creates a string: value1, value2, value3, and so on. This is similar to the join function in Perl.

And there are many more useful array functions. PHP can do almost anything you can think of that you want to do with an array.

Check for Variables

Sometimes you just need to know whether a variable exists. The following functions can be used to test whether a variable is currently set:

isset($varname); // true if variable is set
!isset($varname); // true if variable is not set empty($varname); // true if value is 0 or is not set

Format Values

Sometimes you need to format the values in variables. In Chapter 6, I explain how to format numbers into dollar format by using number_format() and sprintf(). In Chapter 6, I also discuss unset(), which removes the values from a variable. In this section, I describe additional capabilities of sprintf().

The function sprintf() allows you to format any string or number, including variable values. The general format is

$newvar = sprintf(“format”,$varname1,$varname2,...);

where format gives instructions for the format and $varname contains the value(s) to be formatted. format can contain both literals and instructions for formatting the values in the $varname. Actually, the format can contain only literals. The following statement is valid:

$newvar = sprintf(“I have a pet”);

This statement outputs the literal string. However, you can also add vari­
ables, using the following statements:

$ndogs = 5;
$ncats = 2;
$newvar = sprintf(“I have %s dogs and %s cats”,$ndogs,$ncats);

The %s is a formatting instruction that tells sprintf to insert the variable value as a string. Thus, the output is I have 5 dogs and 2 cats. The % character signals sprintf that a formatting instruction starts here. The for­ matting instruction has the following format:

%pad-width.dectype

These are the components of the formatting instructions:

%: Signals the start of the formatting instruction.

pad: A padding character that’s used to fill out the number when neces­ sary. If you don’t specify a character, a space is used. pad can be a space, a 0, or any character preceded by a single quote (‘). For instance, it’s common to pad numbers with 0 — for example, 01 or 0001.

-: A symbol meaning to left-justify the characters. If this isn’t included, the characters are right-justified.

width: The number of characters to use for the value. If the value doesn’t fill the width, the padding character is used to pad the value. For instance, if the width is 5, the padding character is 0, and the value is 1, the output is 00001.

.dec: The number of decimal places to use for a number.

type: The type of value. Use s for most values. Use f for numbers that you want to format with decimal places.

Some possible sprintf statements are

sprintf(“I have $%03.2f. Does %s have any?”,$money,$name);
sprintf(“%’.-20s%3.2f”,$product,$price);

The output of these statements is

I have $030.00. Does Tom have any? Kitten.............. 30.00

Compare Strings to Patterns

In earlier chapters in this book, I use regular expressions as patterns to match strings. (I explain regular expressions in Chapter 6.) The following functions use regular expressions to find and sometimes replace patterns in strings:

ereg(“pattern”,$varname): Checks whether the pattern is found in
$varname. eregi is the same function except that it ignores upper- and lowercase.

ereg_replace(“pattern”,”string”,$varname): Searches for the pattern in $varname and replaces it with the string. eregi_replace is the same function except that it ignores upper- and lowercase.

Find Out about Strings

Sometimes you need to know things about a string, such as how long it is or whether the first character is an uppercase O. PHP offers many functions for checking out your strings:

strlen($varname): Returns the length of the string.

strpos(“string”,”substring”): Returns the position in string where substring begins. For instance, strpos(“hello”,”el”) returns 1. Remember that the first position for PHP is 0. strrpos() finds the last position in string where substring begins.

substr(“string”,n1,n2): Returns the substring from string that begins at n1 and is n2 characters long. For instance, substr(“hello”,2,2) returns ll.

strtr($varname,”str1”,”str2”): Searches through the string
$varname for str1 and replaces it with str2 every place that it’s found.

strrev($varname): Returns the string with the characters reversed.

Many, many more string functions exist. See the documentation at
www.php.net.

Change the Case of Strings

Changing uppercase letters to lowercase and vice versa is not so easy. Bless
PHP for providing functions to do this for you:

strtolower($varname): Changes any uppercase letters in the string to lowercase letters

strtoupper($varname): Changes any lowercase letters in the string to uppercase letters

ucfirst($varname): Changes the first letter in the string to uppercase

ucwords($varname): Changes the first letter of each word in the string to uppercase

Building a Members Only Web Site

any Web sites require users to log in. Sometimes users can’t view any
Web pages without entering a password, while sometimes just part of the Web page requires a login. Here are some reasons why you might want to require a user login:

The information is secret. You don’t want anyone except a few autho­ rized people to see the information. Or perhaps only your own employ­ ees should see the information.

The information or service is for sale. The information or service that your Web site provides is your product, and you want to charge people for it. For instance, you might have a corner on some survey data that researchers are willing to pay for. For example, AAA Automobile Club offers some of its information for free, but you have to be a member to see its hotel ratings.

You can provide better service. If you know who your customers are or have some of their information, you can make their interaction with your Web site easier. For instance, if you have an account with Barnes and Noble.com or the Gap and log into their site, they use your stored ship­ ping address, and you don’t have to type it in again.

You can find out more about your customers. Marketing would like to know who is looking at your Web site. A list of customers with addresses and phone numbers and perhaps some likes and dislikes is a useful thing. If your Web site offers some attractive features, customers may be will­ ing to provide some information in order to access your site. For instance, a person might be willing to answer some questions in order to down­ load some free software or to play a great online game.

Typically, a login requires the user to enter a user ID and a password. Often, users can create their own accounts on the Web site, choosing their own user ID and password. Sometimes users can maintain their accounts — for exam­ ple, change their password or phone number — online.

In Chapter 11, you find out how to build an online catalog for your Pet Store Web site. Now, you want to add a section to your Web site that’s for Members Only. You plan to offer special discounts, a newsletter, a database of pet infor­ mation, and more in the Members Only section. You hope that customers will see the section as so valuable that they’ll be willing to provide their addresses and phone numbers to get a member account that lets them use the services in the restricted section. In this chapter, you build a login section for the Pet Store.

Designing the Application

The first step in design is to decide what the application should do. Its basic function is to gather customer information and store it in a database. It offers customers access to valuable information and services to motivate them to provide information for the database. Because state secrets or credit card numbers aren’t at risk, you should make it as easy as possible for customers to set up and access their accounts.

The application that provides access to the Members Only section of the Pet
Store should do the following:

Provide a means for customers to set up their own accounts with member IDs and passwords. This includes collecting the information from the customer that’s required to become a member.

Provide a page where customers type their member ID and password and then check whether they are valid. If so, the customer enters the Members Only section. If not, the customer can try another login.

Show the pages in the Members Only section to anyone who is logged in.

Refuse to show the pages in the Members Only section to anyone who is not logged in.

Keep track of member logins. You want to know who logs in and how often.

Building the Database

The database is the core and purpose of this application. It holds the cus­ tomer information that’s the goal of the Members Only section. It also holds the Member ID and password so that the user can log into the Members Only section.

The Members Only application database contains two tables:

Member table

Login table

The first step in building the login application is to build the database. It’s pretty much impossible to write programs without a working database to test the programs on. First design your database; then build it; then add some sample data for use while developing the programs.

Some changes have been made to the database design that I develop in Chapter 3 for the Members Only restricted section of the Pet Store Web site. Development and testing often result in changes. Perhaps you find that you didn’t take some factors into consideration in your design or that certain ele­ ments of your design don’t work with real-world data or are difficult to pro­ gram. It’s perfectly normal for the design to evolve while you work on your application. Just be sure to change your documentation when your design changes.

Building the Member table

In your design for the login application, the main table is the Member table.
It holds all the information entered by the customer, including the customer’s personal information (name, address, phone number, and so on) and the Member ID and password. The following SQL query creates the Member table:

CREATE TABLE Member (
loginName VARCHAR(20) NOT NULL, createDate DATE NOT NULL, password VARCHAR(255) NOT NULL, lastName VARCHAR(50),
firstName VARCHAR(40), street VARCHAR(50), city VARCHAR(50), state CHAR(2),
zip CHAR(10), email VARCHAR(50), phone CHAR(15),
fax CHAR(15), PRIMARY KEY(loginName) );

Each row represents a member. The columns are

loginName: A Member ID for the member to use when logging in. The customer chooses and types in the login name. The CREATE query defines the loginName in the following ways:

• CHAR(20): This data type defines the field as a character string that’s 20 characters long. The field will always take up 20 charac­ ters of storage, with padding if the actual string stored is less than
20 characters. If a string longer than 20 characters is stored, any characters after 20 are dropped.

• PRIMARY KEY(loginName): The primary key identifies the row and must be unique. MySQL will not allow two rows to be entered with the same loginName.

• NOT NULL: This definition means that this field can’t be empty. It must have a value. The primary key must always be set to NOT NULL.

createDate: The date when the row was added to the database — that is, the date when the customer created the account. The query defines createDate as

• DATE: This is a string that’s treated as a date. Dates are displayed in the format YYYY-MM-DD. They can be entered in that format or some similar formats, such as YY/M/D or YYYYMMDD.

• NOT NULL: This definition means that this field can’t be empty. It must have a value. Because the program, not the user, creates the date and stores it, it won’t ever be blank.

password: A password for the member to use when logging in. The cus­ tomer chooses and types in the password. The CREATE query defines the password in the following ways:

• VARCHAR(255): This statement defines the field as a variable char­ acter string that can be up to 255 characters long. The field is stored in its actual length. You don’t expect the password to be 255 char­ acters long. In fact, you expect it to be pretty short. However, you intend to use the MySQL password function to encrypt it rather than store it in plain view. After it’s encrypted, the string will be longer, so you’re allowing room for the longer string.

• NOT NULL: This statement means that this field can’t be empty. It must have a value. You’re not going to allow an empty password in this application.

lastName: The customer’s last name, as typed by the customer. The
CREATE query defines the field as

• VARCHAR(50): This data type defines the field as a variable charac­
ter string that can be up to 50 characters long. The field is stored in its actual length.

firstName: The customer’s first name, as typed by the customer. The
CREATE query defines the field as

• VARCHAR(40): This data type defines the field as a variable charac­
ter string that can be up to 40 characters long. The field is stored in its actual length.

street: The customer’s street address, as typed by the customer. The
CREATE query defines the field as

• VARCHAR(50): This data type defines the field as a variable charac­
ter string that can be up to 50 characters long. The field is stored in its actual length.

city: The city in the customer’s address, as typed by the customer. The
CREATE query defines the field as

• VARCHAR(50): This data type defines the field as a variable charac­
ter string that can be up to 50 characters long. The field is stored in its actual length.

state: The state in the customer’s address. The string is the two-letter state code. The customer selects the data from a drop-down list contain­ ing all the states. The CREATE query defines the field as

• CHAR(2): This data type defines the field as a character string that’s two characters long. The field will always take up two char­ acters of storage, with padding if the actual string stored is less than two characters.

zip: The ZIP code that the customer types in. The CREATE query defines the field as

• CHAR(10): This data type defines the field as a character string that’s ten characters long. The field will always take up ten charac­ ters of storage, with padding if the actual string stored is less than ten characters. The field is long enough to hold a ZIP+4 code, such as 12345–1234.

email: The e-mail address that the customer types in. The CREATE query defines the field as

• VARCHAR(50): This data type defines the field as a variable charac­
ter string that can be up to 50 characters long. The field is stored in its actual length.

phone: The phone number that the customer types in. The CREATE
query defines the field as

• CHAR(15): This data type defines the field as a character string that’s 15 characters long. The field will always take up 15 charac­ ters of storage, with padding if the actual string stored is less than
15 characters.

fax: The fax number that the customer types in. The CREATE query defines the field as

• CHAR(15): This data type defines the field as a character string that’s 15 characters long. The field will always take up 15 charac­ ters of storage, with padding if the actual string stored is less than
15 characters.

Notice that some fields are CHAR and some are VARCHAR. CHAR fields are faster, whereas VARCHAR fields are more efficient in using disk space. Your decision will depend on whether disk space or speed is more important for your application in your environment.

In general, shorter fields should be CHAR because shorter fields don’t waste much space. For instance, if your CHAR is 5 characters, the most space that could possibly be wasted is 4 characters. However, if your CHAR is 200, you could waste 199 characters. Therefore, for short fields, use CHAR for speed with very little wasted space.

Building the Login table

The Login table keeps track of member logins by recording the date and time every time that a member logs in. Because each member has multiple logins, the login data requires its own table. The CREATE query that builds the Login table is

CREATE TABLE Login (
loginName VARCHAR(20) NOT NULL, loginTime DATETIME NOT NULL,
PRIMARY KEY(loginName,loginTime) );

The Login table has only two columns, as follows:

loginName: The Member ID that the customer uses to log in with. The loginName is the connection between the Member table (which I describe in the preceding section) and this table. Notice that the loginName column is defined the same in the Member table and in this table. This makes table joining possible and makes matching rows in the tables much easier. The CREATE query defines the loginName in the following ways:

• CHAR(20): This data type defines the field as a character string that’s 20 characters long. The field will always take up 20 charac­ ters of storage, with padding if the actual string stored is less than
20 characters. If a string longer than 20 characters is stored, any characters after 20 are dropped.

• PRIMARY KEY(loginName,loginTime): The primary key identifies the row and must be unique. For this table, two columns together are the primary key. MySQL will not allow two rows to be entered with the same loginName and loginDate.

• NOT NULL: This definition means that this field can’t be empty. It must have a value. The primary key must always be set to NOT NULL.

loginTime: The date and time when the member logged in. This field uses both the date and time because it needs to be unique. It’s very unlikely that two users would log in at the same second at the Pet Store Web site. However, in some very busy Web sites, two users might log in during the same second. At such a site, you might have to create a sequential login number to be the unique primary key for the site. The CREATE query defines the loginTime in the following ways:

• DATETIME: This is a string that’s treated as a date and time. The string is displayed in the format YYYY-MM-DD HH:MM:SS.

• PRIMARY KEY(loginName,loginTime): The primary key identifies the row and must be unique. For this table, two columns together are the primary key. MySQL will not allow two rows to be entered with the same loginName and loginDate.

• NOT NULL: This definition means that this field can’t be empty. It must have a value. The primary key must always be set to NOT NULL.

Adding data to the database

This database is intended to hold data entered by customers — not by you. It will be empty when the application is first made available to customers
until customers add data. However, to test the programs while you write them, you need to have at least a couple of members in the database. You need a couple of Member IDs and passwords to test the login program. You can add
a couple of fake members for testing purposes — by using an INSERT SQL query — and remove them when you’re ready to go live with your Members Only application.

Designing the Look and Feel

After you know what the application is going to do and what information you want to get from customers and store in the database, you can design the look and feel. The look and feel includes what the user sees and how the user interacts with the application. Your design should be attractive and

easy to use. You can create your design on paper, indicating what the user sees, perhaps with sketches or with written descriptions. You should also show the user interaction components, such as buttons or links, and describe their actions. Include each page of the application in the design.

The Pet Store Members Only application has three pages that are part of the login procedures. In addition, the application includes all the pages that are part of the Members Only section, such as the page that shows the special discounts and the pages that provide discussions of pet care. In this chapter, you only build the pages that are part of the login procedure. You don’t build the pages that are part of the Members Only section, but I do discuss what needs to be included in them to protect them from viewing by non-members.

The login application includes three pages, plus the group of pages that com­
prise the Members Only section, as follows:

Storefront page: The first page that a customer sees. It provides the name of the business and the purpose of the Web site. I introduce a storefront page in Chapter 11, and in this chapter, you modify it to pro­ vide access to the Members Only section.

Login page: Allows the customer to either log in or create a new member account. It shows a form for the customer to fill in to get a new account.

New Member Welcome page: Welcomes the new users by name, letting them know that their accounts have been created. Provides any informa­ tion that they need to know. Provides a button so that users can continue to the Members Only section or return to the main page.

Members Only section: A group of Web pages that contain the content of the Members Only section.

Storefront page

The storefront page is the introductory page for the Pet Store. Because most people know what a pet store is, the page doesn’t need to provide much expla­ nation. Figure 12-1 shows the storefront page. Two customer actions are avail­ able on this page: a link that the customer can click to see the Pet Catalog and a link to the Members Only section.

Login page

The login page allows the customer to log in or create a new member account. It includes the form that customers need to fill out to get a member account. Figure 12-2 shows the login page. This page has two different submit buttons: one to log in with an existing member account and one to create a new member account.

If a customer makes a mistake on the login page, either in the login section or the new member section, the form is displayed again with an error mes­ sage. For instance, suppose that a customer makes an error when typing his e-mail address: He forgot to type the .com at the end of the e-mail address. Figure 12-3 shows the screen that he sees after he submits the form with the mistake in it. Notice the error message printed right above the form.

When members successfully log in with a valid Member ID and password, they go to the first page of the Members Only section. When new members successfully submit a form with information that looks reasonable, they go
to a New Member Welcome page (see the next section). In addition, an e-mail message is sent to the new member with the following contents:

A new Member Account has been setup for you. Your new
Member ID and password are:

gsmith secret

We appreciate your interest in Pet Store at PetStore.com

If you have any questions or problems, send email to webmaster@petstore.com

This e-mail message contains the customer’s password. I think that it’s very helpful to both the customer and the business to provide customers with a hard copy of their password. Customers will forget their password. It seems to be one of the rules. An e-mail message with their password might help them
when they forget it, saving both them and you some trouble. Of course, e-mail messages aren’t necessarily secure, so sending passwords via e-mail isn’t a good idea for some accounts, such as an online bank account. But, for this Pet Store application, with only unauthorized discounts and pet care information at risk, sending the password via e-mail is a reasonable risk.

New Member Welcome page

The New Member Welcome page greets the customer and offers useful infor­ mation. The customer sees that the account has been installed and can then enter the Members Only section immediately. Figure 12-4 shows a welcome page.

Members Only section

One or more Web pages make up the contents of the Members Only section. Whatever the content is, the pages are no different than any other Web pages or PHP programs, except for some PHP statements in the beginning of each file that prevent non-members from viewing the pages.

Writing the Programs

After you know what the pages are going to look like and what they are going to do, you can write the programs. In general, you create a program for each page, although sometimes it makes sense to separate programs into more than one file or to combine programs on a page. (See Chapter 10 for details on how to organize applications.)

As I discuss in Chapter 10, keep the information needed to connect to the database in a separate file and include it in all the programs that need to access the database. Store the file in a secure location, with a misleading name. For this application, the following information is stored in a file named dogs.inc:

<?php
$user=”catalog”;
$host=”localhost”;
$password=””;
$database=”MemberDirectory”;
?>

The member login application has several basic tasks:

1. Show the storefront page. This provides a link to the login page.

2. Show a page where customers can fill in a Member ID and a password to log in.

3. Check the Member ID and the password that the customer types against the Member ID and password stored in the database. If the ID and password are okay, the customer enters the Members Only section. If the ID and/or password are not okay, the customer is returned to the login page.

4. Show a page where customers can fill in the information needed to obtain a member account.

5. Check the information the customer typed in for blank fields or incor­
rect formats. If bad information is found, show the form again so that the customer can correct the information.

6. When good information is entered, add the new member to the
database.

7. Show a welcoming page to the new member.

The tasks are performed in three programs:

PetShopFront.php: Shows the storefront page (task 1).

Login.php: Performs both the login and create new member account tasks (tasks 2–6).

New_member.php: Shows the page that welcomes the new member (task 7).

Writing PetShopFront

The storefront page doesn’t need any PHP statements. It simply displays a Web page with two links — one link to the Pet Catalog and one link to the Members Only section of the Web site. HTML (HyperText Markup Language) statements are sufficient to do this. Listing 12-1 shows the HTML file that describes the storefront page.

Listing 12-1: HTML File for the Storefront Page

<?php
/* Program: PetShopFrontMembers.php
* Desc: Displays opening page for Pet Store.
*/
?>
<html>
<head><title>Pet Store Front Page</title></head>
<body topmargin=”0” leftmargin=”0” marginheight=”0”
marginwidth=”0”>
<table width=”100%” height=”100%” border=”0”
cellspacing=”0” cellpadding=”0”>
<tr>
<td align=”center” valign=”top” height=”30” colspan=”2”>
<img src=”images/awning-top.gif” alt=”awning”>
</td>
</tr>
<tr>
<td align=”center” valign=”top” colspan=”2”>
<img src=”images/Name.gif” alt=”Pet Store”>
</td></tr>

(continued)

344 Part IV: Applications

Listing 12-1 (continued)

<tr>
<td width=”80%” align=”center”>
<p style=”margin-top: 40pt”>
<img src=”images/lizard-front.jpg” alt=”lizard picture”
height=”186” width=”280”>
<p><h2>Looking for a new friend?</h2>
<p>Check out our
<a href=”PetCatalog.php”>Pet Catalog.</a>
<br> We may have just what you’re looking for.
</td>
<td width=”20%” bgcolor=”black”>
<div style=”color: white; link: white”>
<p style=”text-align: center; font-size: 15pt”>
<b>Looking for <br>more?</b></p>
<ul>
<li>special deals?
<li>pet information?
<li>good conversation?
</ul>
<p style=”text-align: center”>Try the
<br><a href=”Login.php”
style=”color: white”>Members Only</a>
<br>section <br>of our store
<p style=”text-align: center”><b>It’s free!</b></p>
</td>
</tr>
</table>
</body></html>

Notice the link to the login PHP program. When the customer clicks the link, the login page appears.

Writing Login

The login page (refer to Figure 12-2) is produced by the program Login.php, as shown in Listing 12-2. The program uses a switch to create two sections: one for the login and one for creating a new account. The program creates a session that’s used in all the Members Only Web pages. The login form itself isn’t included in this program; it’s in a separate file called login_form.inc, which is called into this program, whenever the form is needed, by using include statements.

Listing 12-2: Login Program

<?php
/* Program: Login.php
* Desc: Login program for the Members Only section of the
* pet store. It provides two options: (1) login

* using an existing Login Name and (2) enter a new
* login name. Login Names and passwords are stored
* in a MySQL database.
*/
session_start(); # 9 include(“dogs.inc”); #10 switch (@$_GET[‘do’]) #11
{
case “login”: #13
$connection = mysql_connect($host, $user,$password) #14
or die (“Couldn’t connect to server.”);
$db = mysql_select_db($database, $connection)
or die (“Couldn’t select database.”); #17

$sql = “SELECT loginName FROM Member
WHERE loginName=’$_POST[fusername]’”; #20
$result = mysql_query($sql)
or die(“Couldn’t execute query.”); #22
$num = mysql_num_rows($result); #23
if ($num == 1) // login name was found #24
{
$sql = “SELECT loginName FROM Member
WHERE loginName=’$_POST[fusername]’
AND password=password(‘$_POST[fpassword]’)”;
$result2 = mysql_query($sql)
or die(“Couldn’t execute query 2.”); #30
$num2 = mysql_num_rows($result2);
if ($num2 > 0) // password is correct #32
{
$_SESSION[‘auth’]=”yes”; #34
$logname=$_POST[‘fusername’];
$_SESSION[‘logname’] = $logname; #36
$today = date(“Y-m-d h:m:s”); #37
$sql = “INSERT INTO Login (loginName,loginTime) VALUES (‘$logname’,’$today’)”;
mysql_query($sql) or die(“Can’t execute query.”);
header(“Location: Member_page.php”); #41
}
else // password is not correct #43
{
unset($do); #45
$message=”The Login Name, ‘$_POST[fusername]’ exists, but you have not entered the correct password! Please try
again.<br>”;
include(“login_form.inc”); #49
}
} #51
elseif ($num == 0) // login name not found #52
{

unset($do); #54
$message = “The Login Name you entered does not exist! Please try again.<br>”;
include(“login_form.inc”);
}
break; #59

case “new”: #61
foreach($_POST as $field => $value) #62
{
if ($field != “fax”) #64
{
if ($value == “”) #66
{
unset($_GET[‘do’]);
$message_new = “Required information is missing.
Please try again.”; include(“login_form.inc”); exit();
}
}
if (ereg(“(Name)”,$field)) #75
{
/*if (!ereg(“^[A-Za-z’ -]{1,50}$”,$value))
{
unset($_GET[‘do’]);
$message_new = “$field is not a valid name.
Please try again.”;
include(“login_form.inc”);
exit();
}*/
}
$$field = strip_tags(trim($value)); #86
} // end foreach
if (!ereg(“^[0-9]{5,5}(\-[0-9]{4,4})?$”,$zip)) #88
{
unset($_GET[‘do’]);
$message_new = “$zip is not a valid zip code.
Please try again.”;
include(“login_form.inc”);
exit();
}
if (!ereg(“^[0-9)(xX -]{7,20}$”,$phone)) #96
{
unset($_GET[‘do’]);
$message_new = “$phone is not a valid phone number.
Please try again.”;
include(“login_form.inc”);
exit();
}

if ($fax != “”) #104
{
if (!ereg(“^[0-9)(xX -]{7,20}$”,$fax))
{
unset($_GET[‘do’]);
$message_new = “$fax is not a valid phone number.
Please try again.”;
include(“login_form.inc”);
exit();
}
}
if (!ereg(“^.+@.+\\..+$”,$email)) #115
{
unset($_GET[‘do’]);
$message_new = “$email is not a valid email address.
Please try again.”;
include(“login_form.inc”);
exit();
} #122
/* check to see if login name already exists */
$connection = mysql_connect($host,$user,$password)
or die (“Couldn’t connect to server.”);
$db = mysql_select_db($database, $connection)
or die (“Couldn’t select database.”);
$sql = “SELECT loginName FROM Member
WHERE loginName=’$newname’”;
$result = mysql_query($sql)
or die(“Couldn’t execute query.”);
$num = mysql_numrows($result);
if ($num > 0) #133
{
unset($_GET[‘do’]);
$message_new = “$newname already used. Select another
Member ID.”; include(“login_form.inc”); exit();
}
else #141
{
$today = date(“Y-m-d”); #143
$sql = “INSERT INTO Member (loginName,createDate, password,firstName,lastName,street,city, state,zip,phone,fax,email) VALUES
(‘$newname’,’$today’,password(‘$newpass’),
‘$firstName’, ‘$lastName’,’$street’,’$city’,
‘$state’,’$zip’,’$phone’,’$fax’,’$email’)”;
mysql_query($sql); #150
$_SESSION[‘auth’]=”yes”; #151
$_SESSION[‘logname’] = $newname; #152

(continued)

Listing 12-2 (continued)

/* send email to new member */ #153
$emess = “A new Member Account has been setup. “;
$emess.= “Your new Member ID and password are: “;
$emess.= “\n\n\t$newname\n\t$newpass\n\n”;
$emess.= “We appreciate your interest in Pet Store”;
$emess.= “ at PetStore.com. \n\n”;
$emess.= “If you have any questions or problems,”;
$emess.= “ email webmaster@petstore.com”;
$ehead=”From: member-desk@petstore.com\r\n”; #161
$subj = “Your new Member Account from Pet Store”;
$mailsend=mail(“$email”,”$subj”,”$emess”,”$ehead”);
header(“Location: New_member.php”); #164
}
break; #166

default: #168
include(“login_form.inc”);
}
?>

Some of the lines in Listing 12-2 have line numbers at the ends of the lines. The following list refers to the line numbers in the listing to discuss the pro­ gram and how it works:

9 Starts a session. The session has to be started at the beginning of the program, even though the user hasn’t logged in yet.

10 Reads in the file that sets the variables needed to connect to the data­ base. The program is called dogs.inc, which is a misleading name that seems more secure than calling it mypasswords.inc.

11 Starts a switch statement. The switch statement contains three sections, based on the value that was passed for do, obtained from the built-in array $_GET. The first section runs when the value pair passed for do is login; the second section runs when the value passed for do is new; and the third section is the default that runs if no value was passed for do. The third section just creates the login page and only runs when the cus­ tomer first links to the login page.

13 Starts the case block for the login section — the section that runs when the customer logs in. The login section of the form sends do=login in the URL, which causes this section of the switch statement to run.

14 Lines 14–17 connect to MySQL and select the database.

19 Lines 19–22 look in the database table Member for a row with the login name typed by the customer.

23 Checks to see whether a row was found with a loginName field contain­ ing the Member ID typed by the customer. $num will equal 0 or 1, depend­ ing on whether the row was found.

24 Starts an if block that executes if the Member ID was found. That means that the user submitted a Member ID that is in the database. This block then checks to see whether the password submitted by the user is cor­ rect for the given Member ID. This block is documented in more detail in the following list:

26 Lines 26–28 create a query that looks for a row with both the Member ID and the password submitted by the customer. Notice that the password submitted in the form ($fpassword) is encrypted by using the MySQL function, password(). Passwords in the data­ base are encrypted, so the password that you’re trying to match must also be encrypted, or it won’t match.

29 Lines 29–31 execute the query and check whether a match was found. $num2 equals 1 or 0, depending on whether a row with both the Member ID and the password is found.

32 Starts an if block that executes if the password is correct. This
is a successful login. Lines 32–41 are executed, performing the fol­ lowing tasks: 1) The two session variables, auth and logname, are stored in the SESSION array. 2) $today is created with today’s date and time in the correct format expected by the database table. 3) A row for the login is entered into the Login table. 4) The first page of the Members Only section is sent to the member.

43 Starts an else block that executes if the password is not correct.
This is an unsuccessful login. Lines 45–49 are executed, perform­ ing the following tasks: 1) Unset the form variable $do. This pre­ vents any confusion later. 2) Set the appropriate error message into $message. 3) Show the login page again. The login page will show the error message.

Notice that the loop starting on line 43 lets the user know when they have a real login name but the wrong password. If the security of your data is very important, you may want to write this loop dif­ ferently. Providing that information may be helpful to someone who is trying to break in. The cracker now only needs to find the pass­ word. For more security, just have one condition that gives the same error message whenever either the login name or the pass­ word is incorrect. In this example, I prefer to provide the informa­ tion because it is helpful to the legitimate member (who may not remember whether he or she installed an account at all), and I’m not protecting any vital information.

51 Ends the block that executes when the Member ID is found in the database.

52 Starts an if block that executes when the Member ID is not found in the database. This could actually be an else, instead of an elseif, but I think that it’s clearer to humans with the if condition in the statement. This block unsets the form variable $do, creates the appropriate error message and also shows the login page again, which includes the error message.

59 Ends the case block that executes when the customer submits a Member ID and password to log in. The login block extends from line 13 to this line.

61 Starts the case block that executes when the customer fills out the form to get a new member account. The form sends do=new in the URL, caus­ ing the program to jump to this section of the switch statement.

62 Starts a foreach loop that loops through every field in the new member form. The loop checks for empty required fields and checks the first and last name for acceptable characters. The statements in the loop are docu­ mented in more detail in the following list:

64 Checks whether the field is the fax field. The fax field is not required. The fax field isn’t checked to see whether it is blank because it’s okay for it to be blank.

66 Checks whether the field is blank. If it is, the if block performs the following tasks: 1) Unsets $do. 2) Creates an error message that explains the problem. 3) Shows the login form again, includ­ ing the error message. 4) Stops the program and waits for the user to submit the form again with the field filled in.

75 Checks whether the field is the last name or first name field. If so, it checks the field format for allowed characters. If any characters that are not allowed are found, it performs the following tasks:
1) Unsets $do. 2) Creates an error message that explains the prob­
lem. 3) Shows the login form again, including the error message.
4) Stops the program and waits for the user to submit the form again with the correct format.

86 Trims extra spaces from all the field values after they are checked in line 66 to be sure that they aren’t blank. Removes any HTML tags that are in any of the fields. Creates a variable for each of
the fields in the following way. Suppose in the first loop of the foreach loop, the variable is $ _POST [loginName] = gsmith. The foreach loop sets $key=”loginName” and $value=”gsmith”. Therefore, the statement in line 86 is equivalent to
$loginName=strip_tags(trim(“gsmith”)). The
$$key is $loginName because $key=loginName.

87 Ends the foreach loop.

88 Lines 88–122 are a series of if blocks that check the fields for the cor­ rect format. If any of the fields checked doesn’t have the correct format, the block performs the following tasks: 1) Unsets $do. 2) Creates an error message that explains the problem. 3) Shows the login form again, includ­ ing the error message. 4) Stops the program and waits for the user to submit the form again with the correct format.

124 Lines 124–132 check whether the Member ID submitted by the customer is already a loginName in the database table Member. The loginName must be unique. $num equals 0 or 1, depending on whether the loginName is found in the database.

133 Starts an if block that executes if the loginName is already in the data­ base. The new member cannot be added if the Member ID is not unique. The block performs the following tasks: 1) Unsets $do. 2) Creates an error message that explains the problem. 3) Shows the login form again, including the error message. 4) Stops the program and waits for the user to submit the form again with a different Member ID.

141 Starts an else block if the loginName is not already in the database.
This is a successful application for a member account. The block inserts a new row in the Member table for the new member account and sends
an e-mail message to the customer about the new account. The state­
ments in the block are documented in more detail in the following list:

143 Sets $today to today’s date in the correct format for the
createDate field in the Member table.

144 Creates an INSERT query to add the new member row. Notice that the password is encrypted as password(‘$newpass’) when it is entered. This is a security method so that no one who looks in the database can see the password. If you’re totally sure that no one will see the database that shouldn’t, encryption isn’t really necessary.

150 Executes the INSERT query.

151 In lines 151 and 152, the two session variables, $auth and $logname, are stored in the SESSION array.

154 Lines 154–163 send an e-mail to the new member, verifying the Member ID and password. Notice that the e-mail message is cre­ ated in the variable $emess over several lines. It begins in line 154 and is added to (by using .=) on each line until it finishes on line
160. This is to make it easier for humans to read — not because PHP needs this. Unlike HTML content that ignores extra spaces and line ends, extra spaces and other things have an effect on an
e-mail message. For instance, if I created one long message — with extra spaces to indent it so that I could read it — those spaces would show up in the e-mail. So, I set the message on several lines that I can indent for readability in the program. Line 163 uses the PHP function mail to send the e-mail message. The mail function is documented in Chapter 14.

164 Sends the customer to the New Member page.

165 Ends the else block for a successful new member account application.

166 Ends the case block for the New Member section of the login page.

168 Starts the case block for the default condition. If $do is not set to either “login” or “new”, the program skips to this block. Because both the forms on the login page set $do, this block only executes the first time this program runs — when the user links to it from the storefront page and has not yet submitted either form. This section has only one state­ ment: a statement that displays the login page.

This program shows the login page in many places. This is done with include statements that call the file login_form.inc. This file includes the HTML that produces the login page. The program Login.php does not produce any output at all. All the output is produced by login_form.inc. This type of application organization is discussed in Chapter 10. This is a good example
of the use of include files. Just imagine this program, which is long enough, if the statements in login_form.inc, shown in Listing 12-3, were included in the Login program at each place where login_form is included. Whew, that would be a mess that only a computer could understand.

Listing 12-3: File That Creates the Login Page

<?php
/* File: login_form.inc
* Desc: Displays login page. Page displays two forms--one
* form for entering an existing login name and
* password and another form for the information
* needed to apply for a new account.
*/
include(“functions12.inc”); # 8
?>
<html>
<head><title>Members Only Login</title></head>
<body topmargin=”0” leftmargin=”0” marginheight=”0”
marginwidth=”0”>
<table border=”0” cellpadding=”5” cellspacing=”0”>
<tr><td colspan=”3” bgcolor=”gray” align=”center”>
<font color=”white” size=”+10”>
<b>Members Only Section</b></font></td></tr>

<tr>

<td width=”33%” valign=”top”>
<font size=”+1”><b>Are you a member?</b></font>
<p>
<!-- form for customer login -->
<form action=”Login.php?do=login” method=”POST”>
<table border=”0”>

<?php #25
if (isset($message))
echo “<tr><td colspan=’2’>$message </td></tr>”;
?>

<tr><td align=right><b>Username</b></td>
<td><input type=”text” name=”fusername”
size=”20” maxsize=”20”>
</td></tr>
<tr><td width=”120” align=”right”><b>Password</b>
</td>
<td><input type=”password” name=”fpassword”
size=”20” maxsize=”20”></td></tr>
<tr><td align=”center” colspan=”2”>
<br><input type=”submit” name=”log”
value=”Enter”>

<?php

?>

</td></tr>
</table>
</form>
</td>
<td width=”1” bgcolor=”gray”></td>
<td width=”67%”>
<p><font size=”+1”><b>Not a member yet?</b></font> Get discounts, a newsletter, advance notice of new pets, much more. Fill in the information below and join. It’s easy and free! </b>
<!-- form for new member to fill in -->
<form action=”Login.php?do=new” method=”POST”>
<p>
<table border=”0” width=”100%”>

if (isset($message_new)) #55
echo “<tr><td colspan=’2’><b>$message_new</b>
</td></tr>”;

<tr><td align=”right”><b>Member ID</b></td>
<td><input type=”text” name=”newname” value=”<?php echo @$newname ?>” size=”20” maxlength=”20”></td></tr>
<tr><td align=”right”><b>Password</b></td>
<td><input type=”password” name=”newpass” value=”<?php echo @$newpass ?>” size=”10” maxlength=”8”></td></tr>
<tr><td align=”right”><b>First Name</b></td>
<td><input type=”text” name=”firstName” value=”<?php echo @$firstName ?>” size=”40” maxlength=”40”></td></tr>
<tr><td align=”right”><b>Last Name</b></td>
<td><input type=”text” name=”lastName” value=”<?php echo @$lastName ?>” size=”40” maxlength=”40”></td></tr>
<tr><td align=”right”><b>Street</b></td>
<td><input type=”text” name=”street” value=”<?php echo @$street ?>” size=”55” maxlength=”50”></td></tr>

(continued)

Listing 12-3 (continued)

<tr><td align=”right”><b>City</b></td>
<td><input type=”text” name=”city” value=”<?php echo @$city ?>” size=”40” maxlength=”40”></td></tr>
<tr><td align=”right”><b>State</b></td>
<td><select name=”state”>

<?php

$stateName=getStateName(); #86
$stateCode=getStateCode(); #87
for ($n=1;$n<=50;$n++)
{

$state=$stateName[$n];
$scode=$stateCode[$n];
echo “<option value=’$scode’”;
if ($scode== “AL”)
echo “ selected”;
echo “>$state\n”;
}
?>
</select>
&nbsp;&nbsp;&nbsp;&nbsp;<b>Zip</b>
<input type=”text” name=”zip” value=”<?php echo @$zip ?>” size=”10” maxsize=”10”>
</td></tr>
<tr><td align=right><b>Phone</b></td>
<td><input type=”test” name=”phone” value=”<?php echo @$phone ?>” size=”15” maxlength=”20”>
&nbsp;&nbsp;&nbsp;<b>Fax</b>
<input type=”text” name=”fax” value=”<?php echo @$fax ?>” size=”15” maxlength=”20”></td></tr>
<tr><td align=right><b>Email Address</b></td>
<td><input type=”test” name=”email” value=”<?php echo @$email ?>” size=”55” maxlength=”67”></td></tr>
<tr><td>&nbsp;</td>
<td align=”center”>
<input type=”submit”
value=”Become a Member”></td>
</tr>
</table>
</form>
</td>
</tr>
<tr><td colspan=”3” bgcolor=”gray”>&nbsp;</td></tr>
</table>

<div align=”center”><font size=”-1”>
All comments and suggestions are appreciated. Please
send comments to <a href=”mailto:webmaster@petstore.com”>
webmaster@petstore.com</A> </font></div>
</body></html>

Notice the following points about login_form:

Most of the statements are HTML, with a few small PHP sections here and there.

The two forms that start on lines 23 and 51 set action to the same pro­
gram, but add a different string to the URL — do=login or do=new.

The error messages are shown on the login page by using small PHP sec­ tions. Each form has its section, and the message has different names for the two forms: $message and $message_new. On line 26, the variable
$message is tested. If it has a value, the message is shown but is not if
it has no value. If there was no error in the form, the message was never set, and no message is displayed. A similar statement on line 55 shows error messages for the new member form.

A selection drop-down list (started on line 84) is provided for the cus­ tomer to select the state, guarding against typing errors by the customer. Notice that lines 86 and 87 call functions. These functions are not PHP functions; they’re my functions. The functions are included in the pro­ gram on line 8. The functions make arrays from a list of state names and a list of two-letter state codes. By using functions, you don’t need the two lists of 50 states in the program. The functions can be used repeat­ edly for many programs. The function12.inc file contains the two functions as follows:

<?php
function getStateCode()
{
$stateCode = array(1=> “AL” , “AK” ,
“AZ” ,
...
“WY” );
return $stateCode;
}

function getStateName()
{
$stateName = array(1=> “Alabama”, “Alaska”,
“Arizona”,
...

“Wyoming” );
return $stateName;
}
?>

A for loop then creates 50 options for the select list, using the two state arrays.

After running Login.php, if the user is successful with a login, the first page of the Members Only section is displayed. If the user is successful in obtain­ ing a new user account, the New_member.php program is run.

Writing New_member

The New Member Welcome page greets new members by name and provides information about their accounts. Members then have the choice of entering the Members Only section or returning to the main page. Listing 12-4 shows the program that displays the page that new members see.

Listing 12-4: Program That Welcomes New Members

<?php
/* Program: New_member.php
* Desc: Displays the new member welcome page. Greets member by name and gives user choice to enter
* restricted section or go back to main page.
*/
session_start(); # 7

if (@$_SESSION[‘auth’] != “yes”) # 9
{
header(“Location: Login.php”);
exit();
}
include(“dogs.inc”); #14
$connection = mysql_connect($host,$user,$password)
or die (“Couldn’t connect to server.”); #16
$db = mysql_select_db($database, $connection)
or die (“Couldn’t select database.”); #18
$sql = “SELECT firstName,lastName FROM Member
WHERE loginName=’{$_SESSION[‘logname’]}’”;
$result = mysql_query($sql)
or die(“Couldn’t execute query 1.”);
$row = mysql_fetch_array($result,MYSQL_ASSOC);
extract($row);

echo “<html>
<head><title>New Member Welcome</title></head>
<body>
<h2 align=’center’ style=’margin-top: .7in’>
Welcome $firstName $lastName</h2>\n”; #29
?>
<p>Your new Member Account lets you enter the Members Only section of our web site. You’ll find special discounts and bargains, a huge database of animal facts and stories, advice from experts, advance notification of new pets for sale,
a message board where you can talk to other Members, and much more.
<p>Your new Member ID and password were emailed to you. Store them carefully for future use.<br>
<div align=”center”>
<p style=”margin-top: .5in”><b>Glad you could join us!</b>
<form action=”Member_page.php” method=”POST”>
<input type=”submit”
value=”Enter the Members Only Section”>
</form>
<form action=”PetShopFrontMembers.php” method=”POST”>
<input type=”submit” value=”Go to Pet Store Main Page”>
</form>
</div>
</body></html>

Notice the following points about New_member.php:

A session is started on line 7. This makes the session variables stored in
Login.php available to this program.

The program checks, beginning on line 9, whether the customer is logged in. $auth is set to yes in Login.php when the customer successfully logs in or creates a new account and stored in the $_SESSION array. If
$auth doesn’t equal yes, the customer isn’t logged in. If a customer tries to run the New_member.php program without running the Login. php program first, $_SESSION[auth] won’t equal yes, and the user will be sent to the login page.

The program gets the customer’s first and last name from the database, beginning with the database connection statement on line 15. In line
19/20, the query is created by using $_SESSION[logname] to search for the member’s information. The session variable logname that contains the Member ID was set in the login program.

The PHP section ends on line 30. The remainder of the program is HTML.

The program uses two different forms to provide two different submit buttons. The form statements on lines 41 and 45 start different programs.

The customer controls what happens next. If the customer clicks the button to return to the main page, the PetShopFront.php programs runs. If the cus­ tomer clicks the Members Only Section submit button, the first page of the Members Only section is shown.

Writing the Members Only section

The Web pages in the Members Only section are no different than any other Web pages. You just want to restrict them to members who are logged in. To do this, you start a session and check whether they’re logged in at the top of every page. The statements for the top of each program are

session_start();
if (@$_SESSION[‘auth’] != “yes”)
{
header(“Location: Login.php”);
exit();
}

When session_start executes, PHP checks for an existing session. If one exists, it sets up the session variables. One of the session variables is $auth. When the user logs in, $_SESSION[auth] is set to yes. If $_SESSION[auth] doesn’t equal yes, the user is not logged in, and the program takes the user
to the login page.

Planning for Growth

The original plan for an application usually includes every wonderful thing that the user might want it to do. Realistically, it’s usually important to make the application available to the users as quickly as possible. Consequently, applications usually go public with a subset of the planned functionality. More functionality is added later. That’s why it’s important to write your application with future growth in mind.

Looking at the login application in this chapter, I’m sure you can see many things that could be added to it. Here are some possibilities:

E-mail a forgotten password. Users often forget their passwords. Many login applications have a link that users can click to have their passwords e-mailed to them.

Change the password. Members might want to change their password.
The application could offer a form for password changes.

Update information. Members might move or change their phone number or e-mail address. The application could provide a way for members to change their own information.

Create a member list. You might want to output a nicely formatted list of all the members in the database. This probably isn’t something you want to make available to other members but just for yourself. In some situations, however, you might want to make the list available to all members.

You can easily add any of these abilities to the application. For instance, you can add a button to the login form that reads Forgot my password that e-mails the password to the e-mail address in the database. The button can run the login program with a section for e-mailing the password or run a different program that e-mails the password. In the same manner, you can add buttons for changing the password or updating the customer information. You don’t need to wait until an application has all its bells and whistles to let your cus­ tomers use it. You can write it one step at a time.