Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
PHP Programming With MySQL Second Edition.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
43.07 Mб
Скачать

The php.ini configuration file contains two directives,

display_errors and display_startup_errors, that determine

whether error messages are displayed in a Web browser. The

display_errors directive displays script error messages, whereas the

display_startup_errors directive displays errors that occur when

PHP starts. By default, the display_errors directive is assigned a

Value of “On” and the display_startup_errors directive is assigned

a value of “Off.” Although displaying error messages is useful when

you develop PHP scripts, the PHP Group strongly recommends that

you turn off the feature for scripts that run in production environ-

ments and save any errors in a log file instead. Hackers can use any

displayed error messages to identify potential weaknesses in your

Web site. The PHP Group also recommends that you only turn on the

display_startup_errors directive when debugging a script.


APPENDIX

Error Handling

and Debugging

Regardless of their experience, knowledge, and ability, all program-

mers introduce errors into their programs. Thus, they must devote

part of their programming education to mastering the art of debug-

ging. As you learned at the beginning of this book, debugging is the

act of tracing and resolving errors in a program. Debugging is an

essential skill for any programmer, regardless of the programming

language.

E

Determining the Error Type

Three basic types of errors can occur in a program: syntax errors,

run-time errors, and logic errors.

Syntax Errors

Syntax errors, or parse errors, occur when the PHP scripting

engine fails to recognize code. Syntax errors can be caused by incor-

rect use of PHP code, misspelled words, or references to objects,

methods, and variables that do not exist. For example, if a program-

mer omits a method’s closing parenthesis, the scripting engine

generates a syntax error. As another example, the statement ehco

"<p>Hello World!</p>"; causes a syntax error because echo is

misspelled. Similarly, the following statements cause a syntax error

because the $Hello variable is incorrectly typed with a lowercase ‘h’.

(Remember that identifiers in PHP are case sensitive.)

APPENDIX E

Syntax

errors in

compiled

languages,

such as

C++, are also called

compile-time errors

because they are usually

discovered when a pro-

gram is compiled.

Because PHP is an inter-

preted language, syntax

errors are not discovered

until a program executes.

$Hello = "<p>Hello World!</p>\n";

echo $hello;

Run-Time Errors

A run-time error occurs when the PHP scripting engine encounters

code it cannot execute while the rest of the program is executing.

Run-time errors differ from syntax errors in that they do not neces-

sarily represent PHP language errors. For example, consider the state-

ment customFunction();, which calls a custom PHP function named

customFunction(). This statement does not generate a syntax error

because it is legal (and usually necessary) to create and then call cus-

tom functions in a PHP program. However, if your program includes

the call statement but does not include code that creates the function

in the first place, your program generates a run-time error. The error

occurs when the scripting engine attempts to call the function but

cannot find it.

The following code shows another example of a run-time error. In

this example, an echo statement attempts to display the contents of a

variable named $MessageVar, which is set by calling the user-defined

function GetMessageString(). Because the function is not declared

anywhere in the document, a run-time error occurs.

<?php

$MessageVar = GetMessageString();

echo $MessageVar;

?>

656

When investigating a run-time error, keep in mind that the culprit

might actually be a syntax error. Because syntax errors do not occur

until the scripting engine attempts to execute the code, they often

manifest as run-time errors. For example, suppose your code includes

a function that contains a statement with a syntax error. This syntax

error will not be caught until the function executes at run time.

Logic Errors

A logic error is a flaw in a program’s design that prevents the pro-

gram from running as you anticipate. In this context, “logic” refers to

the execution of program statements and procedures in the correct

order to produce the desired results.

One common logic error is the creation of an infinite loop, in which a

loop statement never ends because its conditional expression is never

updated or is never FALSE. For example, the following code creates an

infinite loop because the third argument in the for statement’s paren-

theses never changes the value of the $Count variable:


APPENDIX E

for ($Count = 10; $Count >= 0; $Count) {

if ($Count == 0)

echo "<p>We have liftoff!</p>\n";

else

echo "<p>Liftoff in $Count seconds.</p>\n";

}

Because the $Count variable is never updated in the preceding exam-

ple, it continues to have a value of 10 through each iteration of the

loop, and “Liftoff in 10 seconds” is repeatedly displayed in a browser

window. To correct this logic error, you add a decrement operator to

the third argument in the for statement’s constructor, as follows:

for ($Count = 10; $Count >= 0; --$Count) {

if ($Count == 0)

echo "<p>We have liftoff!</p>\n";

else

echo "<p>Liftoff in $Count seconds.</p>\n";

}

657

Handling and Reporting Errors

The first line of defense in locating PHP program bugs are the error

messages you receive when the PHP scripting engine encounters an

error. PHP generates four basic types of errors: parse errors, fatal

errors, notices, and warnings. Parse errors are syntax errors, whereas

the other three types are run-time errors.

Parse error messages occur when a PHP script contains a syntax

error that prevents your script from running. For example, the fol-

lowing code raises a parse error because the for() statement is miss-

ing its opening brace ({). Figure E-1 shows the resulting parse error

message in a Web browser.

<?php

for ($Count = 10; $Count >= 0; --$Count)

if ($Count == 0)

echo "<p>We have liftoff!</p>\n";

else

echo "<p>Liftoff in $Count seconds.</p>\n";

}

?>


APPENDIX E

658

Figure E-1

A parse error message

Two important pieces of information are displayed with a parse error:

the line number in the document where the error occurred and a

description of the error. Note that the line number in an error mes-

sage is counted from the start of the document, not just from the start

of a script section.

Keep in mind that error messages only indicate the general location

of an error in a program, not the exact nature of an error. You cannot

assume that the line specified by an error message is the actual prob-

lem. The parse error message in Figure E-1 indicates that the error

occurred on line 15, because the PHP scripting engine searches to the

end of the script for the for() statement’s opening brace. However,

the real problem is that the opening brace should be the first charac-

ter following the closing parenthesis in the for() statement’s condi-

tional expression.

Fatal error messages are raised when a script contains a run-time

error that prevents it from executing. A typical fatal error message

occurs when a script attempts to call a function that does not exist.

Warning and

notice mes-

sages may

be sup-

pressed in

your PHP configuration.

The next section explains

how to enable them to

help you debug your

code.

Warning messages are raised for run-time errors that do not prevent

a script from executing. For example, a warning message occurs when

you attempt to divide a number by 0, or if you pass the wrong num-

ber of arguments to a function.

Notice messages are raised for potential run-time errors that do not

prevent a script from executing. Notices are less severe than warnings

and are typically raised when a script attempts to use an undeclared

variable.


APPENDIX E

Configuring the Way PHP

Displays Errors

The php.ini configuration file contains various directives that control

how the PHP scripting engine handles errors. PHP also includes vari-

ous functions that you can use to control error handling at run time.

659

Displaying Errors in the Web Browser

The php.ini configuration file contains two directives, print_errors

and print_startup_errors, which determine whether error mes-

sages are displayed in a Web browser. The print_errors directive

displays script error messages, whereas the print_startup_errors

directive displays errors that occur when PHP first starts. By

default, the print_errors directive is assigned a value of “On,” and

the print_startup_errors directive is assigned a value of “Off.”

Although displaying error messages is useful when you develop PHP

scripts, the PHP Group strongly recommends that you turn this fea-

ture off for scripts that run in production environments, and instead

save any errors in a log file. Hackers can use any displayed error mes-

sages to identify potential weaknesses in your Web site, so the PHP

Group also recommends that you only turn on the print_startup_

errors directive when debugging a script.

One piece of

information

that is avail-

able to hack-

ers is shown

in Figure E-1. The error

message shows the loca-

tion of the file in the serv-

er’s directory structure

and exposes the underly-

ing directory structure to

visitors.

Setting the Error Reporting Level

The error_reporting directive in the php.ini configuration file deter-

mines which types of error messages PHP should generate. Setting

the error reporting level can be useful in helping you debug your

scripts. However, keep in mind that changing the error messages

generated by PHP does not prevent errors from occurring; it only

prevents the error messages from being displayed in the Web browser

or written to a log file.

By default, the error_reporting directive is assigned a value of

E_ALL, which displays all errors, warnings, and notices in the Web

browser. You can also assign the directive the error levels listed in

Table E-1. Note that each error level can be set using either the con-

stant or integer listed in the table.


APPENDIX E

Constant

E_ERROR

E_WARNING

Integer Description

0

1

2

4

8

16

32

64

256

512

1024

2047

2048

Turns off all error reporting

Reports fatal run-time errors

Reports run-time warnings

Reports syntax errors

Reports run-time notices

Reports fatal errors that occur when PHP first starts

Reports warnings generated by the Zend Scripting Engine

Reports errors generated by the Zend Scripting Engine

Reports user-generated error messages

Reports user-generated warnings

Reports user-generated notices

Reports errors, warnings, and notices, with the exception

of E_STRICT notices

Reports strict notices, which are code recommendations

that ensure compatibility with PHP 5

660

E_PARSE

E_NOTICE

E_CORE_ERROR

E_COMPILE_WARNING

E_COMPILE_ERROR

E_USER_ERROR

E_USER_WARNING

E_USER_NOTICE

E_ALL

E_STRICT

Table E-1

Error reporting levels

To generate a combination of error levels, separate the levels assigned

to the error_reporting directive with the bitwise Or operator (|). For

example, the following statement specifies that PHP will only report

fatal and parse errors:

error_reporting = E_ERROR | E_PARSE

The bitwise

Xor operator

(^) can be

used in place

of the &~.

To specify that the E_ALL error should exclude certain types of mes-

sages, separate the levels with bitwise And (&) and Not operators (~).

The following statement specifies that PHP should report all errors

except run-time notices:

error_reporting = E_ALL &~ E_NOTICE

Instead of modifying the values assigned to the error_reporting

directive in the php.ini configuration file, you can use the error_

reporting() function to specify the messages to report in a particu-

lar script. Use the same bitwise operators to separate reporting levels

that you pass to the error_reporting() function. The following

statement uses the error_reporting() function so that PHP only

reports fatal and parse errors:

error_reporting(E_ERROR | E_PARSE);

The following statement uses the error_reporting() function to

specify that PHP should report all errors except run-time notices:

error_reporting(E_ALL &~ E_NOTICE);

APPENDIX E

To disable error messages for a particular script, place the error_

reporting() function at the beginning of a script section and pass to

it a value of 0, as follows:

error_reporting(0);

Logging Errors to a File

Remember that for security reasons, you should disable the display of

error messages for any scripts that run in a production environment.

Unless you work for a large company with separate development

and production systems, you will probably use the same server to

execute scripts in development and to execute scripts in production.

In this situation, it’s not feasible to use your php.ini configuration file

to enable and disable the print_errors and print_startup_errors

directives each time you want to work on a script. A better choice is

to log all errors to a text file.

PHP logs errors to a text file according to the error reporting level

assigned to the error_reporting directive in the php.ini configura-

tion file, or the level that you set for an individual script with the

error_reporting() function. The php.ini configuration file includes

several parameters for handling error logging, including the log_

errors and error_log directives. The log_errors directive deter-

mines whether PHP logs errors to a file; it is assigned a default value

of “Off.” The error_log directive identifies the text file where PHP

will log errors. You can assign either a path and filename or syslog

to the error_log directive. On UNIX and Linux systems, a value of

syslog specifies that PHP should use the syslog protocol to forward

the message to the system log file. On Windows systems, a value of

syslog forwards messages to the Event Log service.

The E_ALL

level does not

include the

E_STRICT

level. The

E_STRICT level always

needs to be explicitly

included.

661

Using Basic Debugging Techniques

Although error messages are valuable because they point out prob-

lems with your scripts, they cannot always help you identify the

source of a problem. This section discusses basic debugging tech-

niques that can help you locate problems in your PHP scripts.

Tracing Errors with echo Statements

When you cannot locate a bug in your program by using error mes-

sages or examining your code, or if you suspect a logic error (which

would not generate an error message), you must trace your code.

Tracing is the examination of individual statements in an executing


APPENDIX E

If you place

echo state-

ments in a

program to

trace a prob-

lem, place them at a dif-

ferent level of indentation

than other statements to

distinguish them from the

actual program.

662

program. The echo statement provides one of the most useful ways

to trace PHP code. You place an echo statement at different points in

your program and use it to display the contents of a variable or the

value returned from a function. An echo statement is especially useful

when you want to trace a bug in your program by analyzing a list of

values. Using this technique, you can monitor values as they change

during program execution. To trace the problem, you can place an

echo statement at the point in the program where you think the error

might be located.

If your program has multiple functions and functions calling func-

tions, it is often useful to insert echo statements that display

Entering function() and Leaving function() at the beginning

and end of each function, respectively. For functions that take input

parameters, it may help to display the values of the parameters in the

Entering function() string. For functions that return a value, it may

be helpful to display the return value, as in Leaving function(),

returning X. This will allow you to see when each function is called,

what values are passed, when each function returns, and what values

are returned.

When the main script or a function contains a long series of state-

ments, and you know that one of the statements is failing, you might

be able to find the culprit by adding an echo statement that displays

a simple sequence count between each statement, as in the following

code segment:

...

CustomFunctionA();

echo "<p>Step 5</p>\n";

CustomFunctionB();

echo "<p>Step 6</p>\n";

CustomFunctionC();

...

For arrays,

you can

use the

print_r()

function or the

var_dump() function in

place of the echo

statement.

If the Web browser displays “Step 5” but does not display “Step 6”,

then you know that CustomFunctionB() is causing the script to fail.

Using Comments to Locate Bugs

Another method of locating bugs in a PHP program is to transform

lines that might be causing problems into comments. In other words,

you can “comment out” problematic lines. This technique helps you

isolate the statement that is causing the error. In some cases, you

can comment out individual lines that might be causing an error, or

you can comment out all lines except the ones that you know work.

When you first receive an error message, start by commenting out

only the statement specified by the line number in the error message.


APPENDIX E

Save the script, and then open it again in your Web browser to see if

you receive another error. If you receive additional error messages,

comment out those statements as well. After you eliminate the error

messages, examine the statements you’ve commented out to find the

cause of the bug.

Often, you will see the error immediately and not need to comment

out code or use any other tracing technique. However, after you stare

at the same code for a long time, simple spelling errors are not always

easy to spot. Commenting out lines that you know are causing trouble

is a good technique for isolating and correcting even the simplest bugs.

Do not com-

ment out

statements

that span

multiple

lines or

statements on a line that

contains an opening or

closing brace. This intro-

duces further parsing

errors into your code.

The cause of

an error in a

particular

statement is

often the

result of an error in a

preceding line of code.

663

Analyzing Logic

At times, errors in PHP code stem from logic problems that are dif-

ficult to spot using tracing techniques. When you suspect that your

code contains logic errors, you must analyze each statement for

errors. For example, the following code contains a logic flaw that

prevents it from functioning correctly:

if (!isset($_POST['firstName']))

echo "<p>You must enter your first name!</p>\n";

exit();

echo "<p>Welcome to my Web site, " .

$_POST['firstName'] . "!</p>\n";

If you were to execute the preceding code, you would never

see the last echo statement, even if a value were assigned to the

$_POST['firstName'] variable. If you examine the if statement more

closely, you will see that it ends after it executes the echo statement.

The exit() statement following the variable declaration is not part

of the if structure, because the if statement does not include a

set of braces to enclose the lines it executes when the conditional

evaluation returns true. For this reason, the exit() statement

always executes, even when the user correctly assigns a value to the

$_POST['firstName'] variable. For the code to execute properly, the

if statement must include braces as follows:

if (!isset($_POST['firstName'])) {

echo "<p>You must enter your first name!</p>\n";

exit();

}

echo "<p>Welcome to my Web site, " .

$_POST['firstName'] . "!</p>\n";

The following for statement shows another example of an easily

overlooked logic error:

for ($Count = 1; $Count < 6; ++$Count);

echo "$Count<br />\n";


APPENDIX E

664

The preceding code should display the numbers 1 through 5 on

the screen. However, the line for ($Count = 1; $Count < 6;

++$Count); contains an ending semicolon, which marks the end of

the for loop. The loop executes five times and changes the value of

count to 6, but does nothing else because there are no statements

before its ending semicolon. The line echo "$Count<br />\n"; is a

separate statement that executes only once, displaying the number 6

on the screen. The code is syntactically correct, but does not function

as you anticipated. As you can see from these examples, it is easy to

overlook very minor logic errors in your code.

Formatting Code

It is much easier to review your code and analyze your logic by ensur-

ing that your code is properly formatted. By indenting your code

properly and using standard formatting for nested code blocks, you

can often locate a missing closing brace or a scope issue.

Commenting Code

Sometimes it is difficult to tell what a particular section of code is

supposed to do. By commenting those sections with a description

of the intended function, you can avoid trying to figure out what the

code is supposed to do and concentrate on verifying that the code

will accomplish what you intended. Comments also assist in marking

context switches, in which your script stops doing one task and starts

another.

Examining Your Code

When you use an editor like Notepad++, the editor automatically col-

or-codes your source code based on the file extension. This helps you

track down many types of syntax errors. For example, if the code after

a block comment is the same color as the block comment, you prob-

ably did not include the closing */ for the block comment. Another

common error is accidentally mixing opening and closing quotation

marks, such as using a single quotation mark at the beginning of a

string and a double quotation mark at the end of the string. When

this error occurs, the text will appear in the color used to highlight

strings until another single quotation mark occurs.

Examining the Script Output

The purpose of a PHP script is to generate XHTML code that is inter-

preted and displayed by a Web browser. When debugging, it is usually

better to see the actual XHTML code generated by the PHP script

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]