1. Trang chủ
  2. » Công Nghệ Thông Tin

Introduction to Bug Management

76 439 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Introduction to Bug Management
Tác giả Dejan Bosanac
Trường học PHP Architect
Chuyên ngành PHP Programming
Thể loại Magazine Article
Năm xuất bản 2003
Thành phố Markham
Định dạng
Số trang 76
Dung lượng 2,01 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Thisallows us to easily implement interface,abstract classes, and more inheritance capa-bilities, not to mention excellent error han-dling and the ability to better conform withuser-crea

Trang 1

See inside for details

Get Ready For

Creating a Reusable Menu

System with XML and PHP

Understand the need, the solutions,

and the processes

Installing Java for PHP

Demystify the beast

Advanced Database Features Exposed Come to terms with using the best tool for the job

Secure PHP Taking the key out

of the lock

Trang 2

Signup now and save $100.00!

Hurry, space is limited.

Visit us at www.phparch.com/cruise for more details.

March 1 st - March 5 th 2004

Andrei Zmievski - Andrei's Regex Clinic, James Cox - XML for the Masses, Wez Furlong -Extending PHP,Stuart Herbert - Safe and Advanced Error Handling in PHP5, Peter James -mod_rewrite: From Zero to Hero, George

Schlossnagle - Profiling PHP, Ilia Alshanetsky - Programming Web Services, John Coggeshall - Mastering PDFLib,

Jason Sweat - Data Caching Techniques

We’ve got you covered, from port to sockets.

Port Canaveral • Coco Cay • Nassau

Plus: Stream socket programming, debugging techniques, writing high-performance code,

Trang 3

F R O M T H E E X P E R T S AT D E V E L O P E R ’ S L I B R A RY .

M O R E T I T L E S F R O M D E V E L O P E R ’ S L I B R A R Y

Advanced PHP Programming

by George Schlossnagle

ISBN: 0-672-32561-6

$49.99 US • 500 pages

PHP and MySQL Web

Development, Second Edition

by Luke Welling and

While there are many books on

learning PHP and developing

small applications with it, there is

a serious lack of information on

scaling PHP for large-scale,

business-critical systems

Schlossnagle’s Advanced PHP

Programming fills that void,

demonstrating that PHP is ready

for enterprise Web applications

by showing the reader how to

develop PHP-based applications

for maximum performance, stability,

and extensibility

Essential references for programming professionals

php|architect readers, get 40% off books in the Developer’s Library

Visit www.developers-library.comand add the books of yourchoosing to your shopping cart Upon check-out, enter thecoupon code PHPARCH03

to receive discount Offer validthrough 12/31/03

Trang 4

69 Tips & Tricks

By John W Holmes

73 Bits & Pieces

Real Interesting Stuff.

76 exit(0);

Buy vs Build

By Marco Tabini

9 Secure PHP Coding

by David Jorm and Jody Melbourne

19 Introduction to Bug Management

Trang 5

*By signing this order form, you agree that we will charge your account in Canadian dollars for the

“CAD” amounts indicated above Because of fluctuations in the exchange rates, the actual amount charged in your currency on your credit card statement may vary slightly †Limited time offer extended to September 30th, 2003.

Choose a Subscription type:

Canada/USA $ 81.59 $67.99 CAD ($59.99 $49.99 US*)International Surface $108.99 $94.99 CAD ($79.99 $69.99 US*)International Air $122.99 $108.99 CAD ($89.99 $79.99 US*)

Your charge will appear under the name "Marco Tabini & Associates, Inc." Please allow up to 4 to 6 weeks for your subscription to be established and your first issue to be mailed to you.

*US Pricing is approximate and for illustration purposes only.

php|architect Subscription Dept.

VISA Mastercard American Express

Credit Card Number:

Expiration Date:

E-mail address:

Phone Number:

Buy now and save $10 off the price of any subscription†

Visit: http://www.phparch.com/print for more information or to subscribe online.

Signature: Date:

php|architect

The Magazine For PHP Professionals

Existing subscribers

can upgrade to

the Print edition

and save!

Login to your account

for more details.

NEW!

Trang 6

PublisherMarco TabiniEditor-in-ChiefPeter James

petej@phparch.com

Editor-at-LargeBrian K Jones

brian@phparch.com

Editorial TeamArbi ArzoumaniPeter JamesBrian JonesEddie PelokeGraphics & LayoutArbi Arzoumani, Hammed Malik,

Marina ZlatogorovManaging EditorEmanuela CorsoDirector of Marketing

J Scott Johnson

scott@phparch.com

Account ExecutiveShelley Johnston

shelley@phparch.com

AuthorsDejan Bosanac, David Jorm, Dave Palmer, Davor Pleskina, Allessandro Sfondrini, Leon Vismer

php|architect (ISSN 1705-1142) is published twelve times a year

by Marco Tabini & Associates, Inc., P.O Box 3342, Markham, ON

L3R 6G6, Canada

Although all possible care has been placed in assuring the racy of the contents of this magazine, including all associated source code, listings and figures, the publisher assumes no responsibilities with regards of use of the information contained herein or in all associated material.

accu-Contact Information:

General mailbox: info@phparch.com Editorial: editors@phparch.com Subscriptions: subs@phparch.com Sales & advertising: sales@phparch.com Technical support: support@phparch.com

In the relatively short time that I’ve been with

php|architect (about six months now), I’ve

seen a lot of our magazine content cross my

(very messy) desk In that same time period,

I’ve been committed to gobbling up any and all

PHP content gracing the pages of other

publi-cations and developer sites I now feel that I

am qualified to state an opinion:

We have great content

Our authors consistently dig deep into their

top-ics, bringing you their practical experience,

exam-ples, and well-written explanations Their

enthusi-asm for their articles shines through, and brings

warmth and community to the pages of

php|architect every month

We constantly demand the best from our

authors, and they, in turn, demand the best from

us The php|architect editorial team prides itself

on being transparent, and I believe that authors

enjoy writing for us because of it (maybe this

helps explain why there are only two new

authors and four return authors this month) By

transparent, I mean that we are honest and up

front with them, as well as ourselves We view

our authors as collaborators and team members,

never as service providers or vendors We are

easy to work with, and are eager to bend over

backward to help if we can see that an honest

effort is being made

Through all of this we never compromise our

integrity or settle for second best Really, though,

how could we? We serve one of the greatest

soft-ware communities in the world!

This brings me to my next point I am

absolutely ecstatic to have been bestowed the

honor of directing the editorial path of

php|architect Our authors, our readers, and

our editorial team have all worked hard to build

an excellent resource that brings you the best

that the PHP world has to offer each and every

month

The hardest part of my new role here at php|a

will probably be trying to fill Brian’s shoes – he’s

got really big feet.* Brian has worked

extreme-ly hard to foster long-term relationships with

our authors, and I will be working feverishly to

continue to build and maintain that community,

as well as various other initiatives on the front

and back-end of the publication

But don’t worry, I’m still sleeping four hours a

night

I sincerely hope you enjoy this month’s issue

People lost hair, sleep, and teeth over it And, as

always, if you see anything you particularly like or

don’t like in our magazine this month, I strongly

encourage you to send us your feedback at

Trang 7

editors@phparch.com Even fan letters firmly

stating that “You suck.” will be warmly accepted, as

they help to break up the large amounts of spam

that we all get from that address

* Actually, I’ve never physically seen Brian, or

Brian’s shoes I’m pretty sure I can smell them,

though

EDITORIAL

When in Rome

Go to PHP Day 2003!

The first conference dedicated exclusively

to the Italian PHP Community, called PHPDay 2003, will take place on October 24,

2003 in Rome at the Universita’ Tor Vergata.The program includes several speakers fromthe Italian technical community, and focuses

on the theme of interface development, aswell as a few tutorials to get the beginners upand running Most of all, PHP Day revolvesaround the concept of providing the PHP com-munity with an opportunity to meet andexchange their experiences

If you live in Italy, this is a great opportunity

to meet your fellow PHP enthusiasts If youdon’t live in Italy this might be the perfectexcuse for that long-postponed vacation!

For more information on PHP Day, visithttp://www.phpday.it or mail the organizers

at staff@phpday.it

PHP 4.3.3

release of PHP 4.3.3

This release contains a

large number of bug fixes

and it is recommended that

all users ugrade to this

• and much more

Visit to php.net download or view the change log

Apache Cocoon 2.1

Apache Cocoon is a web development

frame-work built around the concepts of separation ofconcerns (making sure people can interact andcollaborate on a project, without stepping oneach other toes) and component-based webdevelopment

Cocoon implements these concepts around thenotion of ‘component pipelines’, each component

on the pipeline specializing on a particular tion This makes it possible to use a Lego(tm)-likeapproach in building web solutions, hookingtogether components into pipelines without anyrequired programming

opera-Cocoon is “web glue for your web applicationdevelopment needs” It is a glue that keeps con-cerns separate and allows parallel evolution of thetwo sides, improving development pace andreducing the chance of conflicts

Cocoon has a PHP Generator which is not

includ-ed in the binary distribution but can be found at:

Trang 8

ZEND Studio 3.0.0 Beta

the Zend Studio 3.0.0 Beta for Windows and Mac

The latest release includes:

• Code Profiler – Determine which scripts are

slowing down your project so you can focus

your time on improving their performance

• One-click debugging and profiling tool –

Direct debugging and profiling of web

pages directly from your browser

• Code Analyzer – Pinpoint messy code,

allowing you to write cleaner more correct

code

• Highlight syntax errors – Write clean PHP

code while you are typing

• Support for PHP 5.0 – Including syntax

highlighting, code completion, file and

proj-ect inspproj-ectors

• Dramatic performance improvements

• Code Completion improvements –

Including improve speed, recognized

con-stants, and new functions arguments

view and much more

Get more information or download from

Zend.com

PhpBB 2.0.6

The phpBB Group is pleased to announce the

release of phpBB 2.0.6 the “phew, it’s way to hot

to be furry” Edition This release had been made

to fix a number of potential security related issues

and more annoying bugs Work continues on 2.2.0

and another 2.0.x release is not planned except

where critical issues arise

phpBB.com describes phpBB as:

” a high powered, fully scalable, and highly

customisable open-source bulletin board

package phpBB has a user-friendly

inter-face, simple and straightforward

administra-tion panel, and helpful FAQ Based on the

powerful PHP server language and your

choice of MySQL, MS-SQL, PostgreSQL or

Access/ODBC database servers, phpBB isthe ideal free community solution for allweb sites.”

phpBB strongly advises all users to upgrade

Get more information for phpBB.com

“Japha is an attempt to bring the main classes

in the Java 1.4.1 (soon to be 1.4.2, time ing) to PHP for use in everyday programs We

allow-do this using the syntax that has been madecommon with the new releases of PHP 5 Thisallows us to easily implement interface,abstract classes, and more inheritance capa-bilities, not to mention excellent error han-dling and the ability to better conform withuser-created data types.”

Get more information or download the latestversion from Japha.xzon.net

LightBulb 4.79

LightBulb (formerly EzSDK) is a PHP SDK whichincludes a PHP source code generator, a library ofPHP Classes, and an application environment con-sisting of premade supporting modules The mod-ules handle user application and data accesssecurity, DB compatibility, a built-in GUI interfacewith an interactive desktop and more Check outthis month’s product review for more information.This release contains changes to the spellchecking features

Spell checking of user data is now an ent, interactive user option throughout thesystem Developers are able to utilize thespell check features throughout every appli-cation developed without writing any sourcecode to facilitate this

inher-Get more information or view the demo at

ezsdk.com

php|a

Trang 9

Web applications, by their very nature,

have a broad exposure to remote ers and a set of potential vulnerabilities

attack-as rich attack-as the languages and protocols from

which they are born Web applications are

han-dling an ever-growing list of business functions,

and the code driving them must be paid due

attention with regard not only to performance

and stability, but also to security

This article is aimed at providing a concise

list-ing and discussion of the most common

vulnera-bilities that exist in PHP web applications This

vulnerability listing is used at the end of the

arti-cle as the basis for developing coding and code

audit/testing methodologies which can be

applied to any PHP web application

Note that, for the sake of brevity, only the most

common and severe vulnerabilities have been

listed and that vulnerabilities outside the scope

of PHP code – such as those which may exist in a

web server or PHP itself – are not covered by this

article

SQL Injection

An SQL injection vulnerability can rear its uglyhead when user-submitted variables are used toassemble SQL queries on the server side withoutsufficient input validation The underlying SQLstatement can be manipulated or additional SQLstatements injected by an attacker SQL Injection

is one of the most common web application nerabilities, but does not affect PHP code asmuch as other languages, mostly due to PHP’sautomatic character escaping and built-in valida-tion functions A sample vulnerability is shown inListing 1

vul-A sample attack on that vulnerability mightlook like the following:

Note that the value being passed to artid is aurlencoded version of “0 or ArticleID <> 0”.Making a call to the link above would cause thefollowing value to be assigned to $ssql and exe-

http://www.server.com/listing1.php?artid=

0%20or%20ArticleID%20<>%200

NOTE: All examples use the HTTP GET

method so that attacks can be easily

illus-trated as URIs Keep in mind that using POST

is no defence; the variables are simply in the

HTTP message body rather than the query

string component of the URI From a

theoret-ical perspective, at least, POST variables are

just as easy to manipulate as GET variables.

REQUIREMENTS

Trang 10

cuted on the SQL server:

Some database servers also allow multiple SQL

statements to be concatenated using a

semi-colon (;) as a separator In that case, the

follow-ing attack could be used:

In this case, the urlencoded value being passed

into artid is “0; DROP TABLE Articles” You can

imagine the problems that this might cause

The key to protecting code against SQL

injec-tion attacks – also key for protecting against

most web application vulnerabilities – is

rigor-ous input validation PHP can automatically

escape some characters, such as apostrophes

(‘), providing protection against attacks

involv-ing those characters, but this is not sufficient

immunity All user-controlled variables used to

construct SQL statements or other commands

must be stripped of any content that may alter

the effects of the query For numeric inputs,

either verify that the value is indeed numeric,

or make it numeric using settype() For

non-numeric inputs, run the variable through

addslashes() or addcslashes() before using it

to construct a query The vulnerable example

above is patched in Listing 2 More information

on patching against SQL injection is available at

In testing for SQL injection, the blackbox tester

studies application inputs and attempts to insert

special characters (such as commas, apostrophes,

semicolons, quotation marks, and equal signs) or

SQL keywords (AND, OR, SELECT, INSERT, etc)

With many of the popular backends,

informa-tive error pages are displayed by default, which

can often give clues to the underlying SQL query

in use For example, asking for

instead of

could return a telltale error like this one:

It is evident from this response that the valuefor itemID is being used directly (without any val-idation) within an SQL query

PHP Code InjectionWhen user-defined inputs form the file pathparameters used to call include(), fopen() orother similar functions, there are several possi-bilities for exploitation The first, PHP code injec-tion, is based on manipulating the input to

include() to run your own PHP code The ond, path traversal, is based on manipulating theinput to include()or fopen()to display files orcreate an open proxy Note that both of thesebugs rely on the same basic problem and overlapsomewhat

sec-PHP code injection is similar to SQL injection,but involves native PHP code being injected bythe user rather than SQL This is made possiblewhen the code makes use of the include()func-tion The include() function will accept a filename or URI (if the appropriate wrapper isinstalled) and include the contents of theresource as part of the PHP program This is fre-quently used as a means of keeping libraries ofcode separate, and applications more modular,

mySQL error with query SELECT myitem FROM shop_item WHERE itemid=123’;:

You have an error in your SQL syntax near

‘’’ at line 1

http://example.com/items.php?itemID=123 http://example.com/items.php?itemID=123’

http://www.server.com/listing1.php?artid=

0;%20DROP%20TABLE%20Articles

SELECT ArticleContents FROM Articles

WHERE ArticleID = 0 OR ArticleID <> 0

1 <?php

2

3 // sqlinject.php

4 $ssql = ”SELECT ArticleContents FROM Articles WHERE

ArticleID = “ $_GET [ ‘artid’ ];

5 $conn = mysql_connect ( ‘127.0.0.1’ , ‘dbuser’ , ‘dbpw’ );

6 $res = mysql_query ( $ssql , $conn );

7 while ( $resarr = mysql_fetch_row ( $res )) {

8 echo “<span id=\”article\”>” $resarr [ ]

7 $conn = mysql_connect ( ‘127.0.0.1’ , ‘dbuser’ , ‘dbpw’ );

8 $res = mysql_query ( $ssql , $conn );

9 while ( $resarr = mysql_fetch_row ( $res )) {

10 echo “<span id=\”article\”>” $resarr [ ]

Trang 11

calling include() to load needed functions at

runtime or ‘on demand’, but it’s also frequently

mis-used to include local text files, or worse,

remote data from a URI PHP code injection is

achieved by placing malicious PHP code inside a

resource which is run through include(), or

finding a way to have the include() call load

something unintended by the application

devel-oper A sample vulnerability is shown in Listing

3

A sample attack on that vulnerability might

look like the following:

Making a call to the above link would cause the

contents of www.hacker.com/phpinjection.phpto

be included into the program and executed

local-ly This page could output any malicious code the

attacker can conjure up

The primary strategy for defending against

code injection attacks is to use include()

appro-priately Having URI file wrappers enabled is

gen-erally a security liability and if your site does not

explicitly use them, they should be disabled If it

is necessary to have user manipulable variables

run through include(), ensure that they are

properly validated Listing 3 is patched in Listing

4

When trying to locate these vulnerabilities via

blackbox testing, the tester would attempt to

inject file and directory special characters (such

as and /) into variables and see if this elicits a

response from the application which might aid

an attack Imagine that a regular

(non-mali-cious) URL looks like this:

Let’s look at what we get if we change the

query string a little, as follows:

The response from the application might besome telltale warnings, like so:

This response indicates that the value of the

‘in’ variable is being used within an include()

call In this case, an attacker would be able tosubmit a request such as:

to open (include) any readable file

Path TraversalVery closely related to PHP code injection is pathtraversal Although Listing 4 protects againstPHP code injection, it applies no input validation

to the page GET variable, allowing the user toenter not just a file name but an absolute path.This can allow an attacker to view any file thatthe web server has permission to read If URIwrappers were enabled, it would also allow anattacker to use the site as an open proxy to view

http://example.com/main.php?in= / / /

/etc/passwd

Warning: main(./ /test.inc) [function.main]: failed to create stream:

No such file or directory in main.php on line 102

Warning: main() [function.main]: Failed opening ‘./ /test.inc’ for inclusion (include_path=’.:’) in main.php on line 102

4 if isset( $_GET [ ‘page’ ])

5 include( $_GET [ ‘page’ ]);

3 //phpcodeinjectpatched.php

4 if isset( $_GET [ ‘page’ ]) {

5 $fp = fopen ( $_GET [ ‘page’ ], ‘rb’ );

3 //pathtraversal.php

4 if isset( $_GET [ ‘page’ ]) {

5 $fp = fopen ( $_GET [ ‘page’ ], ‘rb’ );

Trang 12

other resources on the web A sample

vulnera-bility is shown in Listing 5

A sample attack on that vulnerability might

look like the following:

Calling the above link might cause the contents

of /etc/passwd to be returned to the attacker —

obviously not what the script was supposed to

do! If URI wrappers were enabled, the following

attack could also be used:

This would cause the web server to source the

contents of the URI www.phparch.com and

return them to the attacker, effectively working

as an open proxy Oh, what we wouldn’t do for

our daily dose of PHP goodness!

The key to defending against path traversal

attacks is, once again, input validation Ideally,

all files that the script is serving can be

numeri-cally sequenced, requiring only a numeric input

of the file number from the user A patched

ver-sion of Listing 5 using this method is shown in

Listing 6

Alternatively, the page variable can be

stripped of all characters which may allow a user

to enter an absolute path or URI A patched

ver-sion of Listing 5 using this method is shown in

Listing 7

These vulnerabilities can often be located

through blackbox testing of the application The

tester would attempt to inject file and directory

special characters (such as and /) into variables

and see if this returns (or attempts to return)

arbitrary files Imagine that a regular

(non-mali-cious) URL looks like this:

To test for path traversal, we might use the

fol-lowing URL’s:

If the tester receives a ‘File not found’ or

‘Cannot open’ error, it may simply be a matter of

adjusting paths or increasing the amount of

tra-versal characters ( /) fopen() and include()

error messages are generally very informative indescribing the error, and can give the tester allthe information needed to correctly manipulatethis request

Trusted User Manipulable Values

A major problem with the web application ronment and the advanced tools used within it,

envi-of which PHP is only one, is the fact that theyhide the source of some inputs from the develop-

er For example, PHP will expose the contents of

a form field, GET variable or POST variable criminately as a variable with the same name asthe field or HTTP variable Developers come torely on this feature and can fail to considerwhether a trusted variable, such as the value of

indis-a product or nindis-ame of indis-a file, comes from indis-a sourcewhich cannot be manipulated by an attacker Theclassic example is hidden form fields used tocarry session-related variables, such as thename and value for products on an e-commercesite The developer is relying on the notion thatsince he has set these values, he will read themback in from the subsequent form, unchanged.But when a form is submitted, the contents ofthe form fields are simply passed to the resource

in the FORM tag’s ACTION attribute as either GET

or POST variables, as specified by the METHODattribute An attacker can then change the price

of products by making his own form carrying thedesired values, or manipulating GET/POST vari-

http://example.com/viewfile.php?cat=/etc

/motd http://example.com/viewfile.php?cat= /

/ / /etc/passwd http://example.com/viewfile.php?cat=users

3 //pathtraversalpatched1.php

4 if is_numeric ( $_GET [ ‘page’ ]) {

5 $fp = fopen ( ‘/var/www/files/file’ $_GET [ ‘page’ ]

3 //pathtraversalpatched2.php

4 if isset( $_GET [ ‘page’ ]) {

5 $fp = fopen ( stripfilename ( $_GET [ ‘page’ ]), ‘rb’ );

11 function stripfilename ( $filename ) {

12 $filename = str_replace ( ‘.’ , ‘’ , $filename );

13 return str_replace ( ‘/’ , ‘’ , $filename );

14 }

15

16 ?>

Listing 7

Trang 13

ables manually A sample vulnerability is shown

in Listings 8 (the HTML form) and 9 (the form

handler)

A sample attack on that vulnerability might

look like the following:

Calling the link above allows an attacker to

successfully place an order, using a valid credit

card, but with a price of the attacker’s choosing,

in this case $1 The developer is presuming that

the only way his form handler will be accessed is

via Listing 8, where the price value is set by a

PHP variable Were POST being used rather than

GET, an attacker could construct an HTML

docu-ment, as shown in Listing 10, and place the order

for $1 by simply submitting the new form

Trusted variable vulnerabilities can be avoided

by setting session-related variables appropriately,

using sessions or cookies (although both of these

have some, albeit lesser, problems in their own

right) A preferable solution would be to always

reference the price from a database on the server

side and carry a productid variable in a PHP

ses-sion or browser cookie Both of the previous

vul-nerabilities are patched with Listings 11 and 12

The blackbox tester examines all available

source pages for evidence of HIDDEN or

dynami-cally-generated variables The tester saves a copy

of the form page locally and manipulates these

variables, loads the form page into a browser and

submits the modified request In many cases, the

tester may not be able to determine if the

modi-fied values have been accepted unless they are

displayed on a subsequent page (such as in the

Checkout page of a shopping-cart application.)

Weak AuthenticationDespite the widespread gospel that clear-textauthentication credentials are a cardinal sin andthat passwords should conform to minimum com-plexity rules, these fundamentals of secure pro-gramming are frequently not applied in the webapplication world HTTP includes two standardauthentication mechanisms: basic and digest.Both mechanisms operate as a series of HTTPexchanges with a demand for authenticationissued by the server in an HTTP header, followed

by a repeated request from the client, includingauthentication credentials in another HTTP header.The primary difference is that basic authenticationuses clear text and is simply base64 encoded,while digest is encrypted using a nonce (time sen-

3 <form action=”trustedvaluesformhandler.php” method=”get”>

4 <input type=”hidden” name=”price” value=” <?=$price?> ”>

5 Credit Card #:<input type=”text” size=”10” name=”cc”>

3 //trustedvaluesformhandler.php

4 if (!isset( $_GET [ ‘price’ ]) || !isset( $_GET [ ‘cc’ ]))

5 die;

6 mail ( “billing@server.com” , “New Bill” , “Bill card “

$_GET [ ‘cc’ ] “\nFor amount: \$”

3 <input type=”hidden” name=”price” value=”1”>

4 <input type=”hidden” name=”cc” value=”5353167819823”>

5 <input type=”submit” value=”Order Product”>

6 </form>

7 </html>

Listing 10

1 <?php 2

3 //trustedvaluesformhandlerpatched.php

4 session_start ();

5 if (!isset( $_SESSION [ ‘productid’ ]) || !isset( $_GET [ ‘cc’ ]))

6 die;

7 // Call me paranoid, but sanity check session variable

8 if (! isnumeric ( $_SESSION [ ‘productid’ ]))

9 die;

10 $ssql = ”SELECT Price FROM Products WHERE ProductID = “

$_SESSION [ ‘productid’ ];

11 $conn = mysql_connect ( ‘127.0.0.1’ , ‘dbuser’ , ‘dbpw’ );

12 $res = mysql_query ( $ssql , $conn );

13 $resarr = mysql_fetch_row ( $res );

14 mysql_close ( $conn );

15 mail ( “billing@server.com” , “New Bill” , “Bill card “

$_GET [ ‘cc’ ] “\nFor amount: \$” $resarr [ ]);

16 echo “Order placed\n” ;

17

18 ?>

Listing 12

1 <?php 2

10 <input type=”hidden” name=”price” value=” <?=$price?> ”>

11 Credit Card #:<input type=”text” size=”10” name=”cc”>

Trang 14

sitive value) issued by the server as a key

Basic authentication can be set up easily by using

PHP’s header() function to issue the required

header The $_SERVER[‘PHP_AUTH_USER’] and

$_SERVER[‘PHP_AUTH_PW’] variables are created

by PHP when a request has included authentication

credentials This is, unfortunately, promoted by

many tutorials on PHP programming The main

alternative to basic HTTP authentication is to have

a custom solution where a session id or cookie is

issued to the client once it has successfully

authen-ticated – this token then being checked with each

subsequent request for a protected resource This

relies on the developer correctly enforcing

pass-word complexity rules and is vulnerable to replay

attacks A sample vulnerability is shown in Listing

13 (allowing a weak password to be set) and 14

(doing effectively clear-text authentication)

Lack of complexity rules can make you

vulnera-ble to brute force attacks, because with short and

common passwords little key space will need to be

exhausted before an attacker finds his way in

Brute force attacks most commonly work either

from a dictionary file of common words, or in an

incremental mode trying every possible string

Sometimes a hybrid of the two is used, attaching

short incremental suffixes and prefixes to

com-mon words Listing 15 is an example of an

incre-mental-mode brute-forcing tool

Basic HTTP authentication is vulnerable only to

third party attack, where an attacker is sniffing

or otherwise intercepting the site’s

communica-tion and extracting the clear text authenticacommunica-tion

credentials No sample attack is provided for

extracting clear text credentials

There is no patch, as such, for the use of basic

HTTP authentication The point was merely toillustrate that its use, without SSL or some otherform of encryption, is a security liability

Password complexity rules, however, can beapplied in a variety of ways PHP functions areavailable to utilise the CrackLib library to checkthe strength of passwords The strength is deter-mined by length, use of upper and lower caseand dictionary checks If CrackLib is not available

or you wish to enforce custom business rules forpassword strength, writing your own implemen-tation is simple Listing 13 is patched using acustom password strength test in Listing 16

To identify these vulnerabilities, the blackboxtester must first identify the authenticationmethod in use If basic HTTP authentication is

4 if ( $PHP_AUTH_USER != “user” || $PHP_AUTH_PW != ”pass” ) {

5 header ( ‘WWW-Authenticate: Basic realm=”server.com”’ );

28 echo “String ‘“ $str “‘ works as password\n” ;

29 if ( $ord_arr [ sizeof ( $ord_arr )- 1 ] == $num_chars ) {

44 for ( $i = sizeof ( $ord_arr )- 1 ; $i >= 0 ; $i —) {

45 if ( $ord_arr [ $i ] == $num_chars &&

Trang 15

being used, the tester can attempt to

brute-force a valid login and password pair – in

most cases, account lockout restrictions are not

enforced

There are many tools available online to test the

strength of basic HTTP authentication One of the

more popular password cracking tools is Cain&Abel

– available from http://www.oxid.it/cain.html

Poorly-Applied Authentication

Authentication mechanisms can sometimes fail

to cover every access method for a resource and

restrict access accordingly The classic example

is a menu driven by permissions associated with

authentication credentials providing access to a

list of resources the user is allowed to view The

resources themselves, however, do not require

authentication credentials and rely on the notion

that they are hidden unless access to them is

provided via a menu This is security through

obscurity, and is a major flaw A recent

high-pro-file example of this problem is an Australian

Taxation Office site where a user provided

detailed credentials to authenticate their

identi-ty and were then allowed to view details

associ-ated with their Tax File Number The page

pro-viding this access simply accepted the Tax File

Number as a GET variable, such as:

An attacker could simply plug in another TFN to

view its details:

A sample vulnerability is shown in Listings 17

(the menu) and 18 (the resource)

A sample attack on that vulnerability might

look like the following:

By accessing the above URI, an attacker can

bypass the authentication applied by Listing 17,

and go straight to the resource (Listing 18) it was

designed to provide access to

The best strategy to avoid these kinds of

prob-lems is to apply authentication at every individual

resource, so it can never be bypassed In the

pro-duction world, your authentication would never be

as simple as the ‘if’ test used in Listing 17, so a

con-venient technique is to create an authentication

class and include it with every resource These nerabilities are patched by Listings 19 (the authen-tication class) and 20 (the protected resource)

vul-Authentication and logic flaws in applicationscan sometimes be located via blackbox testingmethods The tester, using valid credentials,authenticates to the application and interacts as anormal user At every point beyond the initialauthentication routine, the tester locates any GETand POST variables, manipulates them using validdata, and examines the output Imagine that a

5 if ( $_GET [ ‘un’ ] == ‘user’ && $_GET [ ‘pw’ ] == ‘pass’ ) {

6 echo “<form>\n”

7 “<input type=\”button\” value=\”Resource 1\”

8 onClick=\”location.replace (‘poorauthresource.php?res=1’);\”>\n<br>\n”

9 “<input type=\”button\” value=\”Resource 2\”

Trang 16

regular (non-malicious) URI looks like this:

A blackbox tester might try the following:

In the above example, the user might expect to

receive an ‘unauthorized’ error message when

attempting to submit an alternate ‘startpg’

vari-able If authentication has only been applied to the

application portal page (and subsequent requests

are not being re-authenticated) an attacker may

be able to request arbitrary start pages

Cross-Site Scripting

Many sites, such as message forums, allow a user

to enter content and post it to the site This is

usu-ally handled using an SQL database to store

mes-sages and PHP code to add and render posts on

demand If the contents of these messages are not

stripped for HTML tags and Javascript code, an

attacker can effectively inject client-side scripts

which will be run under the security context of the

message forum This vulnerability, however, is not

limited to message forums Any site where the

contents of user-defined variables such as

GET/POST variables, HTTP headers or cookies will

form part of the page returned can be vulnerable

to cross-site scripting, or XSS As an example of

XSS outside of a classic message forum example,

take the following URI:

In this case, the q variable would be set to

“<script>alert(document.cookie);</script>”

This will run the Javascript code

alert(docu-ment.cookie); within the security context the

user has set for ninemsn.com.au This will

expose the user’s cookie for the site On a

mes-sage board this could well include a session id

token which could be replayed to hijack their

ses-sion This could then be logged to a remote

cap-ture application using Javascript code such as:

A sample vulnerability is shown in Listing 21 Asample attack on that vulnerability might looklike the following:

This would cause the “query” GET variable tocontain:

Accessing the above URL would causewww.porn.com to be opened in a new window

100 times by a Javascript-enabled browser

Defending against XSS is not just simply a matter

of stripping special characters as with SQL tion Not accepting certain input may limit the func-

injec-<script>for (i=0;i<100;i++;) { window.open(‘http://www.porn.com/’);

8 function auth ( $un , $pw ) {

9 if ( $un == ‘user’ && $pw == ‘pass’ )

10 $this -> isvalid = true ;

Trang 17

tionality of the site A better strategy is to parse

user-defined inputs after they have been used by

the PHP script, but before being returned as part of

the response, to replace ‘<’ and ‘>’ characters with

‘&lt;’ and ‘&gt;’ respectively This will prevent

‘<script>’ or other tags from being injected Listing

21 is patched using this technique in Listing 22

Cross-site scripting vulnerabilities are generally

quite easy to locate using blackbox testing

meth-ods The tester examines all GET and POST

vari-ables to determine if any of these values are being

returned within page outputs In the example

below, the tester can safely assume that the

con-tents of the Title variable will be used somewhere

within the returned page Imagine that a regular

(non-malicious) URI looks like this:

The tester inserts HTML special characters (<>)

into the Title variable and resubmits the request

If the injected HTML can be found within the

returned page, then this application is vulnerable

to cross-site scripting In this case, if the Title

value is being used directly between <title> and

</title> tags, without filtering of <> characters,

additional HTML and Javascript can be injected

into the returned page

Environment Information Disclosure

By default, PHP displays all warnings and errors

These frequently contain verbose information

per-taining to the operating environment, such as file

paths, database credentials and configuration

details A sample vulnerability is shown in Listing 23

A sample attack on that vulnerability mightlook like the following:

If an attacker runs the above URI when thedatabase server is down and/mnt/data/file1.txt is not available, the fol-lowing error (with HTML removed) will be given

by PHP:

This discloses both the name of the databaseserver and the path from which the script is read-ing files Although this does not open the site toany specific attack, it is not good security prac-tice to disclose this kind of information

The best strategy to prevent this is to disableerror reporting on production sites and reserve itfor development use This is best implemented

in php.ini but is illustrated using the

error_reporting()function in Listing 24

The blackbox tester inserts special charactersinto all identified GET and POST variables in anattempt to elicit exception conditions from theapplication Errors from failed include(),

popen(), fopen() and DB-related calls can beextremely informative and may assist the tester

in identifying further vulnerabilities Imaginethat a regular (non-malicious) URI looks like this:

Let’s look at what we get if we change thequery string a little, as follows:

Warning: MySQL Connection Failed:

Unknown MySQL Server Host er.com’ (2) in C:\PHP\phparch\env.php on line 2

‘dbserver.serv-Warning: fopen(“/mnt/data/file1.txt”,

“rb”) - No such file or directory in C:\PHP\phparch\env.php on line 3 http://www.server.com/listing23.php

4 $q = str_replace ( ‘<’ , ‘&lt;’ , $_GET [ ‘query’ ]);

5 $q = str_replace ( ‘>’ , ‘&gt;’ , $_GET [ ‘query’ ]);

6 echo “You searched for “ $q ;

Trang 18

The server’s response could be as follows:

Secure Coding Methodology

The key to coding secure web applications in PHP

is to be aware of the potential flaws that your code

may be vulnerable to, and be attentive in

prevent-ing these flaws throughout the entire

develop-ment process Too often security is an

after-thought or added feature The most secure code

is written with security in mind from the word ‘go’

Testing Methodology

The blackbox testing method is where a security

professional attempts to expose flaws in an

application The term ‘blackbox’ refers to the

closed-source or proprietary application, and the

process of manipulating known inputs and

ana-lyzing outputs from the application

In blackbox testing PHP code, the tester

exam-ines the application and identifies all of the

expected GET and POST variables, including

hid-den and dynamically-generated variables These

variables are then manipulated using potentially

“unexpected” values – such as special characters

and type-mismatched or oversized requests In

most cases, the PHP applications’ expected inputs

can be identified by reading all available HTML

source pages, and/or capturing and decoding

valid requests

As an example, examine the following URI:

In the above example, the GET variables that

should be manipulated and tested are ID, title

and lang

As another example, examine the form in

Listing 25 Here, the POST variables to be

test-ed are ‘sid’, ‘listid’ and ‘usermail’

The tester inserts special characters into each

of these inputs, and submits the request Output

is analyzed to determine if the application

han-dled the input correctly, or if some unexpected

error has occurred

Manipulated POST variables can be submitted

using a command-line tool such as lynx or curl,

or a copy of the form input page can be saved

and modified locally Manipulated GET variablescan be submitted using a regular browser

Unexpected behavior may take the form ofhalf-loaded or blank pages, or a redirect to afront page If the application displays an errormessage, the tester can determine if it is vulner-able to any of the common PHP coding errorsdetailed in this article

ConclusionWeb applications are, in security terms, a differentball game from conventional applications Thecommunication protocols, server-side applicationcode and client-side presentation code combine toform a development environment in which bugscan make use of problems in various components

of the technology simultaneously To compoundthis problem, web technology was originallydesigned to handle the public dissemination ofmarkup documents, not the development ofsecure applications This is slowly being rectified,but the developer must remain astute to securityconcerns if he is to produce secure applications.Hopefully what has been outlined above can assist

in the creation of more secure web applications

Warning: MySQL Connection Failed: Unknown

MySQL Server Host ‘sql.example.com’ (2)

in /www.example.com/cgi-bin/index.php on

line 45

Click HERE To Discuss This Article http://forums.phparch.com/44

David works as a document imaging and OCR programmer for a small Australian company He spends his spare time writing PHP code and studying environmental science

1 <form action=”subscribe.php” method=”POST”>

2 <input type=”hidden” name=”sid” value=”666”>

3 <input type=”hidden” name=”listid” value=”1024”>

4 Email:<input type=”text” size=”100” name=”usermail”>

5 <input type=”submit” value=”subscribe”>

6 </form>

Listing 25

Trang 19

What is a bug?

It all started in 1945 at Harvard University, while

testing the Mark II Aiken Relay Calculator for

mal-function A moth was found trapped between two

electrical relays Operators removed the moth and

entered the log entry “First actual case of bug being

found.” They said that they had “debugged” the

machine and the term “debugging a computer

pro-gram” was introduced

Anyone who has ever used any kind of software

is familiar with the term “bug” But before we

pro-ceed further with our story, we should make it

clear what we mean by this term Classic definition

of the bug is that it is an error in software code that

causes the program to malfunction We must be

careful with this, however, because it is very

close-ly related to the requirements of our project We

can’t tell that something is not working properly

unless we know the desired behavior Some users

for example, can interpret lack of certain

function-ality as a bug Because of this thin line between

bugs and functionality, it is a good practice to do

request tracking along with the bug tracking

process, as we will see later in the text We will

introduce a new term (issue), to describe both

bugs and feature requests

The layman would say that bugs in software are

only the result of programmer carelessness, but

anyone who has ever worked on a large software

project knows that is not always true Sometimes

projects are so complicated that a minor change in

one module could produce an unexpected disaster

where it is least expected There are many softwaretechniques that model how to take your software’squality to a higher level, but that is way beyond thescope of this article Here, we will try to concentrate

on how to keep track of the bugs (and requests) inyour project We will also learn how to organize thedevelopment process so that most of the malfunc-tions in the software code are detected before finalrelease and not by your customers

Life cycle of a bugThe first thing you will always hear when discussingsoftware testing and quality assurance is that theperson who implements the code should not be theperson who is testing it There are few reasons forthis statement The first is that the person who isactually writing the code has his own mindset andcannot see the certain flaws in the design even if helooks at it for a very long time Another person, who

is actually only looking at the code’s behaviour, caneasily spot things that the original writer missed.The second argument is rather psychological; thetester should act destructively against the code,which is very hard to do with your own work Wewon’t go deeper into details about software testing,

REQUIREMENTS

Trang 20

that could be the topic of some future article, but

this story is very important in establishing roles in

our bug management process Three roles are

nec-essary for successful bug tracking:

• Developer – person who actually writes

code and fixes bugs

• Tester (QA staff) – person who tests the

code and writes bug reports This

per-son, as we will see later, also verifies

that the certain bug is fixed

• Project manager – person who assigns

certain properties to bugs (like we are

going to see in the next section) and

assigns them to developers for fixing

The bug life cycle would look like this: quality

assurance person finds the bug and submits the

bug report Project manager reviews every bug

report If he finds that the bug is valid, he assigns

some attributes to the bug and assigns it to the

appropriate developer The developer than fixes

the bug and assigns it to QA for verification QA

repeats the tests on a requirement and the bug

gets closed or reopened depending on the

prob-lem’s presence in the system

Anatomy of a bug

Now is a good time to see what bug attributes we

need in order to successfully track our bugs

Components

Components help us to partition and

decou-ple the whole project imdecou-plementation and

also make it easier to find who is in charge of

the particular code base You can divide the

project vertically by encapsulating all the

code that is solving the same problem

domain (business logic) into a component

(financial classes, address book and so on) or

horizontally by making components of the

particular application layers Or you could do

both There are no strict rules You should find

the scheme that best suits your needs For

example, we could introduce the followingcomponents for tracking bugs in the project:

• Presentation layer – all bugs that arerelated to the user interface such asHTML code, client side code (JavaScript),etc

• Business layer – malfunctions in ness scripts and classes

busi-• Data access layer – bugs in Data Objectclasses, SQL queries, database wrappersand so on

So when QA reports the bug, the componentattribute should address a certain projectsubsystem in order to make it easier for theproject manager to assign it later

Severity

Severity is another important bug attributethat tells us how serious our bug is Somecommon values are:

• Stopper – This kind of bug is stoppingeither the client in software usage orfurther development (e.g crashes, bugs

in database wrapper that disables thewhole project from connecting to data-base, etc.)

• Critical – serious bug that causes heavyprogram malfunctions (e.g bug in acore library that causes other subsys-tems to act unstable)

• Major – ‘major’ bugs make our softwareunreliable and can cause serious dam-age to us or our clients (e.g bad datacalculation in some cases that makesthe data unreliable)

• Normal – bugs that are not serious butare unpleasant to our clients (e.g bro-ken links in pages)

• Minor – small bugs that are not crucialfor core program execution, but should

be fixed in order to make better quality

of the product (e.g bad label for a formfield)

QA submit bug report

Project manager reviews the bug report and assigns it if necessary

Bug gets closed Developer fixes the bug

QA verifies that bug is fixed

Bug Life Cycle

Trang 21

• Enhancement – this is not a real bug,

but a request for a new feature

Priority

Priority is the attribute that is assigned by

the project manager and helps developers

organize their tasks It’s a common practice

to have five priority levels and the bugs with

higher priorities should be fixed first

Status

Status is directly connected with bug life

cycle It tells us in what stage of the bug

cycle our bug currently resides Some

com-monly used values are:

• New – bug has been reported, but not

yet reviewed

• Assigned – bug has been reviewed by

project manager and assigned to

par-ticular developer

• Fixed – bug has been fixed by

develop-ment team and has to be reviewed by

QA

• Verified (Closed) – QA has verified that

the bug has been fixed

• Reopened – QA have run tests against

the bug that was marked as fixed, and

some problems still remain, so it is sent

back to development for further repair

• Duplicated – this bug has already been

reported

• Won’t fix – these are so called “known

bugs” that are not going to be fixed in

this development cycle, mostly because

of a great risk involved in fixing the bug

or the required time for that job

• Invalid – Problem that is reported is not

a bug

• Works for me – Problem that has been

reported couldn’t be reproduced so it is

put in the repository for later analysis

Subject

Every bug report should have a subject

attribute for easier browsing and querying

Milestone

The software development process is often

divided into smaller iterations called

mile-stones We should keep track of the project

milestone that a bug has been reported to

and for which it has to be fixed We can

demonstrate this by imagining that we have

delivered version 1.2 of the project to the

client and continued to work on the next

release (1.3) We need a way to separate

bugs that are reported to these two versionsbecause it is often a completely differentcode base

Comments

Comments are a very important and usefulattribute of the bug We should always allowour team members to enter an unlimitednumber of comments to the bug Doing sowill allow us to keep track of the communi-cation and history of the bug An initial com-ment for the bug could be a description ofthe problem that QA (or the client) hasfound in our software

Attachment

In some development organizations a verylimited number of developers can commitchanges to the code repository In this case,the bug’s attachment attribute is used to addpatches of code that fixes bugs Attachmentcan also be used for many other purposeslike screen shots, test cases and all materialthat helps to document the bug properly

The bug attributes described above are just asmall subset of commonly used attributes in theproject You should, of course, adjust theseattributes to the specifics of your individual proj-ect and process Some additional attributes thatcan be useful to describe the bug are web brows-

er (particularly interesting for web applicationdevelopment), URL of the page in which bugappears, operating system (for platform specificproblems) and many, many more

Now that we know how to define our bugs, weshould mention the process of collecting newfeature requests for our project This process issometimes very closely related to the bug man-agement process When we were talking aboutthe bug status attribute earlier, we said thatspecial status could be introduced to separatethe bug from a request for enhancement (RFE).Basically a feature request could have a verysimilar structure to the bug report and, sincemany bug tracking tools support this functional-ity, it is natural (to some point) to keep track ofenhancement requests in the same repository

as bugs

Bug reports

OK, we have now discussed some basic tion about the structure and life cycle of bugs.This information, however, is not enough for asuccessful bug tracking process In order tomake your process efficient, the QA department

informa-F

Trang 22

needs to supply useful bug reports to the

devel-opment team The more information developers

have to work on, the sooner the bug will be

traced and fixed

When submitting a bug report, there are a few

things to keep in mind First things first, a basic

rule in any bug tracking process is to always try

to repeat the bug before submitting the report

This is very important because some bugs occur

only under very specific circumstances and

envi-ronment settings You must be sure that you

know the specific environment variables and

steps that lead to the malfunction that you are

going to submit Of course, some bugs are

almost impossible to trace, but even then you

should make it easier for the developer by

point-ing him to all of the thpoint-ings that failed to repeat

it That way we can save some time by not

dupli-cating effort, and it gives certain clues to the

development team about what could be the

problem

Let’s take a look now at what makes a good

report We can start by showing one bad example

and go through to see how to make it better Let’s

say that a report like this is submitted:

When a developer gets a message like this, the

only thing he knows is that some problem exists in

the process of adding a new customer He can’t

begin fixing the problem without actually

contact-ing the person that submitted this report because

he hasn’t a clue where to start So, the usual

ques-tions end up being asked: What error was

dis-played? What data did you submit? On what page

did the error occur? In 99% of the cases, the

sub-mitter doesn’t remember all the details because it

was a “century” ago, and we’re trapped in an

infi-nite loop But, if we use another approach and

submit a report like this, everything could be very

• Subject: Add a new customer

• Brief description: submitting of a new customer

with the regular data failed

• Steps:

Log in

Click the link to the address book

Click” Add new customer” button Enter the data (see “data” section) Click “Save changes” button

• Data:

Name: Dejan Bosanac Email: chubrilo@yahoo.com Title: Software developer All other fields: empty (default)

• Expected results: The data is submitted to the database and “view” page for the customer is displayed

• Actual results: Error page with a message “Error executing SQL query: phone_number field cannot

as the comment or the attachment to the bug Wecan now summarize what a good report shouldconsist of:

1 Brief description of the problem

2 Environment under which problemoccurs

3 Steps needed to reproduce the problem

4 Specific inputs that caused the problem

5 pected and actual results

6 Summary of what the problem could be

Of course, details of the each step depend onwhat the specific problem is For example, if thebug is found during unit testing, input datashould be the test case that caused the bug (youcan attach the test class that caused the bug, ifyou want) Or, in another extreme case, if it is avisual (cosmetic) bug, all you have to submit ishow to enter the specific page and what is wrong(environment-specific data is always useful) Ageneral rule is that the more complex the prob-lem is, the more information the developer isgoing to need

Bug tracking and development cyclesFor successful bug and request tracking there are

a few more issues that you must keep in mind.The development cycle plays a key role in how theprocess is handled It can be divided into threesections:

• Development - implementation of thesystem functionality, resulting in huge

When I inserted some customer data and

clicked on the “Save changes” button, an

error page was displayed.

Trang 23

changes to the codeset

• Code freeze – software has entered beta

testing phase and code is usually frozen

• Release planning – preparations for the

next project release are under way

In order to have an efficient development

process, we will look at how to use the

bug-track-ing system in each of these phases

In the development phase, good practice dictates

that developers create test cases at the same time

they write the code A test case is code that is

writ-ten to test certain functionality and to report the

error if it is found This way, we will actually have

the confirmation that the software is doing the job

for which it is meant These test cases are

normal-ly grouped in a test suite that is executed regularnormal-ly

(preferably every night) This type of testing is

called regression testing We will not get into this in

this article, but it is important to mention it because

it affects the bug tracking process itself Some

authors say that in this stage of development we

should not use a bug-tracking system as a

reposi-tory for bug issues, as our test suite would keep this

information for us The would advise, though, to

use a bug-tracking system for storing features that

will be introduced later in the process

While this may true to some point, some errors

cannot be detected with regression testing Defects

that are found during code reviews, user

experi-ence issues, and visual defects are just some of the

bugs that we must handle outside of a test suite

So, my opinion is that in this phase we shouldn’t

really submit duplicate reports to the system, but

all the other issues that are reported during testing

should be stored If we don’t do this, we can

easi-ly forget about them until it is too late Of course, if

you don’t have automated testing introduced into

your process, you should keep all the issues this

way Feature requests are always good to be stored

in the system for later analysis

In the code freeze (beta testing) phase, the code

is usually frozen and no immediate changes can

be done Now, we should keep track of all found

malfunctions so that they can be fixed before the

final release It is also convenient to keep track of

a user’s feature requests (usually beta testers are

potential future users) At this point, we should

introduce a request “grade” In other words, we

should keep track of how many requests we have

for each feature, so we can easily separate the

must-have features from the eccentric ones

When you are ready to start planning the next

release, you could use the information stored in

your tracking system According to the request

grade you can decide what features will become

part of the next release One more thing is tant in this stage: you must estimate the effortneeded to implement certain features For exam-ple, if some feature is a must-have feature and itrequires minor code changes, then it should defi-nitely be planned for the next release In the casewhere the feature implementation requires hugecode refactoring and involves great risk, youshould think of delaying those features to somefuture release

impor-When you have specifications for future

releas-es, you should build the test cases for them andmark those requests as closed (remove them fromthe system)

Bug tracking tools

To start implementing organized bug management

in your organization, you merely need concretebug-tracking software You could use a well-definedsheet in Excel-like software You will soon see, how-ever, that it would be much more efficient if youhad just a little more Many companies decide tobuild their own solutions, often seriously underesti-mating the effort for such a task Many start with noclear idea of what they really want or need, andstart coding a solution with minimal requirements.Soon after, they realize that maintenance andimprovements to the solution are not cost effective

by any means, and that costs of later porting tosome commercial solution are much higher then itwould have be in the start Even if you have a smallbudget, it is not really hard to find a free solution intoday’s open source software initiative Many ofthese solutions will save you enormous time andmanpower compared to building your own solution.That way, your developers can focus on buildingthe project that needs the bug tracking process andnot the particular tool itself

So, let’s start talking about what the tracking tool needs to provide you

defect-How to choose the right tool for you?

Before starting your search for a bug-trackingtool, you should have a clear vision of your bugtracking process so you can choose the tool thatwill have all the necessary requirements to meetyour needs Let’s divide the requirements into twobasic groups: business requirements and techni-cal requirements

Business requirementsFirst of all, you should fit the tool into your currentcompany profile and budget There are various sys-tems on the market with a wide price range, so youshould start by positioning yourself into a group

F

Trang 24

that you can currently afford If your budget is

small, don’t worry, there are many very nice

open-source solutions There are also companies that

allow you to outsource this service to them for a

reasonable amount

Second, you should know who the users of the

bug management system will be, and if they have

any specific needs You will also need to be aware

of how many users will be using the system, as

well as their locations The price of the bug

man-agement tool is often related to this information

You can divide users into two large groups

Internal users

• QA staff will submit and query reports to

find bugs that need to be verified

• Developers will query reports to find

assigned tasks

• Project manager will query reports to

find unassigned bugs, and also run

met-rics on the data

External users

• Customers

• Clients

• Beta Testers

External users may like to submit

enhance-ment requests or bugs, and see the progress and

status of certain issues In this case, you will

probably be searching for a tool that can be

exposed to the web for external (and, of course,

internal) users This leads us to the question of

security Does the potential tool allow the

cre-ation of groups of users, as well as the

separa-tion of their privileges on acsepara-tions and data? We

might want to only allow external users to query

a small subset of all issues (for example, only

those that they have entered), and allow them

only to submit new reports, but not allow them to

modify existing data We could, of course, enable

only some groups to submit reports, but I think

that it would be better to allow all users to

sub-mit, as fewer bugs will be missed that way We

could also expect that only project management

staff could change details such as severity and

priority All of these decisions are up to you

Usability of the system is another important

parameter Does the potential tool define the bug

workflow that you need? Could it be configured?

Does the bug submission form have all of the

attributes that you need? Could it be configured?

It is very important for the tool to be easy to use,

as that will minimize the resistance to the tool by

team members that may jeopardize the whole

process You should also consider whether the tool

supports various methods of notification when abug status changes Does the software sendemail, SMS messages, or have any otheradvanced techniques for notification You maywant the project manager to be immediately noti-fied when a new critical bug report arrives, or youcould enable your customers to be alerted when acertain bug is fixed

Administration concerns are the last issue that

we will mention for the business requirements Weshould know if we have someone who has skillsthat are needed for successful deployment, con-figuration, and maintenance of the system andhow much time it is going to take aside from theirregular duties If this is a problem, then employinganother person for this task must be considered.The administration of the bug management tool isusually the responsibility of project andnetwork/database administrators

Technical requirementsTechnical requirements for defect tracking soft-ware are basically the same as for all other soft-ware products

• Reliability – software is stable and takescare of data consistency

• Robustness – software behaves well inextreme conditions and large data vol-umes

• Programmability – software has an cation programming interface (API)through which it can be extended toyour particular needs

appli-• Security – software gives needed

securi-ty for the data and has no securisecuri-ty flawsthat can be easily exploited

• Supportability – software vendor givesfair technical support for their product

• Scalability – software is adaptable toyour particular needs

These are just basic technical concerns Youshould also consider your current environmentand skills For example, does the product supportdatabase servers that you are comfortable with(MySQL, Sybase, Oracle, etc.)? Does the servercode (in client/server and web-based solutions)suit your current development environment(Linux, Windows 2000, …), or will you need to pre-pare a new server for it? There are many factors

to consider when choosing the perfect solution

Just one tip for the end, you should actually tryevery solution that seems to suit, since youwon’t necessarily find the flaws just by readingthe product specification

Trang 25

Some popular solutions

As I said before many software packages are built

for this specific need We will mention two

com-mon ones - the further hunt is up to you

• Bugzilla

( http://www.mozilla.org/projects/bugzilla/ ) –

this product has its genesis in the

open-source Mozilla web browser It is written in

Perl to replace an old bug tracking system

used internally for Netscape

Communications It quickly became the

de-facto standard in the open source

commu-nity, so you can see it in action on many

projects on the web Unix-like environments

are natural for this software, and it is very

well integrated with MySQL (but that’s the

only database server that is currently

sup-ported) The source code comes under a

mix of various licence policies that include

the Netscape Public License (NPL), the

Mozilla Public License (MPL), the GNU

General Public License (GPL) and the GNU

Lesser General Public License (LGPL) Some

features worthy of note:

– Integrated, product-based granular

security schema

– Inter-bug dependencies and

dependen-cy graphing

– Advanced reporting capabilities

– A robust, stable RDBMS back-end

– Extensive configurability

– A very understood and

well-thought-out natural bug resolution

protocol

– Email, XML, console, and HTTP APIs

– Available integration with automated

software configuration management

systems, including Perforce and CVS

(through the Bugzilla email interface

and checkin/checkout scripts)

There are also some drawbacks that will

be addressed in the future:

– Reliance on only single database server

(MySQL)

– Rough user interface

– Spartan email notification templates

– Little report configurability

– Some unsupported bug statuses

– Little support for internationalisation

– Dependence on some non-standard

libraries

• Elementool ( http://elementool.com ) - It is possible these days to outsource your bug tracking to some other company It is very convenient in situations when you don’t have,

or can’t afford, more time and resources for the solution All you need is a few minutes to set-up your account using your web browser, and you are ready to start Also, this is an ideal solution for one-off projects because you can cancel your account at any time with no obligations With this approach you don’t have any concerns regarding installing and updating your software, since you will always have the latest version ready for use.

Their basic free package includes:

– 200 issue storage capacity – Unlimited number of users – Mail notifications

– Downloadable database for your own backup

For extra features like reports, history trail, customisable forms and so on, you must reg- ister for an advanced, commercial package.

These are just representatives of two

approach-es, you should really spend some more time tofind a perfect solution for your needs

Closing wordThe aim of every professional software package is

a satisfied customer If you have an organizedprocess for tracking bugs and feature requests inyour project, you can be sure that less bugs will bedetected by customers, and that the time cycleneeded to fix those bugs (and track down newrequirements) will be noticeably shorter There aremany tools available on the market that couldhelp you organize your defects and requirements,but, before you start tracking them, be sure thatyou know what you need Bug tracking is closelyrelated to quality assurance issues and teamorganization, so it is important to start from there.Just try it; it’s easier than it sounds

F

Click HERE To Discuss This Article http://forums.phparch.com/45

Dejan Bosanac works as a fulltime software developer for DNS Europe Ltd ( http://www.dnseurope.net ) on the Billing software system for ISP's In his spare time he also serves as a Lead Engineer at Noumenaut Software( http://www.noumenaut.com ) on the online jour- naling project He holds a Bachelor degree in Computer Science and currently is on the master studies in the same field.

Trang 27

Although most web applications do not

require highly advanced database servers,

some of these servers provide more

advanced features – such as subqueries,

referen-tial integrity, transaction handling, and support for

stored procedures and triggers – which can make

a developer’s life far easier We will examine

these aforementioned features from a higher

level, giving examples of their use and usefulness,

as well as showing how some of them can be

sim-ulated at a low level within PHP

Perhaps you have heard of some of these

fea-tures, and maybe even used some of them This

article’s intent is to lower the bar for the

uninitiat-ed, and hopefully show you a right tool or two for

the job I mean, there is no sense trying to

devel-op a semi-usable transaction handling system in

PHP (which would be a difficult task indeed), when

you could just use a database with transaction

support built-in, right?

As much as possible, I’ll try to avoid database

specific code To avoid presenting

database-spe-cific PHP examples, I am going to use the PEAR DB

class PEAR (the PHP Extension and Application

Repository) is a free online PHP software

reposito-ry, and can be found at http://pear.php.net PEAR

is usually installed automatically when you install

PHP using common install packages In all

exam-ples, we will assume that we are already

connect-ed to a database server, and that we already have

a database connection handle which we are going

to call $dbh There will also be no error messages

Suppose we have two small tables, one taining data about our customers, and the othercontaining their addresses (we might expect acustomer to have more than one address).These tables are going to contain a very smallnumber of columns, and we will avoid specifyingspecific data types

con-Here are the table structures we’ll work with:

continued

CUSTOMER table:

CUSTOMER_ID FIRST_NAME LAST_NAME GENDER ADDITIONAL_INFO LAST_CHANGE

REQUIREMENTS

Databases have ceased to be a mystery

Designing and setting up databases and

data-base-driven applications is no longer a terribly

complicated task handled successfully only by

specialists and technicians Behind almost

every site that consists of more than a product

brochure is some kind of database from which

information is retrieved and presented

Trang 28

It may be apparent that CUSTOMER_ID is

going to be our customer’s unique identification

number, as well as that table’s primary key

Other information that we will store about the

customer includes first and last name, gender,

and any desired additional info The last column

in the CUSTOMER table represents the date of

the last change made to a specific customer’s

information

The ADDRESS table can hold more than one

address for a single customer The unique

identi-fier and primary key for each address is stored in

a column named ADDRESS_ID This table must

also contain a reference to the appropriate

cus-tomer, and this is found in the CUSTOMER_ID

col-umn Specific address data is also stored,

includ-ing the street, city, postal code and country

columns, while the last column again holds

infor-mation about when the specific record last

changed

Subqueries

You can think of subqueries (or sub-SELECTs) as

SELECTs within other SELECTs A simple example

could look like:

Let’s look at a demonstration of the

impor-tance and use of subqueries Consider that from

time to time we want to remove customers who

do not have any addresses in our database To do

that without subqueries would require a number

of steps We would need to browse the

CUS-TOMER table record-by-record checking for

matching records in the ADDRESS table, deleting

the customers with none An example of doing

this with PHP is shown in Listing 1

Using a subquery, we could do all of this in one

step with the following statement:

As you can see, the subquery will perform asmall join on CUSTOMER and ADDRESS If thesubquery doesn’t return a row for a particularcustomer, it means that there are no addresses

in the ADDRESS table, and the customer can bedeleted What a job done in only one statement!The statement could also have been writtenusing IN operator like

DELETE FROM CUSTOMER WHERE NOT EXISTS

(SELECT CUSTOMER_ID FROM ADDRESS

WHERE CUSTOMER.CUSTOMER_ID = ADDRESS.CUSTOMER_ID)

SELECT something

FROM table_1

WHERE something IN (

SELECT something_else FROM table_2 WHERE something_else LIKE

5 $query_customers = “SELECT * FROM CUSTOMER” ; 6

7 // SQL statements are not complete - we will add parameters later

8 $query_check_address = “SELECT COUNT(*)

28 // Get number of addresses

29 $count = $row [ ‘CNT_ADDRESS’ ];

36 } 37

38 } 39

40 ?>

Listing 1

Trang 29

This is a different approach to doing the same

job, but returns and checks more data for each

customer, which is not recommended when the

tables involved store a large amount of data In

such cases, EXISTS is a more suitable operator

If your applications use very complex SQL

state-ments to retrieve data, you can also simplify

them, and avoid joining too many related tables,

by using subqueries to retrieve single data

col-umn from related tables Note the following two

statements, which both return the same result:

In both cases, the customer’s ID and count of

related addresses is returned; however, in the first

statement we had to group data using the GROUP

BY clause, which is in most cases a slow operation

on large tables In the second statement, we

exe-cuted small and quick subquery (it is quick

because it retrieves only related data from the

ADDRESS table for each customer and counts it

using the table’s primary keys) thereby avoiding

joining and grouping

Although, on first sight, the second statement

would now look more complex than the first one,

think what would it look like if we had to join and

group more than two tables with many fields –

there would appear many field names in the

WHERE and GROUP BY clauses, and the SELECT

list would look much more complicated Field

name conflicts could also appear, and we would

be forced to assign the table name to each field

which appears more than once We should also

mention that all field names in a subquery are

local to that statement, and we do not need to

worry about conflicts with field names in the

main statement

If your statements are complex, the use of queries can often help with their simplification.This is not to say that there are not good reasons

sub-to use each of these other methods Depending

on the SQL statement’s complexity, the number ofjoined tables, and the amount of data processed,each method will act differently

Views

A view is a virtual table which does not physicallyexist It is defined as a query on one or more tablesand stored in the database definition as an SQLstatement You can do any kind of SELECT from aview, and use it in any SQL statement just as youwould any physical table Views can sometimes beupdated and deleted from, but whether a view isupdateable or not depends on the complexity of itsSQL definition and join conditions Views can becreated, altered, or dropped just like regular tables.Let’s return to our problem of counting a cus-tomer’s addresses from table ADDRESS Instead

of doing a subquery or creating a temporary table

to hold the counts of all addresses for each tomer we could simply create a view like this one:

cus-We have defined a virtual table named TOMER_ADDRESS_COUNT, which contains onerow for each customer with his addresses counted

CUS-in field NO_OF_ADDRESSES Now we can selectdata from the view by issuing a statement like

We will get a set of rows containing TOMER_ID and NO_OF_ADDRESSES for eachcustomer, just like we did with the previous SQLstatements that used subqueries or joins Havingthis view defined, we could now repeat ouraddress count check from Listing 1, avoiding the

CUS-$query_check_address SQL statement Betterthan that, our main query can be changed so that

it returns only customers with no addresses:

SELECT * FROM CUSTOMER, CUSTOMER_ADDRESS_COUNT WHERE CUSTOMER.CUSTOMER_ID =

CUSTOMER_ADDRESS_COUNT.CUSTOMER_ID AND NO_OF_ADDRESSES = 0

SELECT * FROM CUSTOMER_ADDRESSES_COUNT

CREATE VIEW CUSTOMER_ADDRESS_COUNT AS SELECT

CUSTOMER_ID, COUNT (*) AS

NO_OF_ADDRESSES FROM ADDRESS

GROUP BY CUSTOMER_ID

SELECT

CUSTOMER.CUSTOMER_ID

COUNT (ADDRESS.*) AS NO_OF_ADDRESSES

FROM CUSTOMER, ADDRESS

WHERE CUSTOMER.CUSTOMER_ID =

ADDRESS.CUSTOMER_ID GROUP BY CUSTOMER.CUSTOMER_ID

DELETE FROM CUSTOMER

WHERE CUSTOMER_ID NOT IN

(SELECT CUSTOMER_ID FROM ADDRESS)

F

Trang 30

This statement immediately returns only tomers without addresses, and we can deletethem easily

cus-Views can be (and are) used to do much morecomplex things than this In fact, their main pur-pose is simplification of SQL statements Viewscan also be used to restrict database access, oftenhiding the structure and full contents of the phys-ical tables from whoever selects data

Referential Integrity

As explained in pretty much any relational base theory book, referential integrity preventsapplications from creating inconsistent dataentries in a database It is usually represented bysome kind of relationship between two databaseobjects (tables), or simply with some rules thatdetermine which data can be entered into existingdatabase objects

data-As a simple example, referential integrity couldprevent entering data into table X if some corre-sponding data does not exist in table Y Likewise, itcould prevent applications from deleting any data

in table X that has corresponding data in table Y

Many relational database systems support ferent modes of referential integrity, but the mostcommon method is the creation of foreign keys Iftable X has a foreign key that points to a field intable Y, a referential integrity system mightrestrict adding records to Table X that don’t refer

dif-to a value in that table Y field It might also vent deletion or single-side change of the linkeddata in table Y, or take care that all deleted ormodified data in table Y is likewise deleted andmodified in all linked tables (table X) While theformer method is preventative or restrictive, thelatter method cascades changes from table Y totable X, and is thus referred to as “cascadingdelete” and “cascading update”

pre-In our case, we should take care that usershandling our application do not delete a cus-tomer from the CUSTOMER table if there areaddresses stored in ADDRESS table that belong

to him Deleting the customer data (as in Listing2) would leave his addresses orphaned, andthere is the possibly that they could be unwit-tingly re-attached at a later time to some newlyentered customer (if the deleted customer’s IDwas re-used when a new customer was added).With referential integrity, we can easily establish

a relation between the CUSTOMER and ADDRESStables by creating a FOREIGN KEY in tableADDRESS which points to the customer’s ID inCUSTOMER We should give the key a name, solet’s make it FK_ADDRESS_CUSTOMER_ID, simplyshowing that it relates the ADDRESS table to the

11 // display an error message and exit

12 echo “Error deleting customer.” ;

11 $result = $dbh -> query ( $query_check_address );

12 $row = $result -> fetchRow ());

13 $count = $row [ ‘CNT_ADDRESS’ ];

25 // display an error message and exit

26 echo “Error deleting customer.” ;

Trang 31

CUSTOMER table through column CUSTOMER_ID.

Our foreign key will do several things for us:

• it will prevent us from entering a

CUS-TOMER_ID into the ADDRESS table that

does not yet exist in the CUSTOMER

table

• it will prevent us from deleting a

cus-tomer whose CUSTOMER_ID is

refer-enced from addresses stored in the

ADDRESS table

• if defined with ON … CASCADE clause, it

would ensure that deleting a customer

would delete all his addresses, or that

updating his CUSTOMER_ID in the

CUS-TOMER table would update it in all

refer-ring records in the ADDRESS table

Our foreign key definition should normally be

specified in the ADDRESS table creation code, and

might look like:

The above statement creates a restrictive

for-eign key To add support for cascading, use:

Now imagine Listing 2 running on linked tables

The referential integrity engine would either

phys-ically prevent the deletion of customer records

that have addresses (restrict), or delete the

addresses as well (cascade)

If you are using a RDBMS that does not support

referential integrity, you can still simulate it fairly

successfully In this simple case it might be an

extended version of our function from Listing 2,

shown in Listing 3

Although writing code to extend this function

does not appear to be too much hard work, it is

obvious that simulating just a simple restrictive

referential integrity engine can mean writing

some amount of extra code Simulating a

cas-cading delete is a fairly simple change (shown in

Listing 4):

There are some performance issues to considerwhen using cascading updates In the case thatyour database server contains a large amount ofrelated data, the change or deletion of some mas-ter records could force the database server to per-form large, time-consuming update operations Inthe worst case scenario, this could result in excep-tional load on the server, as well as script execu-tion timeouts

The proper use of referential integrity can help

to reduce the amount of sanity checking codenecessary and the number of errors introduced,

as well as helping to increase the amount of sleepyou get at night

Transactions

OK, we did nice job programming an checking routine which checks for existingaddresses and either prevents us from deletingthe customers to which they belong, or deletesthe addresses as well Consider, though, that yourapplication communicates with the remote data-base server through some wired link Imaginethat just between deleting data from theADDRESS table and the CUSTOMER table, some-one cuts the wire? Of course, this is not a hugeproblem in our simple case, but there are complexsituations where this would be a big problem

integrity-FOREIGN KEY FK_ADDRESS_CUSTOMER_ID

(CUSTOMER_ID) REFERENCES CUSTOMER (CUSTOMER_ID)

ON UPDATE CASCADE

ON DELETE CASCADE

FOREIGN KEY FK_ADDRESS_CUSTOMER_ID

(CUSTOMER_ID)REFERENCES CUSTOMER (CUSTOMER_ID)

10 $result = $dbh -> query ( $query_delete_address );

11 if ( $dbh -> isError ( $result ))

12 {

13 // display an error message and exit

14 echo “Error deleting addresses.” ;

22 // display an error message and exit

23 echo “Error deleting customer.” ;

24 return 0 ;

25 }

26 else return 1 ;

27 } 28

29 } 30

31 ?>

Listing 4

Trang 32

Besides, users would be confused if addresseswere deleted while customer data stays.

How can we get around this? By usingtransactions

Transactions are, roughly explained, closedprocesses that are invisible to concurrent data-base users A transaction remains invisible toother users until such time as it is committed If

a transaction is rolled back, or discarded, otherusers will never know it even happened in thefirst place

This means that when we start a transaction,whatever we do with data in the database will

be invisible to other users If we send a MIT statement, all of our work will be actuallywritten to the database and other users will beable to see the altered values If we issue aROLLBACK statement, no changes will be writ-ten at all, leaving the data in the same state as

COM-we started with A transaction rollback, ing on the database server’s settings, also hap-pens when the connection to the server is lost

depend-or broken, depend-or if an errdepend-or condition was raisedwhile we were working That is awesome dataconsistency protection!

As we mentioned, with the previous data tion example it was not possible to leave cus-tomers without address data if our script brokebetween the two DELETE statements What if,for some particular reason, we want to changeour customer’s ID? To keep data in the two tablesrelated to each other, the changed ID must also

dele-be updated in all customer address records Ifthe connection breaks in the middle of thechanges, our addresses could be left without acustomer, or our customer could be left withoutaddresses

By invoking a transaction before we startupdating data, and committing it after updateshave completed, we can ensure that no data will

be left in an inconsistent state An example isgiven in Listing 5 Let’s have a look at it

After we set up the queries to run in order tochange our customer ID from $old_customer_id

to $new_customer_id, we also set up an errorindicator The $success variable will tell us if allhas been completed correctly at the end of ourfunction

Notice one special function call,

$dbh->autoCommit(false) This function tellsthe RDBMS which serves our data that we want

to turn off the ‘auto commit’ feature ‘Autocommit’ is supported by many database serverengines, and it means simply that the transac-tion started implicitly by each query will auto-matically be committed when the query is fin-

14 // Server starts the transaction implicitly,

15 // if auto commit option is set to FALSE

21 // display an error message and exit

22 echo “Error updating addresses.” ;

29 // display an error message and exit

30 echo “Error updating customer.” ;

46 // Otherwise, we can undo a complete task

47 // leaving the data in the state just as

before we started

48 $dbh -> rollback ();

49 }

50

51 // You might want to set auto commit option

52 // back to True for other processes that

do not use transactions

Trang 33

ished Most RDBMS’s have this turned on by

default, but to prevent storing incomplete

changes we must turn this feature off We do

not want to store anything until all changes are

complete In the PEAR DB class we can turn off

‘auto commit’ programmatically by calling the

actually means that the first and subsequent

changes to our data will be done within a

trans-action, and will not be written or discarded until

we issue a commit or a rollback

At the end of our function in Listing 5, we can

check if any errors happened while updating

the data If not, we can call the commit()

method, which will write out all of our changes

and close the transaction If an error did ocur,

we can simply call the rollback() method,

which will discard all of our changes and close

the transaction

A little better error handling around the

which case no data would be written It isimportant to handle transaction completionproperly because leaving open transactions(especially in conjunction with table locks)could cause locked data and prevent otherusers from accessing the database!

It should be noted that, although we used thePEAR methods above, transactions can usually beset up manually with SQL statements The exactsyntax varies from system to system

We should also mention that transactionscould be simulated by PHP Any simulation ofthis feature would be hard-pressed to be robustenough for real world use, and would be a verycomplex piece of code, but it is possible to do.The most common way is to prepare all edits

F

1 PROCEDURE NEW_CUSTOMER (FIRST_NAME, LAST_NAME, ADDITIONAL_INFO, GENDER)

1 CREATE TRIGGER before_new_customer

2 BEFORE INSERT ON customer_id

3 REFERENCING NEW AS new_customer_row

4 FOR EACH ROW

5 BEGIN

6 new_customer_row.CUSTOMER_ID =

7 (SELECT MAX(CUSTOMER_ID)+1 FROM CUSTOMER);

8 ENDListing 8

24 // Now incease it’s value

25 $new_id = $result ( ‘LAST_ID’ ) + 1 ;

31 // display an error message and exit

32 echo “Error adding customer.” ;

advanced database servers, some of these servers pro- vide more advanced features.”

Trang 34

and updates in separate tables and then

trans-fer them to the actual data tables, checking if

all updates were OK

Procedures and Functions

Procedures, functions, or stored procedures – they

are all essentially the same thing: blocks of code

(using some supported language, such as SQL,

PL/SQL, C, Java, and recently PHP!) that are

exe-cuted on the database server Procedures that

run on the database server have many uses,

including embedding business logic in the

data-base, data consistency checking, and

simplifica-tion of the database access interface Let’s look

at an example

Consider that instead of customer updates or

deletes, we now have the need to add a new

cus-tomer into the database Among other data, we

must provide a unique ID value to identify the

cus-tomer A PHP function to store new customer data

into the database could look something like

Listing 6

Notice that we do not receive CUSTOMER_ID as

a parameter to the function Instead, we retrieve

the highest existing value from the CUSTOMER

table and add one to it But, what if just between

when we got the last ID and inserted our new

record, someone else got the same ID and tried

to insert the data in the same time? One of us

would receive an error and no data would be

inserted!

Procedures can offer a good solution to this

problem, as they are executed very quickly, and

may be executed serially on your system This

means that we can use them to “get around” the

aforementioned race condition, or at least narrow

the window Truly patching this race condition

would usually require table locking, which may be

the subject of a future article

As the code for writing database procedures is

often very specific for each database system, we

will skip writing a real example, point you to

some pseudo code in Listing 7, and ask you to

consult your local database system manual

Triggers

Triggers are usually functions in disguise, linked

to a specific table, and executed before or after

events like inserting, updating or deleting

records There can often be more than one

trig-ger attached to a single table, and trigtrig-gers are

then executed in specified order, one-by-one

The most common use of triggers is for

main-taining referential integrity Triggers specified

before an action can often choose to prevent the

action, or perform other actions on other tables

(like deleting matching records, in the case ofcascade) Triggers can also change values in therow being modified This will help us in our nextexample

Rather than having to run a query to find outwhat ID we can use, then inserting anotherrow, wouldn’t it be much nicer to just insert therow and let the system worry about giving it anID? This is exactly how Listing 8 works Listing

8 shows a trigger on the CUSTOMER table, to

be fired right before the row is inserted Thebody of the trigger (who’s real implementationwould vary greatly on different systems) getsthe next ID, and sets the CUSTOMER_ID field inthe inserted row This way, adding a new row

is as simple as inserting the data, not worryingabout which ID to use Again, we have to worryabout a race condition, but this could be han-dled with table locks or sequences – topics foranother day

Wrapping upThere are a number of advanced features that wehaven’t covered here, including table locking, rowlocking, sequences, rules, etc Perhaps these can

be the topics for another article

The more tasks the database server can do foryour application, the less code you will have towrite Stability, security, and performance arealso a consideration Generally speaking, featuresembedded in the server are going to be muchmore robust and reliable than any simulation wecan make As database systems are improved,more automated features will likely be engineeredand introduced, allowing us to focus on the moreimportant things

You might think that you should search out thedatabase with all of these features, and be setfor the future, but that’s not necessarily true.Most of the above features come at a cost, andusually it’s performance If you don’t anticipate

a need for these more advanced capabilities, youmay see much better performance with a lessadvanced system

Click HERE To Discuss This Article http://forums.phparch.com/46

Davor Pleskina lives in Opatijia, Croatia He is the author of Davor's

PHP Editor You can reach Davor at davor@pleskina.com

Trang 35

Over the last few months we have seen some

thought-provoking articles on technologies like

XML and the Smarty template engine Other

articles have indirectly expressed the

advan-tages of using OOP (Object-oriented

program-ming) instead of procedural programming In

this article we will like to focus on combining

the knowledge from these previous gems to

build something useful every web developer

can use

Every modern Internet or intranet web

applica-tion these days require some sort of menu

struc-ture or interface to allow for the easy navigation

within the application Let’s use the

aforemen-tioned technologies to build a reusable menu

structure This menu structure will make use of

object-oriented concepts, be defined in XML, and

be driven by templates/styles to allow changes

to the look and feel

Before we start

Firstly, let’s quickly get the logistical things out of

the way To make sure that everything runs

smooth-ly on your side you are going to need the Expat XML

library and the Smarty template engine installed

Most Linux distributions have the Expat library

compiled in with PHP package (Debian, Redhat,

Mandrake, Suse) You can use the following code

to see if Expat has been included in your PHP

package:

You should see a section ‘xml’ with ‘XML port active’ and the ‘EXPAT Version’ asshown in Figure 1 If you do not have Expat sup-port you can get the source from

Expat support within PHP simply include xmlwhen running the configure build script fromthe PHP source directory However it is highlyunlikely that you will not have Expat support

—with-The Smarty template engine is downloadable

<?php phpinfo ();

XML Namespace Support active

EXPAT Version expat_1.95.6

xml

PHP: 4.2+, XML extension, MySQLOS: N/A

Applications: SmartyCode Directory: xml_menus

REQUIREMENTS

Trang 36

from http://smarty.php.netand the latest version

as of this writing is version 2.50 Why use

Smarty? First of all, reinventing a well-invented

wheel is seldom necessary Second, it is almost

always advisable to separate the business logic

from the presentation layer, and Smarty does a

good job of that You will need to uncompress the

Smarty source code into a PHP accessible

direc-tory In my code distribution, I include a

code/class.MySmarty.phpwrapper file (we will

discuss this later) that includes the Smarty

tem-plate engine as:

You might need to change this require

state-ment to point to the correct location of Smarty

The source code for this article contains a

‘code’ directory that should be moved into a

web-accessible area on your local machine in

order to make the examples work

In this article I presume that you know some

basics about XML, Object-oriented programming

and using the Smarty template engine In the

same breath, however, I would also like to use

this article to introduce some of these concepts

I hope you enjoy the ride!

Our requirements

Lets have a look at what we would like to see in

our menu component

• We want to store our menu structure in

a manageable, portable structure, so

we will be using XML to define ourmenu structure

• The menu structure must be able tohandle the following:

- an optional menu heading

- multiple collapsible menu tions

sec multiple menu items undereach menu section

- menu items must support animage and or text description

• The menu structure needs to supportHTML frames, directing access to differ-ent windows

• The menu needs to support differentthemes or styles

• We need to be able to use our menu as

a drop-in component to an existingpage or as a standalone menu inter-face with a separate header and footer

to signify a complete HTML page Wewill be able to achieve this functionalityusing our templates

The following is the basic outline of our menusystem:

Mapping what we need into XMLNext we need to look at mapping our menurequirements into a XML definition In Listing 1(menu_example_1.xml) we see the menu defini-tion starting and ending with <menu> tags Theexample menu is typically something we will find

in our web administration section Every menustructure has an optional menu heading and thedefault state of the menu (either open or closed) The menu structure can have multiple sectionswith multiple menu items linked to a specific sec-tion Every section has a unique id that identifiesthe section We will use this id as theheading/title for the section Multiple menuitems can belong to a section Every item has anitem name to identify the menu item, the item’s

menu heading (optional)

menu section1 (optional) (click to expand/collapse)

menu item menu item menu section2 (optional) (click to expand/collapse)

menu item menu item

require_once( ‘smarty/Smarty.class.php’ );

< menu >

< heading >php|a</ heading >

< state >closed</ state >

< section id =”Company Management”>

< item >

< name >Add a new company</ name >

< href >action.php?function=add_company</ href >

< image />

</ item >

< item >

< name >Delete a company</ name >

< href >action.php?function=del_company</ href >

< name >Add a new user</ name >

< href >action.php?function=add_user</ href >

< image />

</ item >

< item >

< name >Delete a user</ name >

< href >action.php?function=del_user</ href >

3 $menu = new Menu ( ‘menu_example_1.xml’ , ‘default’ );

4 $menu -> setTarget ( ‘info’ );

5 $menu -> buildMenu ();

6 $menu -> displayMenu ();

7 ?>

Listing 2: menu.php

Trang 37

link, and an optional image for the menu item In

our example, every menu item will be using the

arrow.gif image to identify a menu item

How does everything fit together?

We will take a slightly different approach here, and

show you the end result first Listing 2 (menu.php)

shows how we would like to create our menu

We first create an instance of the Menu class

The Menu class constructor takes two parameters,

our menu structure, saved as a xml file, and the

style we would like to use for displaying the menu

We then set the default target of the menu items

to ‘info’ (an HTML frame) After creating the menu

with a call to buildMenu(), we display the menu

to screen Wow five lines of code, that looks easy

I see that hand Yes, we will be working in a

framed environment for this example Listing 3

(example_1.html) shows the HTML code we will use

For those of us that have itchy fingers, you are

welcome to open example_1.html in your browser to

see the menu we have just created You are only

allowed to do that, though, if you promise to

return After all, we will need to have a look at how

we did that Figure 2 is a screen shot of the

‘default’ menu style with both sections expanded

(The ‘default’ style’s images and style sheet are

included in the article’s source directory)

Figure 2

What do we need to continue?

Looking at Listing 2, we will explain our project

by examining the following:

1 We will first look at a class for parsing our

XML menu structure This class will create

a menu array, containing the structure andinformation about our menu

2 Second, we will look at a class to managethe style component of our menu We willexamine our style file (menu.tmp) and thecode we use to assign the Smarty vari-ables within our menu template

3 Third, we will look into the detail of ating collapsible and expandable menusections and items

cre-4 Finally, we will end off with the Menuclass, tying all of this together

Lets carry on by looking at the XML parser class

6 <frame src=’menu.php’ scrolling=’auto’ frameborder=’no’

mar-ginwidth=’2’ marginheight=’2’ noresize name=’main’>

7 <frame src=’blank.html’ scrolling=’auto’ frameborder=’no’

mar-ginwidth=’2’ marginheight=’2’ noresize name=’info’>

37 if (isset( $element [ ‘attributes’ ][ ‘ID’ ]) )

38 $key = $element [ ‘attributes’ ][ ‘ID’ ];

45 $this -> menu [ $key ][ $i ][ ‘href’ ] =

str_replace ( ‘##’ , ‘&’ , $element [ ‘value’ ]);

Trang 38

The XML parser

On to the real stuff In our XML class we want to

create an array that will hold the contents of our

menu structure Looking at Listing 4

(class.MenuXML.php), we see the MenuXML

class with four important class variables

Our class constructor expects a $data variable

If the $data variable is a valid file location, we

read the contents of the file into our $data class

variable, else the $data variable is assigned to

the class $data variable By doing it this way, we

allow future support where we could create our

menu XML structure from a database, choosing

not to store the menu structure in a file

We next call the loadXML() method to create

our menu array In our loadXML()method we first

load the contents of our menu structure file into a

variable After creating an XML parser, a call to

xml_parse_into_struct() parses the XML data

into 2 array structures The $i_ar (index) array

contains pointer to the location of the appropriate

values in the $d_ar (values) array After freeing

the XML parser we are ready to work with our

val-ues array ($d_ar) to construct our menu array

Looping over our values array ($d_ar), we set

our heading, state and type class variables

When we encounter a ‘section’ element we get

the value of the ‘id’ tag The ‘id’ tag’s value will

be used as a $key for building our menu array

The following code tests our MenuXML class

Listing 5 shows us the output of the above

script, derived from the XML definition in Listing

1 (menu_example_1.xml)

Using Smarty and

our MenuStyle class

As we defined in our requirements, our menu

system needs to support themes or styles

Listing 6 (class.MySmarty.php) is a wrapperclass that extends the Smarty class In our con-structor we set the template directory, the con-fig directory, the compile directory and, lastly, adirectory where we store extra Smarty plug-ins

If the ‘compile’ directory does not exist, we ate it and set the appropriate permissions (Youmight need to change this setting if your tem-plate directory needs to have world access)Listing 7 (class.MenuStyle.php) contains ourMenuStyleclass which manages the style or theme

cre-of our menu system The style class currently onlyworks with one Smarty template file, calledmenu.tmp, stored in the style’s specific directory

‘style/STYLE_NAME/’ Listing 8 is the defaultmenu.tmp style file (style/default/menu.tmp)which we used to build the look and feel in Figure 1.The accompanying source code also includes thestyle sheet (styles.css)

Have a look at the sidebar on Smarty (page 40)

if you’re a little rusty or have never ventured thatway

As we look at our style class, we will see theSmarty functions assign() and fetch() beingused You should be familiar with the assign()

function from the sidebar, but the fetch() tion returns our completed template into a vari-able, instead of directly printing it out

func-In our style class’ constructor, shown in Listing

$heading Contains the heading we are

using for our menu

$state Contains the default state of

the menu (open or closed)

1 <pre>php|a

2 closed 3

Ngày đăng: 22/10/2013, 20:15

TỪ KHÓA LIÊN QUAN