Errata

Learning PHP, MySQL, and JavaScript

Errata for Learning PHP, MySQL, and JavaScript

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted By Date submitted Date corrected
Printed
Page 57
Middle and botttom of page (there are two instances)

The term

$_SERVER['HTTP_REFERRER']

should be replaced with $_SERVER['HTTP_REFERER']

(one less R)

Robin Nixon
Robin Nixon
 
Jun 16, 2010  Nov 01, 2010
PDF
Page 65
example 4-9

Example 4-9. After evaluating the subexpressions in parentheses
1 + (6) - (20)
2 - (60) + 1
5 + 2 - 4 + (4)

3rd example should be:

5 + 2 - 4 + (3)

Note from the Author or Editor:

Anonymous  Oct 23, 2009  Feb 01, 2010
Printed
Page 66
Table 4-3

The ternary operators (? and :) are correctly identified in Table 4-2 and should not have been copied to Table 4-3 where they do not belong.

Robin Nixon
Robin Nixon
 
Sep 12, 2010  Nov 01, 2010
PDF
Page 67
Example 4-4

Example does not define $day_number.

<?php
$day_number = date("z"); // This is today's day number
$days_to_new_year = 366 - $day_number;
if ($days_to_new_year < 30)
{
echo "Not long till new year";
}else {
echo "We have a way to go till the end of the year.";
}

?>

Note from the Author or Editor:
Yes, you would set $day_number to a value (such as 350) before executing the example, like this:

$day_number = 350;

$days_to_new_year = 366 - $day_number;
if ($days_to_new_year < 30)
{
echo "Not long now till new year";
}

Phil Cyphers  Feb 25, 2013 
Printed
Page 72
Example 4-19

$money += 1000;

should be:

$money = 1000;

George  Apr 26, 2012 
PDF
Page 82
3rd paragraph from bottom

The terminating condition in the for loop is:

$i + $j < 10

but in the analysis of this loop it appears as:

$i + $j < 1

Note from the Author or Editor:
The three example lines at the foot of page 82 should be as follows (the middle line should be $j < 10, not $j < 1):

$i = 1, $j = 1 // Initialize $i and $j
$i + $j < 10 // Terminating condition
$i++ , $j++ // Modify $i and $j at the end of each iteration

razorbill  Nov 30, 2010  Feb 01, 2011
PDF
Page 84
Example 4-36

In the final closing tag '?' is missing, i. e. should be "?>".

Vadim Flyagin  Oct 07, 2011 
PDF
Page 103
2nd paragraph from below

--printed--

copies the property values from the original class to the new instance.

--should be--

copies the property values from the original instance to the new instance.

Vadim Flyagin  Nov 26, 2011 
Printed
Page 106
In the "warning text" approx. in the middle of page 106

...within a static class, ...

should be

...within a static function, ...

Rationale: I've never heard of static classes (it's pointless because it's like saying 'class classes').

  Sep 12, 2010  Feb 01, 2011
Printed
Page 107
Example 5-21

As listed, with PHP 5.3, a strict run-time error will be generated.

Changing the code to make the lookup function static will resolve this.

Correct code for example 5-21 is as follows:

<?php

Translate::lookup();

class Translate
{
const ENGLISH = 0;
const SPANISH = 1;
const FRENCH = 2;
const GERMAN = 3;
// ...

static function lookup()
{
echo self::SPANISH;
}
}
?>


Note from the Author or Editor:
With PHP 5.3 running in strict mode you have to make the function within the class static.

Anonymous  Aug 31, 2010  Nov 01, 2010
PDF
Page 118
bottom of the page

--printed--

echo $p1['inkjet']; // Undefined index
echo $p2['3']; // Undefined offset

--should be--

In the second line single quotes near number 3 must be deleted. For they will produce another kind of error: "Undefined index", instead of "Undefined offset". Also, in the first line "Inkjet" would be better then "inkjet", because in the previous example 6.5 array $p1 has "Inkjet" element, but not "inkjet".

Vadim Flyagin  Dec 03, 2011 
Printed
Page 122
Example 6-11

Sorry to be pedantic, but if your depiction of a chessboard is to follow the usual convention of white pieces starting at the bottom of the board, you need to swap round the King and Queen positions.
;-)

john maguire  Sep 26, 2011 
Printed
Page 122
Example 6-11

In Example 6-11 on page 122 there are 10 rows instead of 8 in the array used to construct a chessboard. Two of the blank rows should be removed from the middle.

Robin Nixon
Robin Nixon
 
Feb 09, 2010  Nov 01, 2010
PDF
Page 132
Table 7-2

I think in line 3 the "Display precision" value ".2" should be assign to line 2 and value ".4" in line 2 should be assign to line 3.

Note from the Author or Editor:
On page 132, in Table 7-2, the .4 and .2 in the 'Display precision' column should be swapped.

Anonymous  Oct 11, 2009  Feb 01, 2010
PDF
Page 135
Table 7-4, under "Week specifier"

--printed--

Week number of year 1 to 52

--should be--

Week number of year 01 to 52

Vadim Flyagin  Jan 21, 2012 
Printed
Page 136
DATA_COOKIE example

The 'l' format specifier implies that the day should be output as 'Thursday'
and not 'Thu' as shown.
Also hyphens are shown in the format specifier but not in the example output.
Which is the correct format for DATA_COOKIE format?

john maguire  Sep 26, 2011 
PDF
Page 136

DATE_ATOM paragraph
printed: +0000
should be: +00:00

DATE_COOKIE paragraph
printed: Thu, 16 Aug 2012 12:00:00 UTC
should be: Thursday, 16-Aug-12 15:52:01 UTC

DATE_RSS paragraph
printed: D, d M Y H:i:s T
should be: D, d M Y H:i:s O
printed: UTC
should be: +0000

DATE_W3C paragraph
printed: +0000
should be: +00:00

(Correct version see here:
http://php.net/manual/en/class.datetime.php )

Vadim Flyagin  Jan 21, 2012 
PDF
Page 141
1st paragraph after example 7-11

The book says:
"...by setting the mode with '+r', which puts..."
It should say:
"...by setting the mode with 'r+', which puts..."

razorbill  Dec 10, 2010  Feb 01, 2011
Printed
Page 142
Example 7-12

The command fseek($fh, 0, SEEK_END); must be moved to become the first statement inside the following if statement to ensure it also benefits from the file locking. The corrected example should look like:

<?php
$fh = fopen("testfile.txt", 'r+') or die("Failed to open file");
$text = fgets($fh);

if (flock($fh, LOCK_EX))
{
fseek($fh, 0, SEEK_END);
fwrite($fh, "$text") or die("Could not write to file");
flock($fh, LOCK_UN);
}
fclose($fh);
echo "File 'testfile.txt' successfully updated";
?>

Robin Nixon
Robin Nixon
 
Sep 15, 2009  Feb 01, 2010
Printed
Page 149
3rd paragraph

ereg_replace() has been deprecated

Jesse Wheeler  Aug 22, 2011 
PDF
Page 159
Middle of page

In my case (I have't password)
after this:
"\Program Files\EasyPHP 3.0\mysql\bin\mysql" -u root

I'm receiving:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

I must add "-p" (\Program Files\EasyPHP 3.0\mysql\bin\mysql" -u root -p)and just press enter (after query "Enter password:")

Note from the Author or Editor:
Summary: In some cases if you do not have a password set and are using MySQL as the root user, then you can enter it by using both the -u root and -p options, and simply pressing Enter when prompted for the password.

Damian  Feb 07, 2011 
Printed
Page 166
After the first paragraph

Instead of GRANT ALL ON publications.* TO 'jim' IDENTIFIED BY 'mypasswd';

Following is the correct syntax, as recommended at http://dev.mysql.com/doc/refman/5.1/en/adding-users.html:

GRANT ALL ON publications.* TO 'jim'@'localhost' IDENTIFIED BY 'mypasswd';

Robin Nixon
Robin Nixon
 
Mar 25, 2010  Nov 01, 2010
PDF
Page 172
2nd paragraph under 'The AUTO_INCREMENT data type' heading

The sentence: 'The general solution is to use an extra row just for this purpose.' should read: 'The general solution is to use an extra column just for this purpose.'.

Anonymous  Aug 22, 2009  Feb 01, 2010
PDF
Page 214
Figure 9-3

Note from the Author or Editor:
The two ISBN numbers 0596527403 and 0596101015 in rows 2 and 3 should be swapped.

Anonymous  Jul 31, 2009  Feb 01, 2011
219
After third paragraph

The example given,

LOCK TABLES tablename1 tablename2 ... READ

produces an error for me. I found this format will work:

LOCK TABLES tablename1 READ, tablename2 READ, ... ;

Gil Yoder  Dec 26, 2009  Feb 01, 2010
Printed
Page 220
next to last line

Example 9-8. Dumping the publications database to screen

--should be--

Example 9-8. Dumping the publications database to file

richard  Jan 08, 2011  Feb 01, 2011
221
Example 9-9

Example 9-9 should include "use publications;" statements after both startings of the mySql command line environment, and semicolons at the end of each mySql command.

Note from the Author or Editor:
The section on page 221 that reads as follows is not quite correct, since the publications table is not selected before issuing the LOCK command, and it can also be much simplified:

Should you wish to back up only a single table from a database
(such as the classics table from the publications database), you
could use a sequence of commands such as those in Example 9-9, in
which you simply follow the database name with that of the table
to be backed up.

I've assumed here that you haven't shut down the MySQL server.
You're letting it run while you back up the classics table, but
you lock that single table during the backup so that no one can
access it.

Example 9-9. Dumping just the classics table from publications

$ mysql -u user -ppassword
mysql> LOCK TABLES classics READ
mysql> QUIT
$ mysqldump -u user -ppassword publications classics > classics.sql
$ mysql -u user -ppassword
mysql> UNLOCK TABLES
mysql> QUIT

The replacement text for these two paragraphs and Example 9-9 is as follows:

To back up only a single table from a database (such as the
classics table from the publications database), you should first
lock the table from within the MySQL command line, by issuing a
command such as the following:

LOCK TABLES publications.classics READ

This ensures that MySQL remains running for read purposes, but
writes cannot be made. Then, while keeping the MySQL command line
open, use another terminal window to issue the following command
from the operating system command line:

mysqldump -u user -ppassword publications classics > classics.sql

You must now release the table lock by entering the following
command from the MySQL command line, which unlocks all tables
that have been locked during the current session:

UNLOCK TABLES

Gil Yoder  Dec 26, 2009  Feb 01, 2010
Printed
Page 221 and 222
Example 9-9

Example 9-9. Dumping just the classics table from publications

the two following lines are missing semicolons:

mysql> LOCK TABLES classics READ

mysql> UNLOCK TABLES

Anonymous  Nov 27, 2010  Feb 01, 2011
Printed
Page 227
Example 10-2

Title of this example should read:-

Connecting to a MySQL server

rather than a database.

john maguire  Sep 26, 2011 
Printed
Page 227
bottom of page in note re: function mysql_fatal_error

in line 3 of example:

$msg2 - mysql_error();

should be:

$msg2 = mysql_error();

sdguy  Nov 09, 2009  Feb 01, 2010
Printed
Page 231
Example 10-7

The title of example 10-7 should be

Closing a MySql server connection

although it does by implication also close the database.

john maguire  Sep 26, 2011 
Printed
Page 233
Start of page

The listed example does not correctly handle deleting an entry and the entire code should be replaced with the following:

<?php // sqltest.php
require_once 'login.php';
$db_server = mysql_connect($db_hostname, $db_username, $db_password);

if (!$db_server) die(

Note from the Author or Editor:
Replace Example 10-8 on page 233 with the following:

<?php // sqltest.php
require_once 'login.php';
$db_server = mysql_connect($db_hostname, $db_username, $db_password);

if (!$db_server) die("Unable to connect to MySQL: " . mysql_error());

mysql_select_db($db_database, $db_server)
or die("Unable to select database: " . mysql_error());

if (isset($_POST['delete']) && isset($_POST['isbn']))
{
$isbn = get_post('isbn');
$query = "DELETE FROM classics WHERE isbn='$isbn'";

if (!mysql_query($query, $db_server))
echo "DELETE failed: $query<br />" .
mysql_error() . "<br /><br />";
}

if (isset($_POST['author']) &&
isset($_POST['title']) &&
isset($_POST['category']) &&
isset($_POST['year']) &&
isset($_POST['isbn']))
{
$author = get_post('author');
$title = get_post('title');
$category = get_post('category');
$year = get_post('year');
$isbn = get_post('isbn');

$query = "INSERT INTO classics VALUES" .
"('$author', '$title', '$category', '$year', '$isbn')";

if (!mysql_query($query, $db_server))
echo "INSERT failed: $query<br />" .
mysql_error() . "<br /><br />";
}

echo <<<_END
<form action="sqltest.php" method="post"><pre>
Author <input type="text" name="author" />
Title <input type="text" name="title" />
Category <input type="text" name="category" />
Year <input type="text" name="year" />
ISBN <input type="text" name="isbn" />
<input type="submit" value="ADD RECORD" />
</pre></form>
_END;

$query = "SELECT * FROM classics";
$result = mysql_query($query);

if (!$result) die ("Database access failed: " . mysql_error());
$rows = mysql_num_rows($result);

for ($j = 0 ; $j < $rows ; ++$j)
{
$row = mysql_fetch_row($result);
echo <<<_END
<pre>
Author $row[0]
Title $row[1]
Category $row[2]
Year $row[3]
ISBN $row[4]
</pre>
<form action="sqltest.php" method="post">
<input type="hidden" name="delete" value="yes" />
<input type="hidden" name="isbn" value="$row[4]" />
<input type="submit" value="DELETE RECORD" /></form>
_END;
}

mysql_close($db_server);

function get_post($var)
{
return mysql_real_escape_string($_POST[$var]);
}
?>

Robin Nixon
Robin Nixon
 
Aug 21, 2009  Feb 01, 2010
Printed
Page 244
Paragraph 2

The section that begins "But there's a slight window of opportunity" should be ignored. After having spent a lot of time researching the reports on the web about this, none of those I looked at were actually bugs in MySQL, and were instead bugs in the programmer's code. Therefore I will lay this one to rest and say that there is not a problem in MySQL with mysql_insert_id() and race conditions.

Robin Nixon
Robin Nixon
 
Mar 17, 2010 
247
First Paragraph

I just happened to notice a simple title in your text. You refer to mysql_real_escape_string as mysql_real_eascape_string. Notice the extra "a" in escape. Thanks for the great book!

Brian Gasperosky  Feb 10, 2010  Nov 01, 2010
Printed
Page 252
top

<?php // formtest.php
echo <<<_END
<html>
<head>
<title>Form Test</title>
</head>
<body>
<form method="post" action="formtest.php" />
What is your name?
<input type="text" name="name" />
<input type="submit" />
</form>
</body>
</html>
_END;
?>

Same online. Form shouldn't be closed by />, right?

Note from the Author or Editor:
The <form method... /> statement in Example 11-1 should not have the self-closing /> tag, and should therefore read:

<form method="post" action="formtest.php">

However, since self-closing is not supported by the <form> tag, this typo should not affect the behavior of the HTML.

Anonymous  May 21, 2010  Nov 01, 2010
PDF
Page 263
Example 11-9

This problem was mentioned in the unconfirmed errata,
I think Example 11-9 should be:

function sanitizeString($var)
{
if (get_magic_quotes_gpc()) $var = stripslashes($var); //check
$var = htmlentities($var);
$var = strip_tags($var);
return $var;
}

function sanitizeMySQL($var)
{
$var = sanitizeString($var); //first
$var = mysql_real_escape_string($var); //second
return $var;
}

Excellent book...

Note from the Author or Editor:
Yes, that makes sense to add.

Damian  Mar 18, 2012 
Printed
Page 266
1st paragraph

In the first paragraph of page 266 the author writes down the formula for converting from Celsius to Fahrenheit.
According to him, the formula is "Fahrenheit = (9/5) * (Celsius +32).
I have tested back an forth, and I think the correct way of writing it would be like this:
"Fahrenheit = ((9/5) * Celsius) + 32"

Haavard  Oct 22, 2011 
Printed
Page 271
The final line of Example 12-1

Because the path to the template files is already known, the final line of Example 12-1, which reads

$smarty->display("$path/temp/index.tpl");

Should be replaced with:

$smarty->display("index.tpl");

Robin Nixon
Robin Nixon
 
Dec 14, 2009  Feb 01, 2010
Printed
Page 271
Directory Structure just above Creating Scripts header.

The directory structure above the heading says to create a directory named 'config' should be named 'configs' according to the install readme from Smarty and the code examples within this chapter.

Garry Freemyer  May 17, 2010  Nov 01, 2010
Printed
Page 274
The fifth line from the bottom of Example 12-3

Because the path to the template files is already known, the fifth line from the bottom of Example 12-3, which reads:

$smarty->display("$path/temp/smartytest.tpl");

Should be replaced with:

$smarty->display("smartytest.tpl");

Robin Nixon
Robin Nixon
 
Dec 14, 2009  Feb 01, 2010
Printed
Page 292
Bottom of example 13-8

Calling setcookie() after echo causes the following warning:
Warning: Cannot modify header information - headers already sent by (output started at C:\web\lpmj.examples\named_examples\continue.php:36) in C:\web\lpmj.examples\named_examples\continue.php on line 47

Note from the Author or Editor:
The section of code which reads as follows:

echo "Welcome back $forename.<br />
Your full name is $forename $surname.<br />
Your username is '$username'
and your password is '$password'.";

destroy_session_and_data();

Should be changed so that the call to destroy_session_and_data() comes first, like this:

destroy_session_and_data();

echo "Welcome back $forename.<br />
Your full name is $forename $surname.<br />
Your username is '$username'
and your password is '$password'.";

Ron Inbar  Aug 21, 2010  Nov 01, 2010
Printed
Page 303
Table 14-1

Note from the Author or Editor:
On Page 303 in Table 14-1, the entry that reads:

"Safari does not have an Error Console enabled by default, so the Firebug Lite JavaScript module will do what you need."

should be changed to

"Safari does not have an Error Console enabled by default, but you can turn it on by selecting Safari->Preferences->Advanced->Show Develop menu in menu bar. However, you may prefer to use the Firebug Lite JavaScript module which many people find easier to use."

Benjamin Westafer  Aug 17, 2009  Nov 01, 2010
Printed
Page 313-314
Example 14-11 , Example 14-12 and top of page 314

Note: Second time posting this errata.

You can not pass an undefined variable as an argument to a function.

The comment on page 314, "If your browser issues a warning about b being undefined, the warning is correct but can be ignored." is not accurate. An error is generated not a warning.

To confirm this is true, in script Example 14-12 reverse the following statements:

if (isset(a)) document.write('a = "' + a + '"<br />')
if (isset(b)) document.write('b = "' + b + '"<br />')

to:

if (isset(b)) document.write('b = "' + b + '"<br />')
if (isset(a)) document.write('a = "' + a + '"<br />')

Now when you execute this script, no output will be generated, instead an error is generated in the JavaScript/error console.

In Chromium 9, the following error message is generated:

Uncaught ReferenceError: b is not defined.

In Firefox 13.6, the following error message is generated:

b is not defined

Note from the Author or Editor:
The function issest() does not work as described, so please
replace example 14-12 with the following alternative, since JavaScript doesn't support passing an undefined variable to a function:

<script>
test()

if (typeof a != 'undefined') document.write('a = "' + a + '"<br />')
if (typeof b != 'undefined') document.write('b = "' + b + '"<br />')
if (typeof c != 'undefined') document.write('c = "' + c + '"<br />')

function test()
{
a = 123
var b = 456
if (a == 123) var c = 789
}

</script>

R. H. Topics  Feb 07, 2011  Feb 01, 2011
Printed
Page 321
Caption for example 15-3

Shouldn't the caption read 'Two simple JavaScript statements'. The caption currently refers to PHP instead of JavaScript.

Ken Wilson  Jan 11, 2010  Feb 01, 2010
Printed
Page 322
Table 15-2

The bitwise operator &, | and ^ are not listed in the table.

Russell Stringham  Jul 29, 2010  Nov 01, 2010
Printed
Page 324
Example 15-6

In order for the sample code to produce the output described in the follow up paragraph the following code statements:

if (a > b) document.write("a is greater than b<br />")
if (a < b) document.write("a is less than b<br />")
if (a >= b) document.write("a is greater than or equal to b<br />")
if (a <= b) document.write("a is less than or equal to b<br />")

need to be changed as follows:

if (a > b) document.write(a + " is greater than " + b + "<br />")
if (a < b) document.write(a + " is less than " + b + "<br />")
if (a >= b) document.write(a + " is greater than or equal to " + b + "<br />")
if (a <= b) document.write(a + " is less than or equal to " + b + "<br />")

Note from the Author or Editor:
the output following Example 15-6 on page 324 should be changed from this:

7 is less than 11
7 is less than or equal to 11

To the following

a is less than b
a is less than or equal to b

Ken Wilson  Oct 24, 2009  Feb 01, 2010
PDF
Page 325
Example 15-9

In the JavaScript code:

gn = getnext()
if (finished == 1 OR gn == 1) done = 1;

there should be "||" instead of "OR".

Tigran  Jul 16, 2012 
Printed
Page 326
Example 15-11

"onError" should be all lowercase, i.e. "onerror". JavaScript is case sensitive.

Note from the Author or Editor:

Ken Wilson  Oct 24, 2009  Feb 01, 2010
Printed
Page 350
Top of page

The out at the top of this page should be:

Element at index 0 has the value Cat
Element at index 1 has the value Dog
Element at index 2 has the value Rabbit
Element at index 3 has the value Hamster

Note from the Author or Editor:
Example 16-11 was modified late in the copy edit stage to clarify the difference between indexes and elements held in indexes. Therefore the output shown from the modified example should include the extra words "at index". This does not affect the working of the example or the explanation of its function.

Hongjiang Li  Jul 04, 2010  Nov 01, 2010
PDF
Page 353
2nd paragraph

Written:

"If the function returns a value greater than zero, the sort assumes that a comes before b. If the function returns a value less than zero, the sort assumes that b comes before a."

In fact it is vice versa:

"If the function returns a value greater than zero, the sort assumes that a comes AFTER b. If the function returns a value less than zero, the sort assumes that b comes BEFORE a."

Also if the function returns 0, a and b remain unchanged with respect to each other.

Tigran  Jul 16, 2012 
Printed
Page 360
1st paragraph.

I just submitted an error where I thought code on page 358 was incorrect but it is the text description that is incorrect not the code.

The description of the function code in the first paragraph of page 360 is "If even one character that isn't one of the acceptable characters is encountered, the test function returns FALSE. and so validateUser returns an error string."

The word in all caps above should actually be true, not false in keeping with the code.

Note from the Author or Editor:
The sentence at the top of page 360 which goes "If even one character that isn't one of the acceptable characters is encountered, the test function returns false. and so validateUser returns an error string.", should be replaced with the following:

"If even one character that isn't one of the acceptable characters is encountered, the test function returns true, and so validateUser returns an error string."

Garry Freemyer  May 19, 2010  Nov 01, 2010
Printed
Page 361
Paragraphing following heading Matching Through Metacharacters

Second sentence "Within these slashes, certain characters have special meanings; there are called metacharacters." should change "there" (after semicolon) to "they".

Russell Stringham  Aug 04, 2010  Nov 01, 2010
Printed
Page 365 and 366
figure 17-3 and 17-4

First slash is in the wrong direction on the figure.
It is correct in the rest of the explanation

Note from the Author or Editor:
On page 365 of the printed edition, the first character in Figure 17-3 is shown as a \, but it should be a /. The same goes for the first character of Figure 17-4 which should be a /.

Anonymous  Jan 01, 2010  Feb 01, 2011
Printed
Page 368
Table 17-2

The fourth example in Table 17-2, rec(ei)|(ie)ve, should be: rec(ei|ie)ve.

Robin Nixon
Robin Nixon
 
Apr 01, 2010  Nov 01, 2010
Printed
Page 368
Table 17-2

In table 17-2, example:

a-f Matches any of the characters a,b,c,d,e or f

the a-f should be in square brackets:

[a-f]

Note from the Author or Editor:
You would place such sequences within square brackets so I agree it would be better to show them in the table.

jteeters  Apr 15, 2010  Nov 01, 2010
Printed
Page 381-384

I downloaded code for Examples 18-2 and 18-3. It simply does not work in Google Chrome, Firefox or IE.

With GC and FF, I get an error message "Ajax error". After running the unaltered code, I changed it slightly. By changing the text of the relevant error message, I found that condition "if (this.status == 200) is not met. This change to the text of 18-2 was necessary because "this.statusText" does not display in the alert box. Without this modification on my part, I would have been unable to determine if the problem was with the this.status or the this.responseText condition was the problem.

What is the solution? Thanks.

Note from the Author or Editor:
Ajax must be run on a server with a valid domain and cannot simply be loaded from a local filesystem. This is because of all the security built around Ajax to prevent cross site scripting attacks.

Anonymous  Jan 04, 2013 
Printed
Page 382
2nd paragraph

The line "After this, the open method is called to set the object to make a POST request to geturl.php in asynchronous mode." Does not correspond with the code on page 381 where it is listed as:

request.open("POST", "urlpost.php", true)

The 'geturl.php' on page 382 needs to be replaced with 'urlpost.php'

Anonymous  Aug 12, 2010  Nov 01, 2010
Printed
Page 397
Just after heading "The YUI asnynRequest method

The line in bold after '"The syntax is:" should conclude with

...callback, [ 'parameters...'] rather than
...callback [, 'paramaters...']. In other words, the first comma and the first square bracket are juxtaposed.

I discovered this in writing Example 19-1 using the POST method.

Note from the Author or Editor:
...callback [, 'parameters...'] is correct.

It means that the code within the [ ] brackets is optional, but if you choose to use it there must be a comma then the parameters. If you place the comma and don't provide a parameter following you may get unpredicted results, so the comma is omitted unless a parameter is to be added.

Jim Holmberg  Jan 10, 2013 
409
Example 20-2 rnheader.php

In the file rnheader.php, it is necessary to place the "session_start()" statement before the "include 'rnfunctions.php" statement in order to have the example work properly.
This is probably due to the fact that "rnfuctions.php" introduces html code.

Note from the Author or Editor:
Thanks for pointing this out. rnsetup.php had a single HTML message added that ended up requiring this fix. The alternative solution would be to remove the command "echo '<h3>Setting up</h3>';" from rnsetup.php.

Jos? Fournier  Feb 24, 2010 
Printed
Page 415
Near the end of example 20-5

The section of code that reads:

else
{
$query = "INSERT INTO rnmembers VALUES('$user', '$pass')";
queryMysql($query);
}

die("<h4>Account created</h4>Please Log in.");

Should actually be as follows...

else
{
$query = "INSERT INTO rnmembers VALUES('$user', '$pass')";
queryMysql($query);
die("<h4>Account created</h4>Please Log in.");
}

This is not a serious problem but, without the modification, it will display an incorrect success message instead of an error if you try to create a user that already exists.

Robin Nixon
Robin Nixon
 
Oct 25, 2009  Feb 01, 2010
PDF
Page 415
towards end of rnsignup.php code

This is a minor error.
Instead of the password input type being 'text' it should have been 'password' so that the password isn't visible when the user types it in.

So the code should be:
<?php //rnsignup.php
.
.
.
}
echo<<<_END
<form method='post' action='rnsignup.php'>$error
Username<input type='text' maxlength='16' name='user' value='$user'
onBlur='checkUser(this)'/><span id='info'></span><br/>
Password<input type='password' maxlength='16' name='pass'
value='$pass' /><br/>
??????
<input type='submit' value='Signup' />
</form>
_END;
?>

Great book though. 5/5. Thanks Robin.

Note from the Author or Editor:
Although not an error the reader makes a useful suggestion to change the type of the user input from text to password. I had left it as text so that the user could see what was happening, but on reflection this change to obscure the password as it is entered is better practice.

Pule Nong  Feb 28, 2010  Feb 01, 2011
Printed
Page 423
imageconvolution

Ubuntu (debian) uses the generic GD libray (as in apt-get install php5-gd). This library does not include many functions including imageconvolution - hence rnprofile.php won't run. To force PHP to use its inbuilt (forked) GD library I followed the useful post at http://cumu.li/2008/5/13/recompiling-php5-with-bundled-support-for-gd-on-ubuntu to recompile PHP from source. I suggest a footnote/instructions and a security warning to readers since many may be using Ubuntu/Debian.

Thanks for a good book.

matt black  Feb 18, 2010 
PDF
Page 432
Example 20-12

echo date('M jS \'y g:sa:', $row[4]);

Should be:
echo date('M jS \'y g:i:sa', $row[4]);

Note from the Author or Editor:
The date() function call as used displayed hh:ss (hours and seconds) instead of hh:mm (hours and minutes). To correct this it should read as follows:

echo date('M jS \'y g:ia', $row[4]);

Henry  Jan 03, 2011  Feb 01, 2011
Printed
Page 433
Example 20-13, line 2

The rnheaders.php file (included at the start) outputs html meaning that the call to destroySession() at line 7 cannot delete the cookie since headers are closed already.

I coded logout.php as follows to avoid this:
<?php // rnlogout.php
require_once 'rnfunctions.php';
session_start();
if(isset($_SESSION['user'])){
destroySession();
}
require_once 'rnheader.php';
...

Thanks for a good book.

Note from the Author or Editor:
The following code should replace that for rnlogout.php, shown in the book:

<?php // rnlogout.php
include_once 'rnheader.php';

if (isset($_SESSION['user']))
{
destroySession();
echo "<h3>Log out</h3>You have been logged out. Please
<a href='index.php'>click here</a> to refresh the screen.";
}
else echo "<h3>Log out</h3>You are not logged in";
?>

matt black  Feb 18, 2010  Feb 01, 2011
Other Digital Version
10395
2nd paragraph

"The next chapter will show you how to use the Smarty templating engine..."

The Amazon Kindle edition of this book (which I purchased at URL http://www.amazon.com/dp/1449319262) seems to contain no Smarty material whatsoever, other than a URL at location 108503.

I can only conclude that a large chunk of the book is missing.

Note from the Author or Editor:
Smarty was covered in Edition 1 of the book but so few readers actually used it the decision was taken to focus on an area of more interest, and so that chapter was removed to make way for one of the later chapters on CSS. Unfortunately the reference to Smarty appears not to have also been removed, please ignore that sentence.

Charles David Tallman  Oct 08, 2012