Luke Welling and Laura Thomson201 West 103rd St., Indianapolis, Indiana, 46290 USAPHP and MySQLWeb Development00 7842 FM 3/6/01 3:38 PM Page i
PHP AND MYSQL WEB DEVELOPMENTxReturning Values from Functions ...141Code Blocks ...
Using Loops with each() and list()Because the indices in this associative array are not numbers, we cannot use a simple counterin a for loop to work w
This line uses each() to take the current element from $prices, return it as an array, and makethe next element current. It also uses list() to turn t
Using PHP, we would write the following code to set up the data in the array shown in Figure 3.3.$products = array( array( “TIR”, “Tires”, 100 ),array
price => 10 ),array( Code => “SPK”, Description => “Spark Plugs”, price =>4 ) );This array is easier to work with if you want to retrieve
FIGURE 3.4This three-dimensional array allows us to divide products into categories.From the code that defines this array, you can see that a three-di
echo “|”.$categories[$layer][$row][$column];}echo “|<BR>”;}}Because of the way multidimensional arrays are created, we could create four-, five-
The function asort() orders the array according to the value of each element. In the array, thevalues are the prices and the keys are the textual desc
The following code sorts this array into alphabetical order using the second column in thearray—the description.function compare($x, $y){if ( $x[1] ==
if ( $x[2] == $y[2] )return 0;else if ( $x[2] < $y[2] )return -1;elsereturn 1;}When usort($products, compare) is called, the array will be placed i
Reordering ArraysFor some applications, you might want to manipulate the order of the array in other ways. Thefunction shuffle() randomly reorders the
CONTENTSxiWeb Database Architecture ...180Architecture ...
Because the code selects random pictures, it produces a different page nearly every time youload it, as shown in Figure 3.5.Using PHPPART I84FIGURE 3.
Alternatively, we can use the array_reverse() function to reverse the array created byrange().$numbers = range(1,10);$numbers = array_reverse($numbers
LISTING 3.3 vieworders2.php—Using PHP to Separate, Format, and Display Orders for Bob<html><head><title>Bob’s Auto Parts – Customer
The code in Listing 3.3 loads the entire file into an array but unlike the example in Listing 3.2,here we are using the function explode() to split up
There are a number of ways that we could have extracted numbers from these strings. Here weused the function, intval(). As mentioned in Chapter 1, int
the output would appear in a browser as321Using each(), current(), reset(), end(), next(), pos(), and prev(), you can write yourown code to navigate t
Occasionally, you might be interested in the key of each element as well as the value. Yourfunction can, as with MyPrint(), choose to ignore the key a
For example, the following code$array = array(4, 5, 1, 2, 3, 1, 2, 1);$ac = array_count_values($array);creates an array called $ac that containsKey Va
TABLE 3.1 Allowed extract_types for extract()Type MeaningEXTR_OVERWRITE Overwrites the existing variable when a collision occurs.EXTR_SKIP Skips an el
CHAPTER4String Manipulation andRegular Expressions06 7842 CH04 3/6/01 3:41 PM Page 93
PHP AND MYSQL WEB DEVELOPMENTDropping a Whole Database ...226Further Reading ...
Using PHPPART I94In this chapter, we’ll discuss how you can use PHP’s string functions to format and manipulatetext. We’ll also discuss using string f
mail($toaddress, $subject, $mailcontent, $fromaddress);?><html><head><title>Bob’s Auto Parts - Feedback Submitted</title>&l
Unsurprisingly, this function sends email. The prototype for mail() looks like this:bool mail(string to, string subject, string message, string [addit
Depending on your particular purpose, you might like to use the ltrim() or chop() functionsinstead. They are both similar to trim(), taking the string
Both of these techniques print a string “as is.” You can apply some more sophisticated format-ting using the functions printf() and sprintf(). These w
All conversion specifications start with a % symbol. If you actually want to print a % symbol,you will need to use %%.The padding_character is optiona
The first column shows the function name, the second describes its effect, the third shows howit would be applied to the string $subject, and the last
(This rule applies universally to special characters, so if you have \\ in your string, you needto replace it with \\\\.)PHP provides two functions sp
component parts. PHP provides several string functions (and one regular expression function)that allow us to do this.In our example, Bob wants any cus
The prototype for strtok() isstring strtok(string input, string separator);The separator can be either a character or a string of characters, but note
CONTENTSTable Optimization ...262Using Indexes ...
We will look at examples using this test string:$test = “Your customer service is excellent”;If you call it with a positive number for start (only), y
return a number greater than zero. If str1 is less than str2, strcmp() will return a numberless than zero. This function is case sensitive.The functio
Given the functions we have already looked at, we could use explode() or strtok() toretrieve the individual words in the message, and then compare the
There are two variants on strstr(). The first variant is stristr(), which is nearly identicalbut is not case sensitive. This will be useful for this a
You can avoid this problem by using the === operator to test return values:$result = strpos($test, “H”);if ($result === false)echo “Not found”elseecho
The length value is optional and represents the point at which PHP will stop replacing. If youdon’t supply this value, the string will be replaced fro
Character Sets and ClassesUsing character sets immediately gives regular expressions more power than exact matchingexpressions. Character sets can be
TABLE 4.3 Character Classes for Use in POSIX-Style Regular ExpressionsClass Matches[[:alnum:]] Alphanumeric characters[[:alpha:]] Alphabetic character
Counted SubexpressionsWe can specify how many times something can be repeated by using a numerical expression incurly braces ( {} ).You can show an ex
Summary of Special CharactersA summary of all the special characters is shown in Tables 4.4 and 4.5. Table 4.4 shows themeaning of special characters
PHP AND MYSQL WEB DEVELOPMENTAuthentication Principles ...291Using Authentication ..
The second use is to validate customer email addresses in our application by encoding the stan-dardized format of an email address in a regular expres
We can adapt the Smart Form example to use regular expressions as follows:if (!eregi(“^[a-zA-Z0-9_]+@[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+$”, $email)){echo
while (list($key, $value) = each ($arr))echo “<br>”.$value;This splits the host name into its five components and prints each on a separate line
CHAPTER5Reusing Code and WritingFunctions07 7842 CH05 3/6/01 3:35 PM Page 117
Using PHPPART I118This chapter explains how reusing code leads to more consistent, reliable, maintainable code,with less effort. We will demonstrate t
ReliabilityIf a module of code is in use somewhere in your organization, it has presumably already beenthoroughly tested. Even if it is only a few lin
If you load reusable.php, it probably won’t surprise you when “Here is a very simplePHP statement.” appears in your browser. If you load main.php, som
Normally, PHP statements would not be processed if they were in a file called for example,page.html. PHP is usually only called upon to parse files wi
FIGURE 5.2TLA Consulting has a standard look and feel for all its Web pages.Directly reusing the sections of HTML that are common to all pages is a mu
<!-- page header --><table width=”100%” cellpadding = 12 cellspacing =0 border = 0><tr bgcolor = black><td align = left><im
CONTENTSUsing Encryption in PHP ...338Further Reading ...
You can see in Listing 5.1 that a number of distinct sections of code exist in this file. TheHTML head contains Cascading Style Sheet (CSS) definition
LISTING 5.3 header.inc—The Reusable Header for All TLA Web Pages<html><head><title>TLA Consulting Pty Ltd</title><style>
LISTING 5.4 footer.inc—The Reusable Footer for All TLA Web Pages<!-- page footer --><table width = “100%” bgcolor = black cellpadding = 12 bo
If we use these directives, we do not need to type require() statements, but the headers andfooters will no longer be optional on pages.If you are usi
This code will needlessly load both files every time the script is run, but only use one depend-ing on the value of $variable. However, if the code ha
Note that we can create variables in the main file or in the included or required file, and thevariable will exist in both. This behavior is the same
Most functions do require one or more parameters—information given to a function when it iscalled that influences the outcome of executing the functio
representing the file we want to open, and a variable called $openmode containing a string rep-resenting the mode in which we want to open the file. W
Case and Function NamesNote that calls to functions are not case sensitive, so calling function_name(),Function_Name(), or FUNCTION_NAME() are all val
This function declaration begins with function, so that human readers and the PHP parserknow that what follows will be a user-defined function. The fu
PHP AND MYSQL WEB DEVELOPMENTConverting Between PHP and MySQL Date Formats ...396Date Calculations ...
Many languages do allow you to reuse function names. This feature is called function over-loading. However, PHP does not support function overloading,
FIGURE 5.4This HTML table is the result of calling create_table().Passing a parameter allowed us to get data that was created outside the function—in
Optional values do not all need to be provided—we can provide some and ignore some.Parameters will be assigned from left to right.Keep in mind that yo
The following code produces no output. Here we are declaring a variable called $var insideour function fn(). Because this variable is declared inside
If we want a variable created within a function to be global, we can use the keyword global asfollows:function fn(){global $var;$var = “contents”;echo
The contents of $value have not changed.This is because of the scope rules. This code creates a variable called $value which contains10. It then calls
Returning from FunctionsThe keyword return stops the execution of a function. When a function ends because either allstatements have been executed or
$c = 1.9;larger($a, $b);larger($c, $a);larger($d, $a);will be as follows:2.51.9this function requires two numbersReturning Values from FunctionsExitin
The following code:$a = 1; $b = 2.5; $c = 1.9;echo larger($a, $b).”<br>”;echo larger($c, $a).”<br>”;echo larger($d, $a).”<br>”;will
Line 1Line 2Line 1Line 2Line 1Line 2Because the code in these examples is properly indented, you can probably see the differencebetween them at a glan
CONTENTSSimple Session Example ...435Configuring Session Control ...
In this listing, we have implemented two functions. Both of these will print a string in reverse.The function reverse_r() is recursive, and the functi
Further ReadingThe use of include(), require(), function, and return are also explained in the online man-ual. To find out more about concepts such as
07 7842 CH05 3/6/01 3:35 PM Page 146
CHAPTER6Object-Oriented PHP08 7842 CH06 3/6/01 3:34 PM Page 147
Using PHPPART I148This chapter explains concepts of object-oriented development and shows how they can beimplemented in PHP.Key topics in this chapter
In other areas of software development, OO is the norm and function-oriented software is con-sidered old fashioned. For a number of reasons, most Web
this would rarely be a problem. Bicycles are not likely to get confused and start using a car’smove operation instead. However, a programming language
Structure of a ClassA minimal class definition looks as follows:class classname{}In order to be useful, our classes need attributes and operations. We
One thing to remember is that PHP does not support function overloading, which means thatyou can only provide one function with any particular name, i
$this->attribute = $paramecho $this->attribute;}}Some programming languages allow you to limit access to attributes by declaring such dataprivat
PHP AND MYSQL WEB DEVELOPMENT23 Debugging 477Programming Errors ...478Syntax E
With only a single access point, we can implement checks to make sure that only sensible datais being stored. If it occurs to us later that the value
We then call operations the same way that we call other functions: by using their name andplacing any parameters that they need in brackets. Because t
It is important to note that inheritance only works in one direction. The subclass or child inher-its features from its parent or superclass, but the
Declaring B does not affect the original definition of A. Consider the following two lines ofcode:$a = new A();$a -> operation();We have created an
FIGURE 6.1PHP does not support multiple inheritance.The left combination shows class C inheriting from class B, which in turn inherits from classA. Ea
We are going to create a Page class. The main goal of this class is to limit the amount ofHTML needed to create a new page. It should allow us to alte
We can also set attributes to store the page’s title. We will probably want to change this toclearly show what particular page our visitor is looking
$this -> DisplayHeader();$this -> DisplayMenu($this->buttons);echo $this->content;$this -> DisplayFooter();echo “</body>\n</ht
var $keywords = “TLA Consulting, Three Letter Abbreviation,some of my best friends are search engines”;var $buttons = array( “Home” => “home.ph
function DisplayTitle(){echo “<title> $this->title </title>”;}function DisplayKeywords(){echo “<META name=\”keywords\” content=\”$th
CONTENTSSolution Overview ...542Implementing the Database ...
{echo “<table width = \”100%\” bgcolor = white”.” cellpadding = 4 cellspacing = 4>\n”;echo “ <tr>\n”;//calculate button size$width = 100/
}function DisplayFooter(){?><table width = “100%” bgcolor = black cellpadding = 12 border = 0><tr><td><p class=foot>&co
2. Creates an instance of the class Page. The instance is called $homepage.3. Calls the operation SetContent() within the object $homepage and pass so
LISTING 6.3 services.php—The Services Page Inherits from the Page Class but OverridesDisplay() to Alter the Output<?require (“page.inc”);class Serv
Outside the class definition, we create an instance of our ServicesPage class, set the values forwhich we want non-default values and call Display().A
IN THIS PART7 Designing Your Web Database 1718 Creating Your Web Database 1839 Working with Your MySQL Database 20710 Accessing Your MySQL Database fr
09 7842 part 2 3/6/01 3:39 PM Page 170
CHAPTER7Designing Your Web Database10 7842 CH07 3/6/01 3:34 PM Page 171
Using MySQLPART II172Now that you are familiar with the basics of PHP, we’ll begin looking at integrating a databaseinto your scripts. As you might re
TablesRelational databases are made up of relations, more commonly called tables. A table is exactlywhat it sounds like—a table of data. If you’ve use
PHP and MySQL Web DevelopmentCopyright © 2001 by Sams PublishingAll rights reserved. No part of this book shall be reproduced, stored in aretrieval sy
PHP AND MYSQL WEB DEVELOPMENTScript Architecture ...623Logging In and Out
Julie Smith from the Customers table for example. If I open my telephone directory, there aretoo many listings of that name to count.We could distingu
The relational database term for this relationship is foreign key. CustomerID is the primary key in Customers, but when it appears in another table, s
written by two coauthors, each of whom had written other books, on their own or possibly withother authors. This type of relationship usually gets a t
Designing Your Web DatabaseCHAPTER 77DESIGNING YOURWEB DATABASE177CustomerIDCUSTOMERSName Address City1 Julie Smith 25 Oak Street Airport West2 Alan W
With this design, we need to insert Julie’s details every time we take an order, so each time wemust check and make sure that her details are consiste
Choose Sensible KeysMake sure that the keys you choose are unique. In this case, we’ve created a special key forcustomers (CustomerID) and for orders
The first way means adding a Review column to the Books table. This way, there is a field forthe Review to be added for each book. If many books are i
FIGURE 7.8The client/server relationship between a Web browser and Web server requires communication.The Web database applications we will build in th
Further ReadingIn this chapter, we covered some guidelines for relational database design. If you want to delveinto the theory behind relational datab
CHAPTER8Creating Your Web Database11 7842 CH08 3/6/01 3:38 PM Page 183
CONTENTSPreviewing the Newsletter ...703Sending the Message ...
Using MySQLPART II184In this chapter we’ll talk about how to set up a MySQL database for use on a Web site.We’ll cover• Creating a database• Users and
2. Have access to MySQL on a machine that you do not administer such as a Web hostingservice, a machine at your workplace, and so on.If this is the ca
The mysql command invokes the MySQL monitor. This is a command line client that connectsyou to the MySQL server.The -h switch is used to specify the h
If it isn’t your machine, make sure that you typed in the password correctly.You should now be at a MySQL command prompt, ready to create the database
For the purposes of setting up a Web database, it’s a good idea to set up at least one user perWeb application.You might ask, “Why would I want to do
The clauses in square brackets are optional. There are a number of placeholders in this syntax.The first, privileges, should be a comma-separated list
Types and Levels of PrivilegeThree basic types of privileges exist in MySQL: privileges suitable for granting to regularusers, privileges suitable for
widely needed by users. Security is always a trade off between usability and safety. You shouldmake your own decision when it comes to ALTER, but it i
The REVOKE CommandThe opposite of GRANT is REVOKE. It is used to take privileges away from a user. It is very simi-lar to GRANT in syntax:REVOKE privi
mysql> revoke alter, create, drop-> on books.*-> from sally;And later, when she doesn’t need to use the database any more, we can revoke her
PHP AND MYSQL WEB DEVELOPMENTProblems with Headers ...777Extending the Project ...
The first thing you’ll need to do when you log in is to specify which database you want to use.You can do this by typingmysql> use dbname;where dbn
You can run an existing SQL file, such as one loaded from the CD-ROM, through MySQL bytyping> mysql -h host -u bookorama books -p < bookorama.s
Each of the tables is created by a separate CREATE TABLE statement. You see that we’ve createdeach of the tables in the schema with the columns that w
the auto_increment facility so that MySQL can manage these for us—it’s one less thing toworry about.The other columns are all going to hold string typ
In this case, we don’t need to generate the primary key because ISBNs are generated elsewhere.We’ve left the other fields NULL because a bookstore mig
| customers || order_items || orders |+-----------------+5 rows in set (0.06 sec)You can also use show to see a list of databases b
A summary of possible identifiers is shown in Table 8.4. The only additional exception is thatyou cannot use ASCII(0) or ASCII(255) in identifiers (an
Numeric TypesThe numeric types are either integers or floating point numbers. For the floating point num-bers, you can specify the number of digits af
TABLE 8.6 Floating Point Data TypesStorageType Range (Bytes) DescriptionFLOAT(precision) depends on varies Can be used to specifyprecision single or d
Date and Time TypesMySQL supports a number of date and time types. These are shown in Table 8.7. With allthese types, you can input data in either a s
About the AuthorsLaura Thomson is a lecturer in Web programming in the Department of Computer Science atRMIT University in Melbourne, Australia. She i
String TypesString types fall into three groups. First, there are plain old strings, that is, short pieces of text.These are the CHAR (fixed length ch
Table 8.10 shows the TEXT and BLOB types. The maximum length of a TEXT field in charactersis the maximum size in bytes of files that could be stored i
Further ReadingFor more information, you can read about setting up a database at the MySQL online manualat http://www.mysql.com/.NextNow that you know
CHAPTER9Working with Your MySQLDatabase12 7842 CH09 3/6/01 3:36 PM Page 207
Using MySQLPART II208In this chapter, we’ll discuss Structured Query Language (SQL) and its use in querying data-bases. We’ll continue developing the
Inserting Data into the DatabaseBefore you can do a lot with a database, you need to store some data in it. The way you willmost commonly do this is w
we insert a row with a NULL value or no value in this field, MySQL will generate the next num-ber in the autoincrement sequence and insert it for us a
You can run this script by piping it through MySQL as follows:>mysql -h host -u bookorama -p < book_insert.sqlRetrieving Data from the DatabaseT
which matches all the columns in the specified table or tables. For example, to retrieve allcolumns and all rows from the order_items table, we would
TABLE 9.1 Useful Comparison Operators for WHERE ClausesOperator Name Example Description(If Applicable)= equality customerid = 3 Tests whether two val
DedicationTo our Mums and Dads.AcknowledgmentsWe would like to thank the team at Sams for all their hard work. In particular, we would like tothank Sh
LIKE uses simple SQL pattern matching. Patterns can consist of regular text plus the % (per-cent) character to indicate a wildcard match to any number
The output of this query is+---------+--------+------------+| orderid | amount | date |+---------+--------+------------+| 2 | 49.99 | 000
As an extension, it can also be used to disambiguate column names from different databases.In this example, we have used a table.column notation. You
This query will return the following output:+-----------------+| name |+-----------------+| Michelle Arthur |+-----------------+Notice that
This output shows us that there are no matching orderids for customers Melissa Jones andMichael Archer because the orderids for those customers are NU
have values in common. If we want to find customers who live in the same city—perhaps toset up a reading group—we can give the same table (Customers)
The ORDER BY clause is used to sort the rows on one or more of the columns listed in theSELECT clause. For example,select name, addressfrom customerso
The most commonly used ones are listed in Table 9.3.TABLE 9.3 Aggregate Functions in MySQLName DescriptionAVG(column) Average of values in the specif
+------------+-------------+| customerid | avg(amount) |+------------+-------------+| 1 | 49.990002 || 2 | 74.980003 ||
This query can be read as, “Select name from customers, and then return 3 rows, starting fromrow 2 in the output.” Note that row numbers are zero inde
Tell Us What You Think!As the reader of this book, you are our most important critic and commentator. We value youropinion and want to know what we’re
Note that in ANSI SQL you can make only one alteration per ALTER TABLE statement, butMySQL allows you to make as many as you like. Each of the alterat
Let’s look at a few of the more common uses of ALTER TABLE.One thing that comes up frequently is the realization that you haven’t made a particular co
Dropping TablesAt times you may want to get rid of an entire table. You can do this with the DROP TABLE state-ment. This is very simple, and it looks
CHAPTER10Accessing Your MySQLDatabase from the Web with PHP13 7842 CH10 3/6/01 3:36 PM Page 227
Using MySQLPART II228Previously, in our work with PHP, we used a flat file to store and retrieve data. When welooked at this in Chapter 2, “Storing an
4. The MySQL server receives the database query, processes it, and sends the results—a listof books—back to the PHP engine.5. The PHP engine finishes
FIGURE 10.1The search form is quite general, so you can search for a book on its title, author, or ISBN.The script that will be called when the Search
@ $db = mysql_pconnect(“localhost”, “bookorama”, “bookorama”);if (!$db){echo “Error: Could not connect to database. Please try again later.”;exit;}my
FIGURE 10.2The results of searching the database for books about Java are presented in a Web page using theresults.php script.The Basic Steps in Query
Our next step is to verify that the user has entered a search term and search type. Note that wecheck he entered a search term after trimming whitespa
00 7842 FM 3/6/01 3:38 PM Page xxvi
Setting Up a ConnectionWe use this line in our script to connect to the MySQL server:@ $db = mysql_pconnect(“localhost”, “bookorama”, “bookorama”);We
Bear in mind that there is a limit to the number of MySQL connections that can exist at thesame time. The MySQL parameter max_connections determines w
In this case, we are searching for the user-input value ($searchterm) in the field the user speci-fied ($searchtype). You will notice that we have use
It’s useful to know this—if we plan to process or display the results, we know how many thereare and can now loop through them:for ($i=0; $i <$num_
Disconnecting from the DatabaseYou can usemysql_close(database_connection);to close a nonpersistent database connection. This isn’t strictly necessary
<body><h1>Book-O-Rama - New Book Entry</h1><form action=”insert_book.php” method=”post”><table border=0><tr><td
{echo “You have not entered all the required details.<br>”.”Please go back and try again.”;exit;}$isbn = addslashes($isbn);$author = addslashe
FIGURE 10.4The script completes successfully and reports that the book has been added to the database.Again, we have connected to the database using m
Freeing Up ResourcesIf you are having memory problems while a script is running, you might want to usemysql_free_result(). This has the following prot
Further ReadingFor more information on connecting MySQL and PHP together, you can read the appropriatesections of the PHP and MySQL manuals.For more i
IntroductionWelcome to PHP and MySQL Web Development. Within its pages, you will find distilledknowledge from our experiences using PHP and MySQL, two
13 7842 CH10 3/6/01 3:36 PM Page 244
CHAPTER11Advanced MySQL14 7842 CH11 3/6/01 3:35 PM Page 245
Using MySQLPART II246In this chapter, we’ll cover some more advanced MySQL topics including advanced privileges,security, and optimization.The topics
Each of these tables stores information about privileges. They are sometimes called granttables. These tables vary in their specific function but all
Each row in this table corresponds to a set of privileges for a user coming from a host and log-ging in with the password Password. These are the scop
Grant_priv enum(‘N’,’Y’)References_priv enum(‘N’,’Y’)Index_priv enum(‘N’,’Y’)Alter_priv enum(’N’,’Y’)TABLE 11.3 Schema of the host Table in the mysql
TABLE 11.4 Schema of the tables_priv Table in the mysql DatabaseField TypeHost char(60)Db char(64)User char(16)Table_name char(64)Grantor char(77)Time
field is blank, then no password is required. It’s more secure to avoid having blank users,wildcards in hosts, and users without passwords.2. Request
MySQL from the Operating System’s Point of ViewIt’s a bad idea to run the MySQL server (mysqld) as root if you are running a UNIX-like oper-ating syst
We will use this functionality when we come to implement the projects in Part 5, “BuildingPractical PHP and MySQL Projects.”User PrivilegesKnowledge i
PHP AND MYSQL WEB DEVELOPMENTUsing a language such as PHP and a database such as MySQL allows you to make your sitesdynamic: to have them be customiza
You should always check all data coming in from a user. Even if your HTML form consistedof select boxes and radio buttons, someone might alter the URL
11ADVANCEDMYSQLAdvanced MySQLCHAPTER 11255+------------------------------------------------------------------------------------------------+| Grants f
SHOW COLUMNS FROM table Lists all the columns in a particular table[FROM database] [LIKE column] from the database currently in use, or fromthe databa
SHOW GRANTS FOR user Shows the GRANT statements required to givethe user specified in user his current levelof privilege.Getting Information About Col
Using MySQLPART II258+-------------+--------+---------------+---------+---------+------------------+------+-------------+| table | type | poss
In the previous example, you can see that one of the tables is joined using eq_ref (books), andone is joined using ref (order_items), but the other tw
There are several ways you can fix problems you spot in the output from EXPLAIN.First, check column types and make sure they are the same. This applie
Speeding Up Queries with IndexesIf you are in the situation mentioned previously, in which the possible_keys column from anEXPLAIN contains some NULL
You can also use the myisamchk utility to sort a table index and the data according to thatindex, like this:>myisamchk --sort-index --sort-records=
• BDB. These tables are transaction safe; that is, they provide COMMIT and ROLLBACK capabil-ities. They are slower to use than the MyISAM tables, and
INTRODUCTIONThe home page for PHP is available at http://www.php.netThe home page for Zend is at http://www.zend.comWhat’s New In PHP Version 4?If you
14 7842 CH11 3/6/01 3:35 PM Page 264
IN THIS PART12 Running an E-commerce Site 26713 E-commerce Security Issues 28114 Implementing Authentication with PHP andMySQL 30315 Implementing Secu
15 7842 part 3 3/6/01 3:42 PM Page 266
CHAPTER12Running an E-commerce Site16 7842 CH12 3/6/01 3:43 PM Page 267
E-commerce and SecurityPART III268This chapter introduces some of the issues involved in specifying, designing, building, andmaintaining an e-commerce
Online BrochuresNearly all the commercial Web sites in the early 1990s were simply an online brochure or salestool. This type of site is still the mos
Regardless of the size of your company, make sure that your Web site is of a high standard.Text should be written and proofread by somebody with a ver
Simpler or cheaper options includeExamining Server Logs: Web servers store a lot of data about every request from your server. Much of this data is us
make a decision now. The more time you give people to reconsider a purchasing decision, themore likely they are to shop around or change their mind. I
Some products are unlikely to succeed as e-commerce categories. Cheap, perishable items,such as groceries, seem a poor choice, although this has not d
OverviewIntroduction 1PART I Using PHP1 PHP Crash Course 92 Storing and Retrieving Data 493 Using Arrays 694 String Manipulation and Regular Expressio
PHP AND MYSQL WEB DEVELOPMENTTo demonstrate this, the examples in this book have been written and tested on two popular setups:• Linux using the Apach
Are you a reputable business? If your business is registered with the relevant authorityin a particular place, has a physical address and a phone numb
CompatibilityBe sure to test your site in a number of browsers and operating systems. If the site does notwork for a popular browser or operating syst
digitally, you need to do it immediately. You cannot manually oversee the process, or spreadpeaks of activity through the day. Immediate delivery syst
Centralization can cut costs. If you have numerous physical sites, you need to pay numerousrents and overheads, staff at all of them, and the costs of
Most successful attacks on computer systems take advantage of well-known weaknesses suchas easily guessed passwords, common misconfigurations, and old
that sell similar things in surrounding areas. New competitors will open occasionally. With e-commerce, the terrain is less certain.Depending on shipp
Deciding on a StrategySome people believe that the Internet changes too fast to allow effective planning. We wouldargue that it is this very changeabi
CHAPTER13E-commerce Security Issues17 7842 CH13 3/6/01 3:36 PM Page 281
E-commerce and SecurityPART III282This chapter discusses the role of security in e-commerce. We will discuss who might be inter-ested in your informat
E-commerce Security IssuesCHAPTER 1313E-COMMERCESECURITY ISSUES283Hobby users will probably have limited time to learn about or work towards securing
INTRODUCTIONCostPHP is free. You can download the latest version at any time from http://www.php.net forno charge.Learning PHPThe syntax of PHP is bas
and should only contain information that either needs to be provided to the public or hasrecently been collected from the public.To reduce the risk of
FIGURE 13.1Transmitting information via the Internet sends your information via a number of potentially untrustworthy hosts.To see the path that data
You can take various measures to reduce the chance of data loss. Secure your servers againstcrackers. Keep the number of staff with access to your mac
File integrity assessment software, such as Tripwire, records information about important files in aknown safe state, probably immediately after insta
Errors in SoftwareIt is possible that the software you have bought, obtained, or written has serious errors in it.Given the short development times no
What is needed is a well-designed test plan that tests all the functions of your software on arepresentative sample of common machine types. A well-pl
An alliance between VISA, a number of financial organizations, and software companies, hasbeen promoting a standard called Secure Electronic Transacti
Creating a Security PolicyA security policy is a document that describes• The general philosophy towards security in your organization• What is to be
nobody else knows or can guess the password, this is secure. Passwords on their own have anumber of potential weaknesses and do not provide strong aut
FIGURE 13.2Web browsers prompt users for authentication when they attempt to visit a restricted directory on a Web server.Both the Apache Web server a
PHP AND MYSQL WEB DEVELOPMENTEase of UseMost modern databases use SQL. If you have used another RDBMS, you should have no troubleadapting to this one.
To create the protected directory whose authentication prompt is shown in Figure 13.2, weused Apache’s most basic type of authentication. (You’ll see
your encrypted messages. As shown in Figure 13.4, both the sender (who encrypts the mes-sage) and the recipient (who decrypts the message) have the sa
The most common public key algorithm is RSA, developed by Rivest, Shamir, and Adelman atMIT and published in 1978. RSA was a proprietary system, but t
When a signed message is received, it can be checked. The signature is decrypted using thesender’s public key. A hash value is generated for the messa
FIGURE 13.6The certificate path for www.equifaxsecure.com shows the network of trust that enables us to trust this site.The most common use for digita
Installation instructions for the two most popular Web servers, Apache and IIS, are inAppendix A, “Installing PHP 4 and MySQL.” You can begin using SS
Log files can help you detect erroneous or malicious behavior as it occurs. They can also tellyou how a problem or break-in occurred if you check them
Backing Up DataYou cannot underestimate the importance of backups in any disaster recovery plan. Hardwareand buildings can be insured and replaced, or
Physical SecurityThe security threats we have considered so far relate to intangibles such as software, but youshould not neglect the physical securit
CHAPTER14Implementing Authenticationwith PHP and MySQL18 7842 CH14 3/6/01 3:35 PM Page 303
IN THIS PART1 PHP Crash Course 92 Storing and Retrieving Data 493 Using Arrays 694 String Manipulation and Regular Expressions 935 Reusing Code and Wr
E-commerce and SecurityPART III304This chapter will discuss how to implement various PHP and MySQL techniques for authenti-cating a user.Topics includ
their customers’ details when they make their first order. This means that a customer is notrequired to type her details every time.Having asked for a
FIGURE 14.2When users enter incorrect details, we need to give them an error message. On a real site, you might want to give asomewhat friendlier mess
<form method = post action = “secret.php”><table border = 1><tr><th> Username </th><td> <input type = text name
Storing PasswordsThere are many better places to store usernames and passwords than inside the script. Insidethe script, it is difficult to modify the
</tr></table></form><?}else{// connect to mysql$mysql = mysql_connect( ‘localhost’, ‘webauth’, ‘webauth’ );if(!$mysql){echo ‘Cann
// visitor’s name and password combination are not correctecho “<h1>Go Away!</h1>”;echo “You are not authorized to view this resource.”;}}
The PHP function crypt() provides a one-way cryptographic hash function. The prototype forthis function isstring crypt (string str [, string salt])Giv
Protecting Multiple PagesMaking a script like this protect more than one page is a little harder. Because HTTP is state-less, there is no automatic li
browser is then responsible for displaying a dialog box or similar device to get required infor-mation from the user.Although the Web server requests
02 7842 part 1 3/6/01 3:42 PM Page 8
Using Basic Authentication in PHPPHP scripts are generally cross-platform, but using basic authentication relies on environmentvariables set by the se
The code in Listing 14.4 acts in a very similar way to the previous listings in this chapter. Ifthe user has not yet provided authentication informati
Using Basic Authentication with Apache’s .htaccessFilesWe can achieve very similar results to the previous script without writing a PHP script.The Apa
LISTING 14.7 .htaccess—An .htaccess File Can Set Many Apache Configuration Settings,Including Activating AuthenticationErrorDocument 401 /chapter14/re
Like the PHP example, to use HTTP authentication, we need to name our realm as follows:AuthName “Realm-Name”You can choose any realm name you prefer,
The optional m, d, p, or s switches can be used if you want to specify which encryption algo-rithm (including no encryption) you would like to use.The
FIGURE 14.5The Microsoft Management Console allows us to configure Internet Information Server 5.To add basic authentication to the protected director
In order to duplicate the behavior of the previous examples, we will also provide a page to tellusers that their authentication details were not corre
Using mod_auth_mysql AuthenticationAs already mentioned, using mod_auth with Apache is easy to set up and is effective. Becauseit stores users in a te
5. After following the other steps in Appendix A, you will need to create a database andtable in MySQL to contain authentication information. This doe
CHAPTER1PHP Crash Course03 7842 CH01 3/6/01 3:39 PM Page 9
specify basic authentication and give a realm name. As in Listing 14.7, we will allow anyvalid, authenticated user access.Because we are using mod_aut
The documentation for mod_auth_mysql can be found athttp://www.zend.comorhttp://www.express.ru/docs/mod_auth_mysql_base.htmlNextThe next chapter expla
18 7842 CH14 3/6/01 3:35 PM Page 326
CHAPTER15Implementing SecureTransactions with PHP andMySQL19 7842 CH15 3/6/01 3:40 PM Page 327
E-commerce and SecurityPART III328In this chapter, we will explain how to deal with user data securely from input, through trans-mission, and in stora
the user’s browser sending a request through the Internet to the Web server. If the page is aPHP script, the Web server will delegate processing the p
We will look at the cURL library, which can be used to simulate connections from a browser,in Chapter 17, “Using Network and Protocol Functions.” This
• Decide that your information is too sensitive to risk any chance of interception and findanother way to distribute your information.The Internet is
One specific thing to consider when installing PHP is that it is generally more secure, as wellas much more efficient, to install PHP as a SAPI module
Networking protocols and the software that implements them are usually arranged as a stack oflayers. Each layer can pass data to the layer above or be
Using PHPPART I10This chapter gives you a quick overview of PHP syntax and language constructs. If you arealready a PHP programmer, it might fill some
SSL is theoretically capable of providing a secure transmission environment for protocols otherthan HTTP, but is normally only used for HTTP. Other pr
FIGURE 15.4SSL breaks up, compresses, hashes, and encrypts data before sending it.One thing you might notice from the diagram is that the TCP header i
Screening User InputOne of the principles of building a safe Web application is that you should never trust userinput. Always screen user data before
not have permission to write or create new files in directories that can be loaded from the Webserver. If you allow others to write files here, they c
the Web server. If you are not the administrator for your Web server (as is likely the case if youare sharing a server), it might be worth discussing
To obtain PGP for use outside the USA and Canada, see the list of international download sitesat the international PGP page:http://www.pgpi.orgAn Open
For a Windows server, the process is just as easy. Download the zip file, unzip it and placegpg.exe somewhere in your PATH. (C:\Windows\ or similar wi
Log in to your account on the Web server and change the permissions on the file so that otherusers will be able to read it. Typechmod 644 filenameYou
Options within this program include help, which will describe the available commands—trust, sign, and save.Type trust and tell GPG that you trust your
If you have GPG set up so that the user your PHP scripts run as can use it from the commandline, you are most of the way there. If this is not working
Using PHPIn order to work through the examples in this chapter and the rest of the book, you will needaccess to a Web server with PHP installed. To ge
//create a unique file name$infile = tempnam(“”, “pgp”);$outfile = $infile.”.asc”;//write the user’s text to the file$fp = fopen($infile, “w”);fwrite(
<p>Your message could not be encrypted, so has not been sent.<p>Sorry.”;}?>In order to make this code work for you, you will need to ch
While we are thinking about the security of our script, it is important to consider all flows ofinformation within our system. GPG will encrypt our em
Currently, our open form tag looks like this:<form method = post action = send_private_mail.php>We could alter it to send data via SSL even if t
19 7842 CH15 3/6/01 3:40 PM Page 348
IN THIS PART16 Interacting with the File System and the Server 35117 Using Network and Protocol Functions 36918 Managing the Date and Time 39119 Gener
20 7842 part 4 3/6/01 3:35 PM Page 350
CHAPTER16Interacting with the FileSystem and the Server21 7842 CH16 3/6/01 3:40 PM Page 351
Advanced PHP TechniquesPART IV352In Chapter 2, “Storing and Retrieving Data,” we saw how to read data from and write data tofiles on the Web server. I
As you can see, the form has a box where the user can enter a filename, or click the Browsebutton to browse files available to him locally. You might
Part of the HTML for this is shown in Listing 1.1. There are two important things to notice inthis code.LISTING 1.1 orderform.html—HTML for Bob’s Basi
You can choose whatever name you like for the file, but keep it in mind as you will usethis name to access your file from the receiving PHP script.Wri
<?if ($userfile==”none”){echo “Problem: no file uploaded”;exit;}if ($userfile_size==0){echo “Problem: uploaded file is zero length”;exit;}if ($user
echo “Preview of uploaded file contents:<br><hr>”;echo $contents;echo “<br><hr>”;?></body></html><?// This f
Finally we display the contents of the file so the user can see that their file uploaded successfully.The results of one (successful) run of this scri
Common ProblemsThere are a few things to keep in mind when performing file uploads.• The previous example assumes that users have been authenticated e
LISTING 16.3 browsedir.php—A Directory Listing of the Uploaded Files<html><head><title>Browse Directories</title></head>
FIGURE 16.3The directory listing shows all the files in the chosen directory, including the . (the current directory) and .. (one levelup) directories
Creating and Deleting DirectoriesIn addition to passively reading information about directories, you can use the PHP functionsmkdir() and rmdir() to c
echo “<a href=\”filedetails.php?file=”.$file.”\”>”.$file.”</a><br>”;}We can then create the script filedetails.php to provide furthe
?></body></html>The results of one sample run of Listing 16.4 are shown in Figure 16.4.Interacting with the File System and the ServerC
You might want to consider adopting a coding standard for field names so that all field namesthroughout your site use the same format. This makes it e
The fileperms() function returns the permissions on the file. We have reformatted them as anoctal number using the decoct() function to put them into
Creating, Deleting, and Moving FilesYou can use the file system functions to create, move, and delete files.First, and most simply, you can create a f
There are four techniques you can use to execute a command on the Web server. They are allpretty similar, but there are some minor differences.1. exec
LISTING 16.5 progex.php—File Status Functions and Their Results<?echo “<pre>”;// exec versionexec(“ls -la”, $result);foreach ($result as $lin
Note that the environment we are talking about here is the environment in which PHP runs onthe server.You can get a list of all PHP’s environment vari
CHAPTER17Using Network and ProtocolFunctions22 7842 CH17 3/6/01 3:39 PM Page 369
Advanced PHP TechniquesPART IV370In this chapter, we’ll look at the network-oriented functions in PHP that enable your scripts tointeract with the res
Sending and Reading EmailThe main way to send mail in PHP is to use the simple mail() function. We discussed the useof this function in Chapter 4, “St
LISTING 17.1 lookup.php—Script Retrieves a Stock Quote from the NASDAQ for theStock with the Ticker Symbol Listed in $symbol<html><head>&l
FIGURE 17.1The script uses a regular expression to pull out the stock quote from information retrieved from NASDAQ.The script itself is pretty straigh
PART V Building Practical PHP and MySQL Projects22 Using PHP and MySQL for Large Projects 45923 Debugging 47724 Building User Authentication and Perso
FIGURE 1.2Text passed to PHP’s echo construct is echoed to the browser.None of the raw PHP is visible. This is because the PHP interpreter has run thr
You can use this approach for a variety of purposes. Another good example is retrieving localweather information and embedding it in your page.The bes
<form method=post action=”directory_submit.php”>URL: <input type=text name=”url” size=30 value=”http://”><br>Email contact: <inpu
The script that performs these checks uses two functions from the PHP network functionssuite—gethostbyname() and getmxrr(). The full script is shown i
?></body></html>Lets’ go through the interesting parts of this script.First, we take the URL and apply the parse_url() function to it.
If the URL is valid, we then go on to check the email address. First, we split it into usernameand hostname with a call to explode():$email = explode(
Using FTP to Back Up or Mirror a FileThe FTP functions are useful for moving and copying files from and to other hosts. One com-mon use you might make
echo “Checking file time...<br>”;if (file_exists($localfile)){$localtime = filemtime($localfile);echo “Local file last updated “;echo date(“G:i
?></body></html>The output from running this script on one occasion is shown in Figure 17.4.Using Network and Protocol FunctionsCHAPTER
The basic steps we follow in this script are the same as if you wanted to manually FTP the filefrom a command line interface:1. Connect to the remote
The function takes three parameters: an FTP connection (obtained from ftp_connect()), ausername, and a password. It will return true if the user can b
Different tag styles are available. This is the short style. If you have some problems runningthis script, it might be because short tags are not enab
useful result from the function. In this case, we choose to artificially set the $remotetime vari-able to be “newer” than the $localtime variable by a
There are two modes for an FTP transfer, ASCII and binary. The ASCII mode is used for trans-ferring text files (that is, files that consist solely of
Avoiding TimeoutsOne problem you might face when FTPing files is exceeding the maximum execution time.You will know whether this happens because PHP w
In terms of other FTP functions, almost anything that you can do from an FTP command line,you can do with the FTP functions. You can find the specific
The only things that change with the application are the URL that you connect to and the para-meters you set with curl_opt(). There are a large number
The curl_setopt() function takes three parameters. The first is the session handle, the secondis the name of the parameter to set, and the third is th
The cURL Web site has some tips on how to use the command line versions of the cURL func-tions, and these are fairly easily translated into the PHP ve
CHAPTER18Managing the Date and Time23 7842 CH18 3/6/01 3:43 PM Page 391
Advanced PHP TechniquesPART IV392In this chapter, we’ll discuss checking and formatting the date and time and convertingbetween date formats. This is
D Day of the week in 3-character abbreviated text format. Range is from“Mon” to “Sun”.F Month of the year in full text format. Range is from “January”
As you have probably guessed, using the echo construct has a very simple result; it prints (orechoes) the string passed to it to the browser. In Figur
w Day of the week as a single digit. Range is from “0” (Sunday) to “6”(Saturday).y Year in 2-digit format, for example, “00”.Y Year in 4-digit format,
you can pass in 0s to the hour, minute, and second parameters. You can, however, leave outvalues from the right side of the parameter list. If you lea
Validating DatesYou can use the checkdate() function to check whether a date is valid. This is especially use-ful for checking user input dates. The c
The format code %m represents the month as a 2-digit number; %d, the day as a 2-digit number;and %Y, the year as a 4-digit number. A summary of the mo
will return the date formatted as a UNIX time stamp. You can then do as you will with it in PHP.As a rule of thumb, use a UNIX timestamp for date calc
Now, the slightly tricky part—to convert this time period back to a more human-friendly unitof measure. This is not a time stamp but instead the age o
Further ReadingIf you’d like to read more about date and time functions in PHP and MySQL, you can consultthe relevant sections of the manuals athttp:/
CHAPTER19Generating Images24 7842 CH19 3/6/01 3:42 PM Page 401
Advanced PHP TechniquesPART IV402One of the useful things you can do with PHP is create images on-the-fly. PHP has some built-in image information fun
Image FormatsThe GD library supports JPEG, PNG, and WBMP formats. It no longer supports the GIF for-mat. Let’s briefly look at each of these formats.J
way they did, when it was last modified, and so on. You will generally find comments in allbut the simplest PHP scripts.The PHP interpreter will ignor
GIFGIF stands for Graphics Interchange Format. It is a compressed lossless format widely used onthe Web for storing images containing text, straight l
3. Outputting the final graphic4. Cleaning up resourcesWe’ll begin by looking at a very simple image creation script. This script is shown in Listing
FIGURE 19.1The script draws a black background and then adds a line and a text label for the image.An alternative way is to read in an existing image
The function returns a color identifier that we can use to access the color later on.Second, to actually draw into the image, a number of different fu
It takes as parameters the image identifier, the font, the x and y coordinates to start writing thetext, the text to write, and the color.The font is
This tells the browser how to interpret the data that follows.In this case, we want to tell the browser that we are sending an image instead of the us
Cleaning UpWhen you’re done with an image, you should return the resources you have been using to theserver by destroying the image identifier. You ca
FIGURE 19.3The dynamically produced inline image appears the same as a regular image to the end user.We will also use TrueType fonts so that we can us
FIGURE 19.4The front end lets a user choose the button color and type in the required text.Advanced PHP TechniquesPART IV412FIGURE 19.5A button genera
if (empty($button_text) || empty($color)){echo “Could not create image - form not filled out correctly”;exit;}// create an image of the right backgrou
FIGURE 1.3PHP’s date() function returns a formatted date string.Calling FunctionsLook at the call to date(). This is the general form that function ca
{// We have found a font size that will fit// Now work out where to put it$text_x = $width_image/2.0 - $width_text/2.0;$text_y = $height_image/2.0 - $
The function ImageCreateFromPNG() takes the filename of a PNG as a parameter, and returnsa new image identifier for an image containing a copy of that
// find out the size of the text at that font size$bbox=imagettfbbox ($font_size, 0, “arial.ttf”, $button_text);$right_text = $bbox[2]; // right co-
TABLE 19.1 Contents of the Bounding Box ArrayArray Index Contents0 X coordinate, lower-left corner1 Y coordinate, lower-left corner2 X coordinate, low
After we have this, we test the loop condition:} while ( $font_size>8 &&( $height_text>$height_image_wo_margins ||$width_text>$width_
Writing the Text onto the ButtonAfter that, it’s all smooth sailing. We set up the text color, which will be white:$white = ImageColorAllocate ($im, 2
Graphing is the other thing these functions are primarily used for. You can chart any data youwant—sales, Web hits, or whatever takes your fancy.For t
<input type=radio name=vote value=”John Smith”>John Smith<br><input type=radio name=vote value=”Mary Jones”>Mary Jones<br><
FIGURE 19.8Vote results are created by drawing a series of lines, rectangles, and text items onto a canvas.The new parts of this script relate to draw
// get current results of poll, regardless of whether they voted$query = “select * from poll_results”;if(!($result = @mysql_query($query, $db_conn))){
Accessing Form VariablesThe whole point of using the order form is to collect the customer order. Getting the details ofwhat the customer typed in is
Part 2 sets up some variables that we will use to actually draw the graph.Working out the values for these sorts of variables can be tedious, but a bi
$text_color = $black;$percent_color = $black;$bg_color = $white;$line_color = $black;$bar_color = $blue;$number_color = $pink;// Create “canvas” to dr
to draw a black outline around the edge of the canvas. This function draws an outlined rectan-gle instead of a filled one. The parameters are the same
ImageFilledRectangle($im, $x, $y-2, $bar_length, $y+$bar_height, $bar_color);// draw title for this valueImageTTFText($im, $main_size, 0, $text_indent
This is a long-ish script, but can be easily adapted to suit your needs, or to auto-generate pollsvia an interface. One important feature that this sc
CHAPTER20Using Session Control in PHP25 7842 CH20 3/6/01 3:42 PM Page 429
Advanced PHP TechniquesPART IV430This chapter will discuss the session control functionality in PHP 4.We will cover• What session control is• Cookies•
the server. (You can change this to use a database if you are willing to write your own function—more on this in the section “Configuring Session Cont
You can delete a cookie by calling setcookie() again with the same cookie name but novalue. If you set the cookie with other parameters (such as speci
It is generally easier to compile with --enable-trans-sid, where possible. Note also that theSID constant will only work like this if you have configu
There are two ways of accessing the form data via variables.In this example, and throughout this book, we have used the short style for referencing fo
Note that you need to pass a string containing the name of the variable tosession_register(). This string should not include the $ symbol.This will re
When you are finished with a session, you should first deregister all the variables and then callsession_destroy();to clean up the session ID.Simple S
Notice that we change the value after the variable has been registered. We could also do theopposite—set the value and then register the variable. The
LISTING 20.3 page3.php—Ending the Session<?session_start();echo “The content of \$sess_var is $sess_var<br>”;session_destroy();?>As you ca
session.cookie_path / Path to set in session cookie.session.name PHPSESSID The name of the session that is used asthe cookie name on a user’s system.s
FIGURE 20.4Because the user has not yet logged in, show her a login page.This page gives the user a place to log in. If she attempts to access the Mem
FIGURE 20.6After the user has logged in, she can access the members’ areas.Let’s look at the code for this application. Most of the code is in authmai
<body><h1>Home page</h1><?if (session_is_registered(“valid_user”)){echo “You are logged in as: $valid_user <br>”;echo “<
The script’s activities revolve around the $valid_user session variable. The basic idea is that ifsomeone logs in successfully, we will register a ses
Because we now know who she is, we don’t need to show her the login form again. Instead,we’ll tell her we know who she is, and give her the option to
This is the string concatenation operator and is used to add strings (pieces of text) together.You will often use it when sending output to the browse
else{echo “<p>You are not logged in.</p>”;echo “<p>Only logged in members may see this page.</p>”;}echo “<a href=\”authmain
else{// if they weren’t logged in but came to this page somehowecho “You were not logged in, and so have not been logged out.<br>”;}?>The cod
25 7842 CH20 3/6/01 3:42 PM Page 446
CHAPTER21Other Useful Features26 7842 CH21 3/6/01 3:41 PM Page 447
Advanced PHP TechniquesPART IV448Some useful PHP functions and features do not fit into any particular category. This chapterwill explain these featur
PHP has a useful capability to automatically or magically add and strip slashes for you. Withtwo settings in your php.ini file, you can turn on or off
Terminating Execution: die and exitSo far in this book we have used the language construct exit to stop execution of a script. Asyou probably recall,
However, you might still want to store a PHP array or object in a file or database. If you do,there are two functions you need to know how to use: ser
The get_loaded_extensions() function returns an array of all the function sets currentlyavailable to PHP. Given the name of a particular function set
You can check the last modification date of a script with the getlastmod() (note the lack ofunderscores in the function name) function, as follows:ech
User-Declared VariablesYou can declare and use your own variables in addition to the variables you are passed fromthe HTML form.One of the features of
$max_execution_time = ini_get(“max_execution_time”);echo “new timeout is $max_execution_time <br>”;?>The ini_set() function takes two paramet
highlight.default = #0000BBhighlight.html = #000000The colors are in standard HTML RGB format.NextPart V, “Building Practical PHP and
26 7842 CH21 3/6/01 3:41 PM Page 456
IN THIS PART22 Using PHP and MySQL for Large Projects 45923 Debugging 47724 Building User Authentication and Personalization 49725 Building a Shopping
27 7842 part 5 3/6/01 3:42 PM Page 458
CHAPTER22Using PHP and MySQL forLarge Projects28 7842 CH22 3/6/01 3:37 PM Page 459
In the earlier parts of this book, we’ve discussed various components of and uses for PHP andMySQL. Although we’ve tried to make all our examples inte
increase the amount of dynamic content in Web sites to the level in which Web sites offer ser-vices rather than documents, this paradigm no longer fit
• Build a prototype, based on all the previous information. Show it to users. Iterate.• Remember that, in all of this, it is important and useful to s
If you end up developing your own functions or components, you should seriously considermaking them available to the PHP community when you have finis
Type StrengthPHP is a very weakly typed language. In most programming languages, variables can onlyhold one type of data, and that type must be declar
It’s also a good idea to distinguish between variables and constants with case—a commonscheme is to use all lowercase for variables (for example, $res
Commenting Your CodeAll programs should be commented to a sensible level. You might ask what level of comment-ing is sensible. Generally you should co
type, they consume a lot of screen space on many people’s monitors. We use an indent level oftwo to three spaces for all projects.The way you lay out
Even if all team members will be working on all pieces of the code, it’s generally a good ideato assign primary responsibility for each component to a
You can solve all these problems with a version control system.These systems can track changes to each file in the repository so that you can see not
Choosing a Development EnvironmentTalking about version control brings up the more general topic of development environments.All you really need are a
Documenting Your ProjectsYou can produce many different kinds of documentation for your programming projects,including, but not limited to the followi
PrototypingPrototyping is a development lifecycle commonly used for developing Web applications. Aprototype is a useful tool for working out customer
presentation from content can be extended to scripting. In general, sites will be easier to useand maintain in the long run if you can separate logic
• Speed up database queries. Reduce the number of queries that you make, and make surethat they are optimized. With a complex (and therefore slow) que
ContentsIntroduction 1Who Should Read This Book? ...1What Is PHP? ...
(As you can see, PHP allows a lot of freedom in this area—all languages will let you changethe value of a variable, but not many will allow you to cha
TestingReviewing and testing code is another basic point of software engineering that is often over-looked in Web development. It’s easy enough to try
site for a client company, they can often supply a good set of naive users by getting staff attheir company to work through the site. (This has the in
28 7842 CH22 3/6/01 3:37 PM Page 476
CHAPTER23Debugging29 7842 CH23 3/6/01 3:41 PM Page 477
This chapter will deal with debugging PHP scripts. If you have been through some of theexamples in the book or used PHP before, you will probably have
If a script does not follow the rules of PHP’s syntax—if it contains syntax errors—the PHPparser will not be able to process some or all of it. Peopl
These errors can be hard to find if they result from a combination of multiple files. They canalso be difficult to find if they occur in a large file.
Common causes of runtime errors include the following:• calls to functions that do not exist• reading or writing files• interaction with MySQL or othe
but except in the, possibly rare, case in which the variable $var has the value 4, the call tostrstr() will not occur, and no warning will be issued.C
If an error occurs, you can access the text of the error message using the functionmysql_error(),or an error code using the function mysql_errno(). If
One important difference between constants and variables is that when you refer to a constant,it does not have a dollar sign in front of it. If you wa
empty table or searching for data that does not exist. Assuming that you have connected to adatabase successfully, and have a table called exists and
This does not mean that you need to attempt to simulate every different error that might occur.MySQL for example can provide one of around 200 differe
Logic errors are not caused by any sort of failure of the code, but merely a failure of the pro-grammer to write code that instructs the computer to d
LISTING 23.1 dump_variables.php—This Code Can Be Included in Pages to Dump theContents of Variables for Debugging<?// these lines format the output
$string .= “ }”;}return $string;}else{// if it is not an array, just return itreturn $array;}}?>This code will iterate through four arrays of varia
the user’s name in—valid_user. As discussed in Chapter 20, PHP uses a cookie to link ses-sion variables to particular users. Our script is echoing the
E_ALL itself is effectively a combination of all the other error types. It could be replaced by theother levels ORed together using the bitwise or ope
Turning track_errors on might help you to deal with errors in your own code, rather than let-ting PHP provide its default functionality. Although PHP
Triggering Your Own ErrorsThe function trigger_error()can be used to trigger your own errors. Errors created in thisway will be handled in the same wa
Logical actions might include• Displaying the error message provided• Storing information in a log file• Emailing the error to an address• Terminating
Arithmetic OperatorsArithmetic operators are very straightforward—they are just the normal mathematical opera-tors. The arithmetic operators are shown
FIGURE 23.1You can give friendlier error messages than PHP if you use your own error handler.This custom error handler does not do any more than the d
If you are still using PHP 3 and have a very troublesome bug that you cannot track down anyother way, you might want to look up the PHP configuration
29 7842 CH23 3/6/01 3:41 PM Page 496
CHAPTER24Building User Authenticationand Personalization30 7842 ch24 3/6/01 3:34 PM Page 497
In this project, we’ll get users to register at our Web site. When they’ve done that, we’ll be ableto keep track of what they’re interested in and sho
Third, we need to be able to recommend to a user sites that might appeal to her, based on whatwe know about her already.Solution ComponentsNow that we
Storing BookmarksTo store a user’s bookmarks, we will need to set up some space in our MySQL database. Wewill need the following functionality:• User
We’ll build a module for each box on this diagram—some will need one script and others,two. We’ll also set up function libraries for• User authenticat
db_fns.php Functions to connect to the databaseuser_auth_fns.php Functions for user authenticationurl_fns.php Functions for adding and deleting bookma
The SQL to create this database, and to create a user for connecting to the database from theWeb, is shown in Listing 24.1. You should edit it if you
String OperatorsWe’ve already seen and used the only string operator. You can use the string concatenationoperator to add two strings and to generate
You will then be prompted to type in your password.With the database set up, let’s go on and implement the basic site.Implementing the Basic SiteThe f
FIGURE 24.3The front page of the PHPBookmark system is produced by the HTML rendering functions in login.php.As you can see, this file is just a conta
LISTING 24.4 do_html_header() Function from output_fns.php—This Function Outputsthe Standard Header That Will Appear on Each Page in the Applicationfu
RegisteringTo register a user, we need to get his details via a form and enter him in the database.When a user clicks on the “Not a member?” link on t
The gray form on this page is output by the function display_registration_form(),contained in output_fns.php. When the user clicks on the Register but
}// check password length is ok// ok if username truncates, but passwords will get// munged if they are too long.if (strlen($passwd)<6 || strlen($p
This is the first script with any complexity to it that we have looked at in this application.The script begins by including the application’s functio
LISTING 24.8 valid_email() Function from data_valid_fns.php—This Function ChecksWhether an Email Address Is Validfunction valid_email($address){// che
FIGURE 24.5Registration was successful—the user can now go to the members page.The register() function is in the included library called user_auth_fns
$result = mysql_query(“insert into user values(‘$username’, password(‘$password’), ‘$email’)”);if (!$result)return “Could not register you in databas
Combination Assignment OperatorsIn addition to the simple assignment, there is a set of combined assignment operators. Each ofthese is a shorthand way
LISTING 24.11 member.php—This Script is the Main Hub of the Application<?// include function files for this applicationrequire_once(“bookmark_fns.p
First, we check whether the user has come from the front page—that is, whether he has justfilled in the login form—and try to log them in as follows:i
FIGURE 24.6The member.php script checks that a user is logged in; retrieves and displays his bookmarks; and gives hima menu of options.We will now loo
return 0;if (mysql_num_rows($result)>0)return 1;elsereturn 0;}As you can see, this function connects to the database and checks that there is a use
Logging OutYou might have noticed that there is a link marked “Logout” on the menu in Figure 24.6. Thisis a link to the logout.php script. The code fo
Changing PasswordsIf a user follows the ”Change Password” menu option, he will be presented with the formshown in Figure 24.7.Building User Authentica
display_user_menu();do_html_footer();exit;}else{if ($new_passwd!=$new_passwd2)echo “Passwords entered were not the same. Not changed.”;else if (strle
// return true or false{// if the old password is right// change their password to new_password and return true// else return falseif (login($username
FIGURE 24.8The forgot_form.php script supplies a form in which users can ask to have their passwords reset and sent tothem.LISTING 24.17 forgot_passwd
As you can see, this script uses two main functions to do its job: reset_password() andnotify_password(). Let’s look at each of these in turn.The rese
However, if the ++ is after the $a, we are using the post-increment operator. This has a differ-ent effect. Consider the following:$a=4;echo $a++;In t
LISTING 24.19 The get_random_word() Function from user_auth_fns.php—This FunctionGets a Random Word from the Dictionary for Use in Generating Password
The function has two clever bits. The first is that, if we reach the end of the file while lookingfor a word, we go back to the beginning:if (feof($fp
It would be more secure to give users a truly random password—made from any combinationof upper and lowercase letters, numbers, and punctuation—rather
LISTING 24.21 add_bms.php—This Script Adds New Bookmarks to a User’s Personal Page<?require_once(“bookmark_fns.php”);session_start();do_html_header
Again this script follows the pattern of validation, database entry, and output.To validate, we first check whether the user has filled out the form u
This function is fairly simple. It checks that a user does not already have this bookmark listedin the database. (Although it is unlikely that they wo
The array from get_user_urls() can be passed to display_user_urls(). This is again a sim-ple HTML output function to print the user’s URLs in a nice t
elseecho “Could not delete “.htmlspecialchars($url).”.<br>”;}}elseecho “No bookmarks selected for deletion”;}// get the bookmarks this user has
As you can see, this is again a pretty simple function. It attempts to delete the bookmark for aparticular user from the database. One thing to note i
However, as you might recall, MySQL does not support subqueries. We will have to performtwo different queries and feed the output of the first into th
It is easy to confuse this with =, the assignment operator. This will work without giving anerror, but generally will not give you the result you want
The full script for making recommendations is shown in Listing 24.26 and 24.27. The mainscript for making recommendations is called recommend.php (see
// create set of users with urls in common// for use in IN clause$row = mysql_fetch_object($result);$sim_users = “(‘“.($row->username).”’”;while ($
if (!($num_urls=mysql_num_rows($result)))return false;$urls = array();// build an array of the relevant urlsfor ($count=0; $row = mysql_fetch_object($
Wrapping Up and Possible ExtensionsThat’s the basic functionality of the PHPBookmark application. There are many possibleextensions. You might conside
30 7842 ch24 3/6/01 3:34 PM Page 538
CHAPTER25Building a Shopping Cart31 7842 CH25 3/6/01 3:38 PM Page 539
Building Practical PHP and MySQL ProjectsPART V540In this chapter, you will learn how to build a basic shopping cart. We will add this on top of theBo
We’ll also need to add some information to our existing database about shipping addresses,payment details, and so on.We already know how to build an i
We can work out the total of an order from a user’s shopping cart session variable. We willrecord the final order details in the database, and get rid
FIGURE 25.2The administrator view of the Book-O-Rama system allows insertion, editing, and deletion of books and categories.In Figure 25.1, we show th
PHP supports logical AND, OR, XOR (exclusive or), and NOT.The set of logical operators and their use is summarized in Table 1.4.TABLE 1.4 PHP’s Logica
As in the last project, we will also build and use a set of function libraries. For this project, wewill use a function API similar to the one in the
insert_category.php Administration Inserts new category into database.insert_book_form.php Administration Form to let administrator add a newbook to s
Implementing the DatabaseAs we mentioned earlier, we have made some minor modifications to the Book-O-Rama data-base presented in Part II.The SQL to c
orderid int unsigned not null auto_increment primary key,customerid int unsigned not null,amount float(6,2),date date not null,order_status char(10),s
grant select, insert, update, deleteon book_sc.*to book_sc@localhost identified by ‘password’;Although nothing was wrong with the original Book-O-Rama
The front page of the site is produced by the script called index.php. The output of this scriptis shown in Figure 25.3.Building a Shopping CartCHAPTE
FIGURE 25.4Each book in the category is listed with a photo.Building Practical PHP and MySQL ProjectsPART V550FIGURE 25.5Each book has a details page
Listing CategoriesThe first script, index.php, lists all the categories in the database. It is shown in Listing 25.2.LISTING 25.2 index.php—Script to
The functions get_categories() and display_categories() are in the function librariesbook_fns.php and output_fns.php, respectively. The function get_c
In our case, we will return this array back all the way to index.php, where we pass it to thedisplay_categories() function from output_fns.php. This f
Other OperatorsIn addition to the operators we have covered so far, there are a number of others.The comma operator, , ,is used to separate function a
$name = get_category_name($catid);do_html_header($name);// get the book info out from db$book_array = get_books($catid);display_books($book_array);//
$result = @mysql_query($query);if (!$result)return false;$num_cats = @mysql_num_rows($result);if ($num_cats ==0)return false;$result = mysql_result($r
// set url for “continue button”$target = “index.php”;if($book[“catid”]){$target = “show_cat.php?catid=”.$book[“catid”];}// if logged in as admin, sho
Implementing the Shopping CartThe shopping cart functionality all revolves around a session variable called $cart. This is anassociative array that ha
In this case, we have clicked the View Cart link when our cart is empty; that is, we have notyet selected any items to purchase.Figure 25.7 shows our
LISTING 25.9 show_cart.php—This Script Controls the Shopping Cart<?include (‘book_sc_fns.php’);// The shopping cart needs sessions, so start oneses
echo “<p>There are no items in your cart”;echo “<hr>”;}$target = “index.php”;// if we have just added an item to the cart,// continue shop
output_fns.php, which is included here as Listing 25.10. Although it is a display function, itis reasonably complex, so we include it here.LISTING 25.
echo “</td><td align = center>$”.number_format($book[“price”], 2);echo “</td><td align = center>”;// if we allow changes, quan
2. Provide an image for each book, if one exists. We use the HTML image height and widthtags to resize the image a little smaller here. This means tha
For example, under UNIX-like operating systems, you can use$out = `ls -la`;echo “<pre>”.$out.”</pre>”;or, equivalently on a Windows server
Third, we need to work out the total price and number of items in the cart. For this, we use thecalculate_price() and calculate_items() functions, as
if(is_array($cart)){foreach($cart as $isbn => $qty){$items += $qty;}}return $items;}The calculate_items() function is simpler—it just goes through
(We covered variable variables in Chapter 1, “PHP Crash Course.”) As a reminder, when werefer to $$isbn, we are actually referring to the variable who
FIGURE 25.8The checkout.php script gets the customer’s details.LISTING 25.13 checkout.php—This Script Gets the Customer Details<?//include our func
display_button(“show_cart.php”, “continue-shopping”, “Continue Shopping”);do_html_footer();?>There are no great surprises in this script. If the ca
session_start();do_html_header(“Checkout”);// if filled outif($from==’process’||$cart&&$name&&$address&&$city&&$zip&am
The logic here is straightforward: We check that the user filled out the form and inserteddetails into the database using a function called insert_ord
if (!$result)return false;}$query = “select customerid from customers wherename = ‘$name’ and address = ‘$address’and city = ‘$city’ and state = ‘$sta
$query = “delete from order_items whereorderid = $orderid and isbn = ‘$isbn’”;$result = mysql_query($query);$query = “insert into order_items values(
FIGURE 25.10This transaction was successful, and the items will now be shipped.The code for process.php can be found in Listing 25.16.LISTING 25.16 pr
PHP AND MYSQL WEB DEVELOPMENTviAccessing Form Variables ...19Form Variables ...
FIGURE 1.5The totals of the customer’s order have been calculated, formatted, and displayed.The total amount seems to be correct, but why were the mul
//empty shopping cartsession_destroy();echo “Thankyou for shopping with us. Your order has been placed.”;display_button(“index.php”, “continue-shoppi
As with other places where we directly refer to $HTTP_POST_VARS, you need to havetrack_vars enabled for this to work. We process the user’s card, and,
FIGURE 25.11Users must pass through the login page to access the admin functions.Building Practical PHP and MySQL ProjectsPART V576FIGURE 25.12The adm
The code for the admin menu is shown in Listing 25.17.LISTING 25.17 admin.php—This Script Authenticates the Administrator and Lets HerAccess the admin
We identify the administration user after login by means of the $admin_user session variableand the check_admin_user() function. This function and the
LISTING 25.18 insert_book.php—This Script Validates the New Book Data and Puts Itinto the Database<?// include function files for this applicationr
FIGURE 25.14The show_book.php script produces different output for an administrative user.The administrator has access to two new options on this page
FIGURE 25.15The edit_book_form.php script gives the administrator access to edit book details or delete a book.This is, in fact, the same form we used
// most of the form is in plain HTML with some// optional PHP bits throughout?><form method=postaction=”<?=$edit?”edit_book.php”:”insert_book
<td>Price:</td><td><input type=text name=pricevalue=”<?=$edit?$book[“price”]:””; ?>”></td></tr><tr><
left xorleft andright printleft = += -= *= /= .= %= &= |= ^= ~= <<= >>=left ? :left ||left &&left |left ^left &n/a == != =
If we pass in an array containing the book data, the form will be rendered in edit mode andwill fill in the fields with the existing data:<input ty
This has a lot of advanced features such as customer tracking, timed sales, multiple languages,credit card processing, and support for multiple online
31 7842 CH25 3/6/01 3:39 PM Page 586
CHAPTER26Building a ContentManagement System32 7842 ch26 3/6/01 3:36 PM Page 587
In this chapter, we’ll look at a content management system for storing, indexing, and searchingtext and multimedia content.Content management systems
Editing ContentFirst, we need to think about how we will get content into the system, and how we will storeand edit that content.Getting Content into
Databases Versus File StorageAn important decision to make at an early stage is how the content will be stored after it hasbeen uploaded into the syst
Document StructureThe example stories we will be using are short one- or two-paragraph news stories with a sin-gle image, designed for people in a hur
We can then develop a search engine algorithm that ranks matches according to this human-specified relevance for stories, rather than a complex algori
Implementing a templated structure such as this from a page design is very simple. In theHTML source, you will find the <TD> where the main cont
You can use as many sets of parentheses as you like in an expression. The innermost set ofparentheses will be evaluated first.Variable FunctionsBefore
$height = $size[1];$x_ratio = $max_width / $width;$y_ratio = $max_height / $height;if ( ($width <= $max_width) && ($height <= $max_heigh
The key to the resize operation is the calculation of the new width and height parameters. Wefind the ratio between the actual and maximum dimensions.
logo.gif Image The logo file displayed in header.phpheadlines.php Application Shows the most recent headline from eachpage of the sitepage.php Applica
Designing the DatabaseListing 26.2 shows the SQL queries used to create the database for the content system. Thislisting is part of the file create_da
create table writer_permissions (writer varchar(16) not null, # foreign key writers.usernamepage varchar(16) not null
LISTING 26.3 headlines.php Shows the Most Recent Headline from Each Page<?include (“include_fns.php”);include (“header.php”);$conn = db_connect();$
The hard work is done by two database queries. First,select * from pages order by codewill retrieve the list of pages that are in the database. Next t
LISTING 26.4 page.php Displays All the Published Stories on a Page<?include (“include_fns.php”);include (“header.php”);$conn = db_connect();if (!$p
will send the visitor back to the headline page so that the omission of $page will not cause anerror.The first queryselect * from storieswhere page =
Building a Content Management SystemCHAPTER 2626CONTENTMANAGEMENTSYSTEMS603FIGURE 26.5The story management page for writers.These screens are not form
Testing Variable StatusPHP has several functions for testing the status of a variable.The first of these is isset(), which has the following prototype
</TR></TABLE><INPUT TYPE=SUBMIT VALUE=”Log in”></FORM><?}else {$conn = db_connect();$w = get_writer_record($auth_user);echo
echo “[<A HREF=\”story.php?story=”.$qry[id].”\”>edit</A>] “;echo “[<A HREF=\”delete_story.php?story=”.$qry[id].”\”>delete</A>]
All this information is shown on the stories screen, first withecho date(“M d, H:i”, $qry[created]);and thenecho date(“M d, H:i”, $qry[modified]);and
The complete listing of story.php can be seen in listing 26.6.LISTING 26.6 story.php Is Used to Create or Edit a Story<?include (“include_fns.php”)
</TR><TR><TD ALIGN=CENTER><INPUT TYPE=FILE NAME=”html” SIZE=40></TD></TR><TR><TD ALIGN=CENTER>Picture&
If $story is not set, the preceding code will produce no value from the PHP statement, so theheadline input box will be blank. If $story is set, it wi
set headline = ‘$headline’,story_text = ‘$story_text’, page = ‘$page’,modified = $timewhere id = $story”;}else { // It’s a new story$sql = “in
The delete story link calls delete_story.php, which actions a simple DELETE statement andreturns the writer to the calling page. The code for delete_s
FIGURE 26.7Setting keywords for a story.The search form in search_form.php contains a single field for keywords, and submits tosearch.php, which queri
}$and .= “and ($k_string) “;}$sql = “select s.id,s.headline,10 * sum(k.weight) / $num_keywords as scorefrom stories s, keywords kwhere s.id = k.story$
Each of these accepts a variable as input and returns the variable’s value converted to theappropriate type.Control StructuresControl structures are t
else$k_string .= “k.keyword = ‘“.$k[$i].”’ “;}$and .= “and ($k_string) “;}This code uses the PHP function split() to create an array containing each w
$conn = db_connect();$sql = “select * from stories order by modified desc”;$result = mysql_query($sql, $conn);echo “<H2>Editor admin</H2>”
This will mark a story as published and authorize it for public viewing.Similarly, unpublish_story.php uses the following query to mark a story as unp
CHAPTER27Building a Web-Based EmailService33 7842 CH27 3/6/01 3:41 PM Page 617
Building Practical PHP and MySQL ProjectsPART V618More and more often these days, sites want to offer Web-based email to their users. This chap-ter ex
Solution ComponentsPHP has excellent IMAP and POP3 support, but it is provided via the IMAP function library. Inorder to use the code presented in thi
For a user to read his mail, we will need to get his server and account details. Rather than get-ting these details from the user every time, we’ll se
We will also give him the option of viewing detailed headers for a particular message. Viewingthe complete headers can tell you a lot about a message.
Setting Up the DatabaseThe database for Warm Mail is fairly simple because we aren’t actually going to store any ofthe emails in it.We will need to st
create table accounts(username char(16) not null,server char(100) not null,port int not null,type char(4) not null,remoteuser char(50) not null,remote
echo “<font color=red>”;echo “You did not order anything on the previous page!<br>”;echo “</font>”;}The three lines of code enclosed
//*****************************************************************************// Stage 1: pre-processing// Do any required processing before page hea
store_account_settings($auth_user, $HTTP_POST_VARS);break;}case ‘select-account’ :{// if have chosen a valid account, store it as a session variableif
//display any text generated by functions called before headerecho $status;if(!check_auth_user()){echo “<P>You need to log in”;if($action&&a
case ‘view-message’ :{// if we have just picked a message from the list, or were looking at// a message and chose to hide or view headers, load a mess
display_new_message_form($auth_user, $to, $cc, $subject, $body);}break;}case ‘forward’ :{//set message as quoted body of current messageif(!$imap)$ima
The four main sections to the script are as follows:1. We do some processing that must take place before we send the page header to thebrowser, such a
This is the default behavior for the application. With no $action chosen yet, and no logindetails supplied, we will execute the following parts of the
FIGURE 27.3After successful login, the user can begin using the application.On this execution of the script, we will activate different sections of co
In addition to setting up the buttons we saw while not logged in, we add another button toallow the user to log out again, as follows:if(check_auth_us
Look back at the script in Listing 27.2. This time around because of the value of $action,weget different behavior.We get a slightly different header,
if( $totalqty == 0){echo “You did not order anything on the previous page!<br>”;}else{if ( $tireqty>0 )echo $tireqty.” tires<br>”;if (
function will display the form that we can see in Figure 27.4. You can see that we use it in twodifferent ways here: We use it with no parameters to d
LISTING 27.5 store_account_settings() Function from mail_fns.php—Function to SaveNew Account Details for a Userfunction store_account_settings($auth_u
As you can see, we then execute the display_account_setup() function as before to list theuser’s account details. The newly added account will now be
After execution returns to index.php, the body stage will run the following code:case ‘store-settings’ :case ‘account-setup’ :case ‘delete-account’ :{
$query = “select count(*) from accounts where username = ‘$auth_user’”;if(db_connect()){$result = mysql_query($query);if($result)return mysql_result($
This SELECT option is generated in the do_html_header() function from output_fns.php,asshown in the following code fragment:<?// include the accoun
Choosing one of the options in the SELECT activates the select_account event. If you look atthe URL in Figure 27.5, you can see this appended to the e
echo “No mailbox selected<br><br><br><br><br><br>.”;}else{$imap = open_mailbox($auth_user, $accountid);if($imap){e
We open the mailbox for a user account with a call to the open_mailbox() function that wehave written in mail_fns.php. This function is shown in Listi
If the protocol is not specified, it defaults to IMAP. In the code we have written, you cansee that we specify POP3 if the user has specified that pro
switch StatementsThe switch statement works in a similar way to the if statement, but allows the condition totake more than two values. In an if state
The messageid is the sequence number used in the headers we retrieved earlier. Note thatIMAP messages are numbered from 1, not 0.If the user clicks on
The line$fullheaders = ($action==’show-headers’);could have been more verbosely—and perhaps more clearly—written asif($action==’show-headers’)$fullhea
$message[‘subject’] = $header->subject;$message[‘fromaddress’] = $header->fromaddress;$message[‘toaddress’] = $header->toaddress;$message
Finally we close the mailbox with imap_close() and return the array we have built. The display_message() function can then display the message’s field
Deleting MailIf a user clicks the Delete button on a particular email, he will activate the “delete” action.This will execute the following code from
Sending MailFinally we come to sending mail. There are a few ways to do this from this script: The usercan send a new message, reply to, or forward ma
Clicking the Send Message button invokes the “send-message” action, which executes the fol-lowing code:case ‘send-message’ :{if(send_message($to, $cc,
}}}As you can see, this function uses mail() to send the email. First, however, it loads the user’semail address out of the database to use in the Fro
$header = imap_header($imap, $messageid);if($header->reply_toaddress)$to = $header->reply_toaddress;else$to = $header->fromaddress;$subject =
you could allow them to use many addresses. You would need to change a limitedamount of other code too. The send mail form would need a drop-down box
This HTML code has added a new form variable whose value will be “a”, “b”, “c”, or “d”. Wecould handle this new variable with a series of if and elsei
33 7842 CH27 3/6/01 3:41 PM Page 654
CHAPTER28Building a Mailing ListManager34 7842 CH28 3/6/01 3:46 PM Page 655
After you’ve built up a base of subscribers to your Web site, it’s nice to be able to keep intouch with them by sending out a newsletter. In this chap
Solution ComponentsThere are a number of components we will need to fulfil the requirements. The main ones aresetting up a database of lists, subscrib
Sending Mail with AttachmentsFor this project, we would like to be able to send users either a plain text newsletter or a“fancy” HTML version, accordi
In Figure 28.1 you can see the actions that can be taken by a user who is not logged in. As youcan see, he can log in (if he already has an account),
Because we have used an event-driven approach again, the backbone of the application is con-tained in one file, index.php, which calls on a set of fun
• Sub_lists: A record of which users have subscribed to which lists (a many-to-many relationship)• Mail: A record of email messages that have been sen
LISTING 28.1 Continuedsent datetime,modified timestamp);#stores the images that go with a particular mailcreate table images(mailid int not null,path
email (subject), and the listid of the list it has been sent to or will be sent to. The actual textor HTML of the message could be a large file, so we
try to use whichever conditional will be most readable in your situation. You will acquire a feelfor this with experience.Iteration: Repeating Actions
LISTING 28.2 Continued$status = ‘’;// need to process log in or out requests before anything elseif($email&&$password){$login = login($email,
LISTING 28.2 Continued$buttons[0] = ‘change-password’;$buttons[1] = ‘account-settings’;$buttons[2] = ‘show-my-lists’;$buttons[3] = ‘show-other-lists’;
LISTING 28.2 Continued// only these actions can be done if not logged inswitch ( $action ){case ‘new-account’ :{unset($normal_user);unset($admin_user)
LISTING 28.2 Continued}//all other actions require user to be logged inif(check_logged_in()){switch ( $action ){case ‘account-settings’ :{display_acco
LISTING 28.2 Continuedcase ‘store-change-password’ :{if(change_password(get_email(), $old_passwd,$new_passwd, $new_passwd2)){echo “<p>OK: Passwo
LISTING 28.2 Continuedcase ‘send’ :{send($id, $admin_user);break;}case ‘view-mail’ :{display_items(“Unsent Mail”, get_unsent_mail(get_email()),‘previe
LISTING 28.3 Continuedif (session_is_registered(“normal_user”))return true;elsereturn false;}function check_admin_user()// see if somebody is logged i
Action Usable By Descriptionshow-all-lists Anyone Shows a list of availablemailing listsshow-archive Anyone Displays archived news-letters for a parti
One noticeable omission from this table is an option along the lines of store-mail, that is, anaction that actually uploads the newsletters entered vi
Creating a New AccountIf a user selects the New Account menu option, this activates the new-account action. Thisactivates the following code in index.
CONTENTSviiBreaking Out of a Control Structure or Script ...47Next: Saving the Customer’s Order ...
</tr><tr><td align = right>100</td><td align = right>10</td></tr><tr><td align = right>150</t
The submit button on this form invokes the store-account action. The code for this action isas follows:case ‘store-account’ :{if (store_account($norma
LISTING 28.3 Continuedelse{echo “<p>Sorry, that email address is already registered here.”;echo “<p>You will need to log in with that addr
LISTING 28.3 Continued// need to process log in or out requests before anything elseif($email&&$password){$login = login($email, $password);if
LISTING 28.3 Continued//echo $query;$result = mysql_query($query);if (!$result)return false;if (mysql_num_rows($result)<1)return false;if(mysql_res
Back in our main program, we report to the user whether she was logged in or not, and at what level.The output from one login attempt is shown in Figu
Viewing ListsWe will implement a number of options for viewing available lists and list details. In Figure28.6, you can see two of these options: Show
FIGURE 28.7The display_items() function has been used to lay out a list of the lists that the user is not subscribed to.This is the Show Other Lists p
LISTING 28.6 Continuedif($items == 0)echo “<tr><td colspan = “.(1+$actions).”align = center>No Items to Display</td></tr>”;els
• $title is the title that appears at the top of the table—in the case shown in Figure 28.7,we are passing in the title Unsubscribed Lists, as shown i
LISTING 28.7 get_unsubscribed_lists() Function from mlm_fns.php—This Function Is Usedto Build an Array of Mailing Lists That a User Is Not Subscribed
echo $num.”<BR>”;$num++;}At the beginning of each iteration, the condition is tested. If the condition is false, the blockwill not be executed a
case ‘information’ :{display_information($id);break;}To see what the display_information() function does, look at Figure 28.8.Building Practical PHP a
LISTING 28.8 Continued$info = load_list_info($listid);if($info){echo “<h2>”.pretty($info[listname]).”</h2>”;echo ‘<p>’.pretty($info[
LISTING 28.9 Continued$query = “select count(*) from mail where listid = $listidand status = ‘SENT’”;$result = mysql_query($query);if($result){$info[‘
LISTING 28.10 Continued$query = “select mailid, subject, listid from mailwhere listid = $listid and status = ‘SENT’ order by sent”;if(db_connect()){$r
unsubscribe(get_email(), $id);display_items(“Subscribed Lists”, get_subscribed_lists(get_email()),‘information’, ‘show-archive’, ‘unsubscribe’);break;
LISTING 28.11 Continued$result = mysql_query($query);return $result;}The subscribe() function adds a row to the sub_lists table corresponding to the s
FIGURE 28.9The display_password_form() function enables users to change their passwords.When a user clicks on the Change Password button at the bottom
LISTING 28.12 change_password() Function from user_auth_fns.php—This FunctionValidates and Updates a User’s Passwordfunction change_password($email, $
unset($normal_user);unset($admin_user);}This snippet of code disposes of the session variables and destroys the session. Notice that italso unsets the
The extra options they have are Create List (create a new mailing list), Create Mail (create anew newsletter), and View Mail (view and send created ne
The basic structure of a for loop isfor( expression1; condition; expression2)expression3;• expression1 is executed once at the start. Here you will us
case ‘store-list’ :{if(store_list($admin_user, $HTTP_POST_VARS)){echo “<p>New list added<br>”;display_items(“All Lists”, get_all_lists(),
LISTING 28.13 Continued$query = “insert into lists values (NULL,‘$details[name]’,‘$details[blurb]’)”;$result = mysql_query($query);return $result;}}Th
FIGURE 28.12The Create Mail option gives the administrator an interface for uploading newsletter files.The form you see is similar to a regular file u
LISTING 28.14 Continued<td bgcolor = “#cccccc”><select name = list><?for($i = 0; $i<$lists; $i++){echo “<option value = “.$list[$
LISTING 28.14 Continued</td></form></tr></table><?}The thing to note here is that the files we want to upload will have the
LISTING 28.15 Continued$buttons[0] = ‘change-password’;$buttons[1] = ‘create-list’;$buttons[2] = ‘create-mail’;$buttons[3] = ‘view-mail’;$buttons[4] =
LISTING 28.15 Continueddo_html_footer();exit;}// creating directory will fail if this is not the first message archived// that’s ok@ mkdir(“archive/$l
LISTING 28.15 Continuedif($i==0)$destination = “archive/$list/$mailid/text.txt”;else if($i == 1)$destination = “archive/$list/$mailid/index.html”;else
Strictly speaking, we should probably also check the $list and $mailid variables forunwanted characters, but we have ignored this for the sake of brev
She can also click on the View Mail button, which will show her all the unsent newsletters inthe system, if she wants to preview and send mail later.
do..while LoopsThe final loop type we will mention behaves slightly differently. The general structure of ado..while statement isdoexpression;while( c
Sending the MessageClicking on the Send button for a newsletter activates the send action, which triggers the following code:case ‘send’ :{send($id, $
LISTING 28.16 Continued}else if (mysql_num_rows($result)==0){echo “There is nobody subscribed to list number $listid”;return false;}else{include(‘clas
LISTING 28.16 Continuedmysql_result($result, $i, 1));}}// add HTML and text to the mimemail object$mail->add_html($html, $text);// note that we bui
LISTING 28.15 Continued$result = mysql_query($query);if(!$result)echo “<p>Error getting subscriber list”;$count = 0;// for each subscriberwhile(
This means each piece of mail must essentially be sent twice: once in test mode and once in real mode.The function also sends two different kinds of e
Extending the ProjectAs usual with these projects, there are many ways you could extend the functionality. Youmight like to• Confirm membership with s
34 7842 CH28 3/6/01 3:46 PM Page 710
CHAPTER29Building Web Forums35 7842 CH29 3/6/01 3:34 PM Page 711
Building Practical PHP and MySQL ProjectsPART V712One good way to get users to return to your site is to offer Web forums. These can be used forpurpos
The most difficult part of this application is finding a database structure that will store theinformation we want, and a way of navigating that struc
Next: Saving the Customer’s OrderNow you know how to receive and manipulate the customer’s order. In the next chapter, we’lllook at how to store the o
The replies will be stored in an array. Each reply will itself be a tree_node, that can contain anarray of replies to that article, which are themselv
FIGURE 29.2There are three main parts of the blah-blah forum system.A summary of the files in this application is shown in Table 29.1.TABLE 29.1 Files
Designing the DatabaseThere are a few attributes we’ll need to store about each article posted to the forum: the personwho wrote it, called the poster
We will make one other optimization: We will separate the message bodies from the other dataand store them in a separate table. The reason for this is
grant select, insert, update, deleteon discussion.*to discussion@localhost identified by ‘password’;You can create this database structure by running
Building Web ForumsCHAPTER 2929BUILDING WEBFORUMS719FIGURE 29.4The initial view of the article list shows the articles in “collapsed” form.What we see
FIGURE 29.5The thread of discussion about persistence has been expanded.Building Practical PHP and MySQL ProjectsPART V720FIGURE 29.6All the threads h
If you look closely at Figures 29.5 and 29.6, you can see that we are passing some parametersback to index.php in the command line. In Figure 29.5, th
unset($expanded);elseunset($expanded[$collapse]);}do_html_header(“Discussion Posts”);display_index_toolbar();// display the tree view of conversations
If we are trying to expand a particular thread, we will have been passed a postid via $expand.We therefore add a new entry to the $expanded array to r
CHAPTER2Storing and Retrieving Data04 7842 CH02 3/6/01 3:37 PM Page 49
Displaying the ArticlesLet’s look at the display_tree() function, shown in Listing 29.4.LISTING 29.4 display_tree() Function from output_fns.php—Creat
the first level articles, which have no parent. After the tree has been constructed, we simplycall its display function to actually display the list o
$query = “select * from header where parent = $postid order by posted”;$result = mysql_query($query);for ($count=0; $row = @mysql_fetch_array($result)
// display + or - or a spacerif ( !$sublist && $this->m_children && sizeof($this->m_childlist))// we’re on the main page, have s
This class contains the functionality that drives the tree view in this application.One instance of the treenode class contains details about a single
When we construct the root treenode from display_tree() from the main page, we are actu-ally creating a -dummy node with no article associated with it
Building Practical PHP and MySQL ProjectsPART V730After all that’s done, we call the root treenode’s display function (this is back in display_tree())
Building Web ForumsCHAPTER 2929BUILDING WEBFORUMS731// we are collapsed - offer button to expandecho “<a href = ‘index.php?expand=”.$this->m_pos
FIGURE 29.7We can now see the message body for this posting.This script shows us the message body, as well as the replies to this message. You will se
echo “<br><br>”;display_replies_line();display_tree($expanded, 0, $postid);}do_html_footer();?>This script uses three main function cal
Using PHPPART I50Now that we know how to access and manipulate data entered in an HTML form, we can lookat ways of storing that information for later
This function, given a postid, will perform the two queries required to retrieve the messageheader and body for that posting, and put them together in
First, look at the URL:http://webserver/chapter29/new_post.php?parent=5The parameter passed in as parent will be the parent postid of the new posting.
do_html_header(“$title”);display_new_post_form($parent, $area, $title, $message, $name);if($error)echo “Your message was not stored. Make sure you ha
//get all header information from ‘header’$query = “select title from header where postid = $postid”;$result = mysql_query($query);if(mysql_numrows($r
After the user types in his reply and clicks the Post button, he will be taken to thestore_new_post.php script. Sample output from this script is show
As you can see, this is a short script. Its main task is to call the store_new_post() function.This page has no visual content of its own. If storing
$query = “insert into header values(‘“.$post[‘parent’].”’,‘“.$post[‘poster’].”’,‘“.$post[‘title’].”’,0,‘“.$post[‘area’].”’,now(),NULL)”;$result = mysq
return false;}return $id;}}This is a long function, but it is not overly complex. It is only long because inserting a postingmeans inserting entries i
NextIn Chapter 30, “Generating Personalized Documents in Portable Document Format (PDF),” wewill use the PDF format to deliver documents that are attr
CHAPTER30Generating PersonalizedDocuments in PortableDocument Format (PDF)36 7842 CH30 3/6/01 3:40 PM Page 743
We’ve modified the form to include a quick way to obtain the customer’s shipping address.You can see this form in Figure 2.1.Storing and Retrieving Da
On service driven sites, we sometimes need to deliver personalized documents, generated inresponse to input from our visitors. This can be used to pro
Evaluating Document FormatsThe most important decision we need to make is what format to deliver the certificate in.Options include paper, ASCII text,
programs; and variable quality printing. In addition, although HTML can include any type of external element, the capability of the browser to display
Because the format is documented and freely available, RTF is readable by more software thanWord’s binary format. Be aware though that users opening a
You can read more about Ghostscript athttp://www.ghostscript.com/and download it fromhttp://www.cs.wisc.edu/~ghost/For our current application, PostSc
Solution ComponentsTo get the system working, we will need to be able to examine users’ knowledge and (assum-ing that they pass the test) generate a c
To create the file, we used Microsoft Word to design a document. One of the tools in theAcrobat package is Adobe Distiller. Within Distiller, we neede
There is a free trial option for this service if you want to test it out.There is also a free ftp-based interface to ps2pdf at the Net Distillery:http
Solution OverviewWe will produce a system with three possible outcomes. As shown in Figure 30.1, we will askquiz questions, assess the answers, and th
TABLE 30.1 ContinuedName Type Descriptionpdflib.php Application Script to generate PDFcertificate using PDFlibsignature.tif image Bitmap image of sign
Overview of File ProcessingThere are three steps to writing data to a file:1. Open the file. If the file doesn’t already exist, it will need to be cre
LISTING 30.1 Continued<li><input type = radio name = q1 value = 1>Outputs strings.<li><input type = radio name = q1 value = 2>
FIGURE 30.2index.html asks the user to answer quiz questions.Grading the AnswersWhen the user submits his answers to the questions in index.html, we n
LISTING 30.2 ContinuedSorry:<img src = ‘rosette.gif’ alt = ‘’></h1>”;echo “<p>You need to fill in your name and answer all questions
LISTING 30.2 Continued<input type = image src = ‘certificate.gif’ border = 0></center>”;echo “<input type = hidden name = score value =
FIGURE 30.3score.php presents successful visitors with the option to generate a certificate in one of three ways.Generating an RTF CertificateThere is
We can build a complex document, such as the one shown in Figure 30.4, easily using a wordprocessor.Generating Personalized Documents in Portable Docu
LISTING 30.3 Continuedif( !$name || !$score ){echo “<h1>Error:</h1>This page was called incorrectly”;}else{//generate the headers to help
header( “Content-type: application/msword” );header( “Content-Disposition: inline, filename=cert.rtf”);The first header tells the browser that we are
This approach works very well. The calls to str_replace() run very quickly, even though ourtemplate and therefore the contents of $output are fairly
This is a neat way of doing things, but it has two limitations. First, it assumes that you own acopy of Acrobat. Second, it is difficult to substitute
Using fopen() to Open a FileLet’s assume that we want to write a customer order to Bob’s order file. You can open this filefor writing with the follow
LISTING 30.4 Continuedif(!$name||!$score){echo “<h1>Error:</h1>This page was called incorrectly”;}else{//generate the headers to help a br
FIGURE 30.6pdf.php generates a certificate from an PDF template.One problem with this approach is that the code runs quite slowly because of the regul
Although it is possible that the official PHP binding might be better then the current one when(or if) it arrives, the current one is very good. The o
LISTING 30.5 Continued// display a link to downloadecho “download the pdf <a href = ‘hello.pdf’>here</a>”;?>The most likely error you w
PDFlib works in points, both for page size, and for locating coordinate locations on each page.For reference, A4 is approximately 595 by 842 points an
pdf_set_font($pdf, “Helvetica-Bold”, 24, “host”);Font sizes are specified in points. We have chosen host character encoding. The allowable val-ues are
When we have finished the whole PDF document, we need to close it using pdf_close().When we are generating a file, we also need to close the file.The
LISTING 30.6 Continued// create a pdf document in memory$pdf = pdf_open();// set up the page size in points// US letter is 11” x 8.5”// there are appr
LISTING 30.6 Continued$startx = 70;pdf_show_xy($pdf, “This is to certify that:”, $startx, 430);pdf_show_xy($pdf, strtoupper($name), $startx+90, 391);p
LISTING 30.6 Continuedpdf_lineto($pdf, 666, 150);pdf_closepath($pdf);pdf_stroke($pdf);// draw ribbon 2pdf_moveto($pdf, 660, 150);pdf_lineto($pdf, 680,
PHP AND MYSQL WEB DEVELOPMENTviiiAssociative Arrays ...73Initializing an
TABLE 2.1 Summary of File Modes for fopenMode Meaningr Read mode—Open the file for reading, beginning from the start of the file.r+ Read mode—Open the
LISTING 30.6 Continued$y = $radius*sin($angle) + $centery;}else{$x = $inner_radius*cos($angle) + $centerx;$y = $inner_radius*sin($angle) + $centery;}i
We will look at some of the parts of this script that are different from the previous examples.Visitors need to get their own details on a certificate
pdf_rect($pdf, $inset+$border/2,$inset+$border/2,$width-2*($inset+$border/2),$height-2*($inset+$border/2));pdf_stroke($pdf);After we have drawn our on
pdf_moveto($pdf, 630, 150);pdf_lineto($pdf, 610, 55);pdf_lineto($pdf, 632, 69);pdf_lineto($pdf, 646, 49);pdf_lineto($pdf, 666, 150);pdf_closepath($pdf
Some of our headers seemed to cause problems with session control headers. There are a fewways around this. We have found using GET parameters rather
IN THIS PARTA Installing PHP 4 and MySQL 781B Web Resources 803AppendixesPARTVI37 7842 part 6 3/6/01 3:35 PM Page 779
37 7842 part 6 3/6/01 3:35 PM Page 780
APPENDIXAInstalling PHP 4 and MySQL38 7842 app a 3/6/01 3:40 PM Page 781
AppendixesPART VI782Apache, PHP, and MySQL are available for multiple operating systems and Web servers. Inthis appendix, we will explain how to set u
PHP accomplishes this by doing the following:• PHP refuses to interpret the command-line arguments, when invoked as a CGI binary.• PHP also prevents a
If the filename you use begins with ftp://, a passive mode FTP connection will be opened tothe server you specify and a pointer to the start of the fi
Our installation will be done on a Red Hat 6.2 Linux server, but will be generic enough toapply to other UNIX servers.Let’s start by listing out the t
Let’s begin! Become root by using su.$ suand enter the user root’s password. Change to the directory that you have stored the sourcefiles in, for exam
Enter password:+--------------------+| Databases |+--------------------+| mysql |+--------------------+When you install MySQL, i
# ./configure --with-mysql=/usr/local/mysql \--with-xml --with-apache=../apache_1.3.x \--with-curl=/usr/local/curl \--with-pspell=/usr/local/pspell \
It’s time to set up OpenSSL. This is what you will use to create temporary certificates andCSR files. The --prefix specifies the main installation dir
(You could alternatively set SSL_BASE and RSA_BASE as environment variables if you prefer.)Finally you can make Apache and the certificates, and then
| Apache the first time by running: || || /usr/local/apache/
FIGURE A.1The default test page provided by Apache.Is PHP Support Working?Now we will test for PHP support. Create a file with the name of test.php wi
FIGURE A.2The function phpinfo() provides useful configuration information.Is SSL Working?Okay, now we are ready to test for SSL. First, stop the serv
certificate from VeriSign or Thawte, the browser would not prompt you because their certifi-cates come from a trusted Certification Authority (CA). In
If you get this error, you need to make sure that the user that the script runs as has permissionto access the file you are trying to use. Depending o
Windows 95/98The Windows 95/98 version of MySQL comes with two different MySQL servers:• mysqld: Compiled with full debugging and automatic memory all
FIGURE A.4The Services Control Manager allows you to configure the services running on your machine.To test whether or not MySQL is working, you can e
FIGURE A.5The Apache installer is easy to use.The install program will prompt you for the following:• The directory to install Apache. (The default is
Running Apache in a Console WindowTo run Apache from the console window, select the Start Apache as console App option fromthe Start menu. This will o
Apache will be listening to port 80 (unless you changed the Port, Listen, or BindAddress direc-tives in the configuration files) after it starts. To c
side-effect of the Windows port. Apache 2.0 is making progress to implement theexpected asynchronous behavior, and we hope to discover that the NT/200
Note that with the AddType directive, you can specify how Apache should handle the variousfile extensions. In the case previously mentioned, we specif
2. Start the Microsoft Management Console (it might appear as the Internet ServicesManager, either in your Windows NT 4.0 Option Pack branch or in the
2. Edit the enclosed PWS-php4.reg file to reflect the location of your php4isapi.dll. Forwardslashes should be escaped, for example:[HKEY_LOCAL_MACHIN
APPENDIXBWeb Resources39 7842 App B 3/6/01 3:38 PM Page 803
FIGURE 2.3Using your own error messages instead of PHP’s can be more user friendly.Writing to a FileWriting to a file in PHP is relatively simple. You
AppendixesPART VI804This appendix lists some of the many resources available on the Web, which can be used to findtutorials, articles, news, and sampl
HotScripts.com—http://www.hotscripts.com—A great categorized selection of scripts. Thesite has scripts in various languages like PHP, ASP, and Perl. I
e-gineer—http://www.e-gineer.com—Articles, scripts, and a knowledge base of commonquestions and answers.Source Forge—http://sourceforge.net—Extensive
INDEXSYMBOLS+ (addition operator), 26= (assignment operator), 27@ (at symbol), 56\ (back slashes), 263, 448^ (bitwise operator), 31| (bitwise operator
+ (plus symbol)808+ (plus symbol), Webforum articles, 719’ (quote symbol)” (quotes)& (reference operator), 29* (regular expressions),111+ (regular
architecture809aliases for tables, 218-219ALL privilege, 191ALTER privilege, 190ALTER TABLE statement,223syntaxes, 224ALTER [COLUMN] column{SET DEFAUL
architecture810performing actions, 663preprocessing, 663Web databases, 180-181arcs, ImageArc() function,428arithmetic operators, 26array push() functi
Boutell Web site811mod_auth_mysql module,322-324documentation Websites, 324installing, 322-323passwords, 291-292session control, 438-445authmain.php s
boxes812boxes, 416. See alsobounding boxesbranching (regularexpressions), 112break statement, 47breaking up code, 466-467brochureware sites, 269-271co
code813Certifying Authorities(CAs), 297-298CGI Interpreter, 782-783PHP, running, 782-783CGI specification Website, 368Change Password button,689change
File FormatsWhen you are creating a data file like the one in our example, the format in which you storethe data is completely up to you. (However, if
code814HTMLfile upload, 353files, catching, 354-356indenting, 39, 465-466line graphs, script for outputting, 405logic, 471separating from content, 472
column types (tables)815script to make HTTPS connections, 388script to verify URL andemail address, 376scriptslist of extensions andfunctions in PHP,
columns816columnsDESCRIBE statement, 257values, EXPLAIN state-ment, 259columns (tables), 173keys, 173-175creating for Web databases, 179foreign keys,
control characters817component structures,467componentsonline newsletters, 657user personalization,499-500compressionGIF, LZW (Lempel ZivWelch), 404GI
control structures818control structures, 38-47breaking out of, 47conditionals, 38-42code blocks, 38-39comparing, 42else statements, 39-40elseif statem
databases819in a particular order,219-220with specific criteria,212, 214rows, returning, 222-223sensitive datacredit card numbers,storing, 338storing,
databases820privilege system, 246-247columns_priv table,249-250db table, 248-249grant table, 250-251host table, 248-249privileges, updating,251tables_
discussion board application821decrement operators, 28-29decryption, 294default values, databaseoptimization, 262delete bm() function, 531DELETE privi
discussion board application822plus symbols, 719treenode class, 725-731database design, 716-718extensions, 741files, 715posters, 716solution component
email client application (Warm Mail)823Ee-commerce Web sites,268-280adding value to goods orservices, 276authentication, 284cutting costs, 276-277onli
This function will return true if the file was successfully closed or false if it wasn’t. This isgenerally much less likely to go wrong than opening a
email client application (Warm Mail)824script architecture,623-629sending mail, 649-652forwarding messages,651-652new messages, 649-651replying to mes
files825EXPLAIN statement, 257-260column values, 259join types, 258output, 257, 260explode() function, 86-87,102, 377exploits, BUGTRAQarchives Web sit
files826catching, code, 354-356checking existence of, 63checking size of, 63closing, 58-59content management systems, 595create database.sql,595-586db
fopen() function827url_fns.php, 502user_auth_fns.php, 502pollsetup.sql, 420progex.php, 366properties, changing, 364reading, 52, 361-364feof() function
for loops828for loops, 45-46foreign keys (databases),175forgot_form.php, 501forgot_passwd.php, 501format codes, date() function, 392-394formattingoutp
functions829ftp_fput() function, 385ftp_get() function, 385ftp_login() function, 382ftp_mdtm() function, 383ftp_nlist() function, 386ftp_put() functio
functions830display_account_setup(),633, 636display_book_form(),581-583display_cart(), 560-563display_categories(), 553display_list(), 640-641display_
functions831htmlspecialchars() function, 233ImageArc(), 428ImageColorAllocate(), 406ImageCopyResized(), 594ImageCreate(), 405ImageCreateFromGIF(),406,
functions832phpinfo(), 368, 751posix_getgrgid(), 363posix_getpwuid(), 363pretty(), 685prev() function, 88print(), 97printf(), 98-99prototypes, 130pute
highlight_string() function833get user urls() function,515get writer record() function, 607getdate() function, 395getenv() function, 367-368gethostbya
FIGURE 2.4The vieworders.php script displays all the orders currently in the orders.txt file in the browser window.Let’s look at the functions in this
host table834host table, 247-249mysql database, 249HotScripts.com Web site,805htaccess files (ApacheWeb server), basicauthentication (HTTP),316-319HTM
insert_book.php script835PNG (Portable NetworkGraphics), 403WBMP (WirelessBitmap), 403functions, 428generating automatically,410inline, dynamically pr
insert_book.php script (Shopping Cart application)836insert_book.php script(Shopping Cart applica-tion), 578-579insert_book_form.phpscript (Shopping C
listings837Gnu Privacy Guard(GPG), 340importing (Gnu PrivacyGuard), 341keys (arrays), 71keys (databases), 173-175creating for Web databases,179foreign
listings838get_random_word()Function fromuser_auth_fns.php, 524get_unsubscribed_lists()Function frommlm_fns.php, 683get_user_urls() Functionfrom url_f
members_only.php script (authentication)839logout.php files, 605logout.php script (authen-tication), 444-445lookup functions, 374-378checkdnsrr(), 378
memory, freeing up (mysql_free_result() function)840memory, freeing up(mysql_free_result()function), 241-242message headers (WarmMail application), vi
mysql_select_db() function841databasescreating, 187creating from PHPscripts, 242deleting, 242results.php script,230-231selecting, 193-194tables, creat
naming functions842Nnaming functions, 133-134naming conventions,code, 463function names, 464modular names, 464variable names, 463-464Natural Order Str
operators843Page class code listing,161-165ServicesPage class,166-167TLA Consulting homepage, generating,165-166ODBC (Open DatabaseConnectivity), func
There are many different functions that can be used to read from files. The fgets() function isuseful when dealing with files that contain plain text
operators844reference operator, 29returning values, 27associativity, 34-35bitwise operators, 31comma operator, 32comparison, WHEREclauses, 212-213comp
PHP845payment module(Shopping Cart applica-tion), 572-575payment systems(Shopping Cart applica-tion), 541-542PDF (Portable DocumentFormat), 744, 748fu
PHP846floor() function, 399getdate() function, 395mktime() function,394-398PHP Web site, 400date() function, 17-18development environments,IDE (integr
php4win Web site847associativity, 34-35bitwise operators, 31comma operator, 32comparison operators,29-30error suppression operator, 32execution operat
phpautodoc Web site848phpautodoc Web site, 470PHPBookmark applicationcreating, 498database schema, 502diagrams, 500front page, 504-506function librari
prototypes (functions)849printing stringsformatting strings forprinting, 97-99print() function, 97printf() function, 98-99sprintf() function, 98text o
public key encryption850public key encryption,295-296public keys, Gnu PrivacyGuard (GPG), 340exporting, 340importing, 341publish story.php, 596publish
retrieving851character sets, 109-110curly braces ({}), 112slash (\), 112Smart Form Mail applica-tion, 113-114special characters, 113literal special ch
retrieving852tables, joining, 216-217tables, rows unmatched,217-218two-table joins,214-216with specific criteria,212-214vote database results, code,42
Secure Sockets Layer (SSL)853scope (variables), 25scope fields, 248score.php, 752-757screening user input, 336script architecture, 663-672footers, 663
The optional second parameter specifies whether PHP should look for the file in theinclude_path and operates the same way as in fopen(). The function
Secure Sockets Layer (SSL)854handshaking, 334protocol stacks, 333sending data, 334-335secure storage, 336-337credit card numbers, 338secure transactio
setting up855Send button, 704send() function, 704sending messages, onlinenewsletters, 704-708sending mail, 371Warm Mail application,649-652forwarding
settype() function856settype() function, 36set_magic_quotes_runtime() function, 449set_time_limit() function,386Shopping Cart applica-tion, 540adminis
statements857software, errors (securitythreats), 288-289software engineering,460-462defined, 460-462software errors (commer-cial Web sites), 279soluti
statements858echo statements, 20-21else statements, 39-40elseif statements, 40exit statement, 47EXPLAIN, 257-260column values, 259join types, 258outpu
syntax859orderingstrcasecmp() function,105strcmp() function, 104strnatcmp() function,105printingformatting strings forprinting, 97-99print() function,
syntax860MODIFY [COLUMN] column_description, 224RENAME [AS]new_table_name, 224SHOW statement, 255-257syntax errors, 478-480syntax highlighter, 454-455
tracking user’s purchases (Shopping Cart application)861plain text (encryption), 293positioning onto buttons,418writing onto buttons, 419text files, 5
transactions, secure862transactions, secure, 328-332Internet, 330-331screening user input, 336Secure Sockets Layer(SSL), 332-335secure storage, 336-33
variable variables863user feedback (commer-cial Web sites), 271user input, screening, 336user interface design(commercial Web sites),274user personali
It is not generally sensible to read a file character-by-character unless for some reason we wantto process it character-by-character.Reading an Arbit
variables864variablesarrays, 70-71applying functions toelements, 89-90associative arrays,73-75converting to scalarvariables, 91-92counting elements,90
Web issues, database security865messages, 643-647selecting accounts,637-640script architecture, 623-629sending mail, 649-652forwarding messages,651-65
Web pages, protecting multiple pages866Web pages, protectingmultiple pages, 312Web serversApache. See Apache Webserverauthentication, 292-293commands,
ZEND.Com Web site867PHP Base Library, 805PHP Center, 805PHP Classes Repository,805Metabase, 243PHP Club, 805PHP Developer, 805PHP Homepage, 805PHP ima
CONTENTSixIntroduction to Regular Expressions ...109The Basics ...
Navigating Inside a File: rewind(), fseek(), and ftell()You can manipulate and discover the position of the file pointer inside a file using rewind(),
File LockingImagine a situation where two customers are trying to order a product at the same time. (Notuncommon, especially when you start to get any
You should also add locks to vieworders.php:$fp = fopen(“$DOCUMENT_ROOT /../orders/orders.txt”, “r”);flock($fp, 1); // lock file for reading// read f
How RDBMSs Solve These ProblemsRelational database management systems address all of these issues:• RDBMSs can provide faster access to data than flat
04 7842 CH02 3/6/01 3:37 PM Page 68
CHAPTER3Using Arrays05 7842 CH03 3/6/01 3:41 PM Page 69
Using PHPPART I70This chapter shows you how to use an important programming construct—arrays. The vari-ables that we looked at in the previous chapter
After we have the information as an array, we can do a number of useful things with it. Usingthe looping constructs from Chapter 1, we can save work b
If you have the information stored in file on disk, you can load the array contents directly fromthe file. We’ll look at this later in this chapter un
Using Loops to Access the ArrayBecause the array is indexed by a sequence of numbers, we can use a for loop to more easilydisplay the contents:for ( $
Comentarios a estos manuales