Product Overview
Build Your Own Database Driven Website Using PHP & MySQL
Corrections & Typos
Find a mistake not listed here? Contact us to let us know!
Confirmed errors in the June 2006 reprint:
Some of the errors listed here may also apply to the previous edition (see below).
- p.12 code listing 1
The filemysql-stamdard-version-linux-i686.tar.gzshould bemysql-standard-version-linux-i686.tar.gz. - p.20
In the latest version of MySQL for Mac OS X, the/usr/local/mysql/data/folder is no longer accessible; consequently, you can't putmy.cnfthere as described on this page. Instead, put the file in the/etc/folder on your system. Simply follow the steps on this page, but replace the folder name/usr/local/mysql/data/with/etc/in each case. - p.90
In the first code listing, the SQL query mentions the table namejokes. This should bejoke. - p.105 code listing
Second<html>doesn't belong there. - p.208 code listing 1
name="uploadedfile"should bename="upload"for consistency. - p.208 paragraph 5
$_FILE['upload']['name']should be$_FILES['upload']['name'].
Confirmed errors in the May 2005 reprint:
Some of the errors listed here may also apply to the previous edition (see below).
- p.26 paragraph 4
You can actually use TextPad if you want to, but you'll have to make sure to type Cmd-Shift-T to convert each file to plain text before saving it in order to avoid having it saved in rich text format. - p.66 code listing 2
For the script to operate as expected, the line<?php if (!isset($_GET['name'])): ?>
should be written<?php if (!isset($_GET['name']) or $_GET['name'] == ''): ?>
This allows for the case where the user might submit the form with an empty name field. In this case, the form will be redisplayed. - p.73 code listing 1
JokeText should be joketext and Jokes should be joke. - p.82 code listing
For security reasons, $jokeid should have quotes around it in the DELETE query in this script:$sql = "DELETE FROM joke WHERE id='$jokeid'";
Confirmed errors in the February 2005 reprint:
Some of the errors listed here may also apply to the previous edition (see below).
- p.2 paragraph 4
The current recommended version of MySQL is now 4.1. - p.2-3
For MySQL 4.1 or later, the my.cnf file is required to ensure your MySQL installation is compatible with PHP. In addition to specifying the basedir and datadir values, you must also set the old-passwords option, which will instruct MySQL to use PHP-compatible passwords:[mysqld] basedir = ... datadir = ... old-passwords
- p.14 paragraph 2
The current recommended version of MySQL is now 4.1. - p.15 command listing 2
For MySQL 4.1 or later, when starting MySQL from the command line, you must specify the --old-passwords option, which will instruct MySQL to use PHP-compatible passwords:shell#bin/mysqld_safe --user=mysql --old-passwords &
- p.16 paragraph 2
For MySQL 4.1 or later, you must add the old-passwords option to your my.cnf file to ensure your MySQL installation is compatible with PHP. This will instruct MySQL to use PHP-compatible passwords:[mysqld] user=mysql old-passwords
- p.21 command listing 1
For MySQL 4.1 or later, when starting MySQL from the command line, you must specify the --old-passwords option, which will instruct MySQL to use PHP-compatible passwords:shell%sudo /usr/local/mysql/bin/mysqld_safe --old-passwords
- p.21
For MySQL 4.1 or later, if you install the MySQLStartupItem.pkg package to make MySQL run automatically when the system starts, you must also configure MySQL to use PHP-compatible passwords. To do this, use TextEdit (or your text editor of choice) to create a plain text file called my.cnf on the desktop with these contents:[mysqld] old-passwords
Then move the file to /usr/local/mysql/data/ and restart your system for the change to take effect.
Here are detailed steps for doing this:- From the Applications folder, start TextEdit.
- Choose Format > Make Plain Text from the menu.
- Type the contents for the file, shown above.
- Choose File > Save As... and type my.cnf in the Save As box. Choose Desktop in the Where box. Click Save.
- When prompted, click Don't Append to keep .cnf as the filename extension.
- Quit TextEdit.
- On the Finder menu bar, choose Go > Go to Folder... and type /usr/local/mysql/data/ as the destination.
- Drag my.cnf from the desktop to the /usr/local/mysql/data/ folder. When prompted, choose Authenticate and enter your administrator login credentials.
- Restart your system.
- p.46 last paragraph
'l, F ds Y.' should be 'l, F dS Y.' - p.70 code listing 1
The closing parenthesis on the 4th line doesn't belong there:'database server at this time.</p>';
- p.99 code listing 4
jokelookup should be jokecategory. - p.109 code listing
In addition to deleting the jokes associated with an author, deleteauthor.php should remove corresponding entries from the jokecategory table before deleting an author. The queries in this script must be changed to the following:$ok1 = @mysql_query(
The first query deletes jokes that have been assigned to categories, along with their category assignments. This query makes use of an extended form of the DELETE query that deletes entries from multiple tables with a single query. This syntax is documented in Appendix A.
"DELETE joke, jokecategory
FROM joke, jokecategory WHERE jokeid=joke.id AND authorid='$id'"); $ok2 = @mysql_query("DELETE FROM joke WHERE authorid='$id'"); $ok3 = @mysql_query("DELETE FROM author WHERE id='$id'"); if ($ok1 and $ok2 and $ok3) { ...
The second query deletes any remaining (uncategorized) jokes. The third query deletes the author from the database. - p.160 code listing 2
The SELECT query in this script should use the DISTINCT option to prevent jokes in multiple categories from being displayed more than once when no category filter is specified:$jokessql = 'SELECT DISTINCT joke.id LEFT(joketext, 20), jokedate, name, email FROM joke, author, jokecategory WHERE authorid=author.id AND jokeid=joke.id'; - p.217 code listing
The second line that begins with } elseif is missing a closing parenthesis:} elseif (isset($_FILES['upload'])) { - p.291 paragraph 2
DISCTINCTROW should be DISTINCTROW. - p.310 table B.1
The "Week 1" data for the last three rows is incorrect:4 Sunday 0 to 53 first week that has more than 3 days in this year 5 Monday 0 to 53 first week that starts in this year 6 Sunday 1 to 53 first week that has more than 3 days in this year 7 Monday 1 to 53 first week that starts in this year
Confirmed errors in the November 2004 reprint:
Some of the errors listed here may also apply to the previous edition (see below).
- p.xii paragraph 4
"...creating static copies of dynamic pages at regular intervals..." - p.24
extension_dir will have already been set to c:\php\ext (or equivalent) at this stage, so there is no need to check it at this point. It should certainly not be set to c:\php, unless you have decided to place your PHP extensions there for some reason. - p.27
In date('l, F dS Y.'); the first character inside the quotes is actually a lowercase 'L', though the font may make it look like the number '1'. - p.45 paragraph 5
"Each statement is an instruction that must be followed by the Web server..." - p.46
In date('l, F dS Y.'); the first character inside the quotes is actually a lowercase 'L', though the font may make it look like the number '1'. - p.52 code listing 2
my should be our to match the output shown in Figure 3.2. - p.55 code listing 2
my should be our to match the output shown in Figure 3.4. - p.56 code listing 1
my should be our. - p.58 code listing 2
my should be our to match the output shown in Figure 3.6. - p.123 code listing
The code listing on this page should be identified as jokes.php. - p.150 paragraph 1, code listing 1
The information about various line break formats in this paragraph is incorrect. Windows uses \r\n and Macintosh uses \r. As a result, the code for handling them needs to be changed:// Convert Windows (\r\n) to Unix (\n)
$joketext = ereg_replace("\r\n", "\n", $joketext);
// Convert Macintosh (\r) to Unix (\n) $joketext = ereg_replace("\r", "\n", $joketext); // Handle paragraphs $joketext = ereg_replace("\n\n", '</p><p>', $joketext); // Handle line breaks $joketext = ereg_replace("\n", '<br />', $joketext); - p.158
The code for handling paragraphs and line breaks needs to be adjusted as per the changes on p.150 above.// Paragraphs and line breaks
$joketext = ereg_replace("\r\n", "\n", $joketext);
$joketext = ereg_replace("\r", "\n", $joketext);
$joketext = ereg_replace("\n\n", '</p><p>', $joketext);
$joketext = ereg_replace("\n", '<br />', $joketext); - p.170 paragraph 5
The access control section of the MySQL Reference Manual is now in Chapter 5 of that document, not Chapter 6. - p.178 paragraph 2
The table maintenance section of the MySQL Reference Manual is now in Chapter 5 of that document, not Chapter 4. - p.230 paragraph 3
'exits' should be 'exists'. - p.266 code listing
This script must begin by calling session_start() to enable session functionality:<?php session_start(); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> ...
- p.272 code listing 2
access.inc.php needs to call session_start() to enable session functionality within the site:<?php require_once 'config.inc.php'; session_start(); function loggedIn() { ... - p.272 code listing 2
$_POST['login'] should be $_POST['username']. - p.296 code listing 3
t1.aid and t2.aid should be t1.tid and t2.tid, respectively.
Confirmed errors in the October 2004 Third Edition:
Some of the errors listed here may also apply to the previous edition (see below), although page numbers will almost certainly differ.
- p.7 step 2
In PHP 5 or later, you must copy the libmysql.dll file from the PHP installation directory to your system32 directory along with php5ts.dll. - p.49 paragraph 3
$myarray contains these three values: 'one', 2, and '3' (not 'three').
Confirmed errors in the June 2003 reprint:
Some of the errors listed here may also apply to the previous edition (see below), although page numbers will almost certainly differ.
- p.61 footnote 6
"was available" should be "is available". - p.118 paragraph 5
The URL for the regular expression tutorial has changed: http://www.delorie.com/gnu/docs/regex/regex_toc.html. - p.164 code listing 1
\n cannot be used in a single-quoted string. For this example, you can simply remove it. - p.194 paragraph 1
'company.com' should be '.company.com'.
missing space after 'with' in "withcompany.com." - p.194 paragraph 3
setcokie should be setcookie. - p.248 line 2
Second number should be ±2.2250738585072014E-308. 'E' is missing.
Second Edition:Mar 2003
Confirmed errors in the March 2003 edition:
Some of the errors listed here may also apply to the previous edition (see below), although page numbers will almost certainly differ.
The credits page of this edition identifies the printing date as February 2003.
- p.25 paragraph 5
shell# should be shell%. - p.27-28 Procedure for setting MySQL root password
As of MySQL 4.0, the procedure given in the book is no longer valid. These updated instructions will work in this new version, as well as in previous versions of MySQL:To set a root password for MySQL, type the following command in the bin directory of your MySQL installation:
mysql -u root mysqlThis command connects you to your newly-installed MySQL server as the root user, and chooses the mysql database. After a few lines of introductory text, you should see the MySQL command prompt (mysql>).
To assign a password to the root user, type the following three commands (pressing Enter after each one):
mysql>SET PASSWORD FOR root@localhost=PASSWORD("new password"); Query OK, 0 rows affected (0.00 sec) mysql>SET PASSWORD FOR root@"%"=PASSWORD("new password"); Query OK, 0 rows affected (0.00 sec) mysql>FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec)Be sure to replace both instances of new password with the password you want to assign to your root user. The first command sets the password required when connecting from the machine on which the server is running; the second sets the password for all other connections.
With that done, disconnect from MySQL with the quit command:
mysql>quit
ByeNow, to try out your new password, at the system command prompt again, request that the MySQL server tell you its current status:
mysqladmin -u root -p status - p.54 paragraph 3
The array contains three values, not four. - p.82 code block
The single quotes around the DELETE query should be double quotes, to allow the $jokeid variable to be interpolated. - p.89 paragraph 2
Should read: "involving just two CREATE TABLE queries". - p.143 code block
There should not be quotes around the 'user' component of the GRANT query. - p.144 paragraph 3
Second sentence should read:Both values may contain the % wild card character, but you need to put quotes around any value that does (e.g. kevin@"%" will allow the user name kevin to log in from any host and use the privileges you specify). - p.145 code blocks 1 and 2
There should be no quotes around 'dbmgr@server.host.net'. - p.145 code block 3
Both "jess@%.host.net" and jess@%.host.net (i.e. with and without quotes) should be replaced with jess@"%.host.net". - p.145 code block 4
There should be no quotes around the 'user' component of the REVOKE query. - p.146 code block 1
The quotes in this query are incorrect. The correct query is:mysql>REVOKE DROP ON *.* FROM idiot@"%.host.net"; - p.147 paragraph 2
On a Window installation, of the two entries described in this paragraph, the hostname of the second is set to %, not the server's hostname. It therefore does not contribute to the problem described here. It does, however, permit connections with any user name from any computer, so it's a good idea to delete it anyway. - p.197 paragraph 1
"Intimidated" should be "intimidating".
Confirmed errors in the August 2001 edition:

First Edition:Aug 2001
The code examples in this book are intended for PHP configurations using the setting register_globals=on. Users of PHP 4.2 and above may need to set this manually. Please see page 20 to 21 for instructions. For more information on register_globals and security, see this article.
- Summary of Contents page
The page numbers for chapters 6 and 7 are not correct (should be 77 and 97, respectively). - p.8 paragraph 3
The latest versions of MySQL for Win32 do not come with the my-example.cnf file described in the book. Get a copy of the file here (right-click and choose "Save Target As..." in MSIE). - p.18 paragraph 5
To clarify, php.ini should only be placed in /usr/local/php/lib if --with-config-file-path was NOT specified in the ./configure command you used. If you used the ./configure command displayed on this page, you should therefore place php.ini in /usr/local/php. - p.31 paragraph 2
Second occurrence of 'pretty' doesn't belong there. - p.49 2nd code block
<?=echo($PHP_SELF)?> should be <?=$PHP_SELF?> - p.57 2nd code block
Second <head> should be </head>. - p.58-59
If your PHP configuration complains "Undefined variable: submitjoke" when you run this script, it's because your PHP error reporting level is turned up a little higher than usual. Change if ($submitjoke=="SUBMIT") to if (isset($submitjoke)) to get rid of the error by not assuming that PHP will create the variable for you if it doesn't exist. - p.66 code block
Under 'DESCRIBE Jokes' the table should list 'AuthorName'. and 'AuthorEmail' as 'varchar(255)' columns. - p.80 code block
Unmatched parenthesis following 'mysql_error()'. - p.83 3rd code block
'intput' tag should be 'input'. - p.89 2nd last line
Closing </p> should go after </textarea>. - p.94 paragraph 2
'addjoke.php' should be 'newjoke.php'. - p.98 paragraph 5
The word 'removing' doesn't belong. - p.100 5th code block
'a-zA-z' should be 'a-zA-Z'. - p.109 paragraph 1
'series' should be 'book'. - p.142 code block
</tutke> should be </title>. - p.149 last paragraph
SitePoit.com should be SitePoint.com. - p.152 paragraph 2
'is on in a member of a family of' should be 'is one of several'. - p.153 paragraph 2
'usethat' should be 'use that'. - p.156 paragraph 4
'url' should be 'URL'. - p.158 code block
All three occurrences of $f['id'] should be $f['ID']. - p.170 code block
Extra quotes on the end of "Used Parachute" line. - p.171 code block
Comment in if ($empty != "") block should be // Empty the $shoppingcart array - p.207 paragraph 2
'Error! Not a valid bookmark self-reference.' should be 'Table 3'. - p.208 last paragraph
The text following 'any of the symbols listed in' all the way to 'placeholders.' at the top of p.209 should not be there. - p.215 code block
Second occurrence of FLOAT(precision) should be DOUBLE(precision). - p.217-218
Maximum length values in parentheses should be 64KB, 16MB, and 4GB for BLOB/TEXT, MEDIUMBLOB/MEDIUMTEXT, and LONGBLOB/LONGTEXT column types, respectively.
3rd Edition
3rd Edition NOW Available!
What's New?
- All-new coverage of PHP 5.0 keeps up to date with the latest best practices in PHP
- New screenshots throughout the book show you how it’s done visually
- A new chapter on building structured programming that teaches you to build an access control system in PHP
- Revised and expanded throughout
- All known errors in the previous edition now corrected
- 58 pages longer

