CHAPTER EIGHT: PHP for Server-Side Preprocessing

Chapter opener image: © Godruma/ShutterStock

Overview and Objectives

The client-side JavaScript programming that we looked at in the previous two chapters is limited to computing that can be safely executed within the confines of the browser. These limitations aside, client-side computing has certain advantages. For example, it limits the amount of data transfer by taking care of simple computing requests on the client computer, instead of transmitting those computational requests to the server, having the server perform them, and then sending the results back to the client. This relieves the server from servicing a large number of requests for minor computational tasks and cuts down on bandwidth consumption as well. Equally important is that client-side computing is very useful for filtering out potentially malicious data, or simply malformed data, on its way to the server.

However, client-side computing using JavaScript is not up to the task of performing much of the computation that is necessary on the contemporary web. Our websites need to serve dynamically created web pages based on the data from users’ input devices, files on both the client and server computers, and information contained in databases stored on servers. In general, for the sake of efficiency, it is better to have calculations on data performed wherever the data lives, so clearly you will want to do some serious computing on the server side as well.

Four of the most popular technologies for providing server-side computing are Active Server Pages (ASP), Java Server Pages (JSP), Perl, and Personal Home Page (PHP). The use of ASP requires a relatively intensive study of languages such as Visual Basic, C#, or C++ on Microsoft’s .NET platform. A study of JSP requires a reasonable prior exposure to the Java programming language. On the other hand, Perl and PHP are both interpreted scripting languages that, by comparison, are much easier to learn, especially for those with no prior programming experience. These languages make it possible for you to get onto the server side of the web programming highway relatively quickly.

Of the two, PHP is the easier to learn and use, and is currently the one in wider use. So, it is our language of choice, and in this chapter we will discuss the following:

  • A brief history of the PHP language, and why it is a reasonable choice for our server-side processing (or “preprocessing”, as we often call it, since the PHP processing for a given page takes place before that page is sent to the browser for display)

  • How PHP fits into the overall web picture as a scripting language, with the help of a simple initial example that introduces one of PHP’s many useful built-in functions, the date( ) function

  • The features of the PHP language required for our purposes, which include comments, variables, and superglobals (a special kind of variable), numerical and string data types, expressions and operators, arrays, built-in and programmer-defined functions, file output, and using PHP to accomplish server-side inclusion of files

  • PHP script development and testing

  • How to incorporate in our page header a PHP-generated welcome message that uses Asynchronous JavaScript And XML (AJAX) to retrieve the current date and time from the server and update it every sixty seconds

  • How to implement the server-side functionality of our feedback form by first uploading the user’s input data to the server and then performing the following actions on the server side:

    1. sending the user’s feedback to the business via email

    2. sending a copy of the email to the client

    3. confirming the submission to the client via a browser display, and

    4. storing a copy of the feedback on the server

  • How to implement an alternate version of our BMI calculator by shifting the computation from client-side JavaScript to server-side PHP, allowing us to email the user a permanent record, if requested, in addition to providing the immediate browser display of the result

  • How to send HyperText Markup Language (HTML)-encoded email, as we do when delivering our BMI report

  • The GET and POST values of the method attribute of the form element, and how they determine the way in which data is passed to a PHP script on the server, either from a form or via a Uniform Resource Locator (URL)

The updated version of our Nature’s Source website for this chapter will require several new scripts written in PHP, which we will, of course, place in our ch08/nature/scripts subdirectory, alongside the JavaScript scripts we have already introduced. We shall discuss each script in detail as we encounter it, and there will be some changes in the JavaScript because, for example, PHP will take over the BMI calculation. And, of course, we will also have to (finally) provide an action attribute in the opening form tags that now appear in bmiForm.php and feedbackForm.php so that the data from these forms is now processed by the new PHP scripts. Along with the form’s action attribute we will also need a method attribute to specify how the data will be transferred.

To get the welcome message that appears in the banner at the top of our website’s pages to the right of our logo, we will replace our logo.html “include file” with a new include file called banner.php, which is comprised of the former content of logo.html plus some additional markup and code to handle this new welcome message.

Since SSI (as we have used it in previous chapters) and PHP do not always play well together without reconfiguring the server, which is beyond the scope of our discussion, we now use a different (and simpler) approach to get our server-side includes. The include( ) function of PHP can be used to include into our index.php (formerly index.html) our new banner.php, as well as the files menus.html and footer_content.html, which are unchanged except for the href values that now contain links to files with a .php extension. Analogous changes need to be made to all of the other files to which we link from our menu options, and to indicate this change we alter the extensions of these files from .html to .php to reflect the fact that each one now contains some PHP code that needs to be “preprocessed” on the server.

Finally, we need a few modifications to our Cascading Style Sheets (CSS) to take care of our new Welcome message, but this does not involve anything we have not seen before. Check the styles at the end of desktop.css and tablet.css to see what we’ve added.

8.1 Some PHP History

In the early days of the web, prior to the appearance of PHP, Perl was by far the most popular language of choice for server-side web programming. In recent years, PHP has gained immense popularity and has become a versatile and robust language with more than enough capability to meet the needs of any aspiring web developer.

The current version of PHP has its roots in the C and Perl programming languages, and many of its features reflect those origins. Many of its most commonly used features are also similar to those of JavaScript, which we have already seen, so our discussion of PHP will focus on pointing out those similarities and highlighting the differences.

Unlike Perl, which is a “standalone” programming language that can be used to write virtually any kind of software, PHP is designed specifically for web page development. In this chapter and the next two, you will gain enough experience with PHP and the MySQL database management system to create a prototype e-commerce system.

The acronym PHP originally stood for PHP, and the set of Perl scripts that comprised its original implementation was written by Rasmus Lerdorf in 1995. He used his PHP tools for tracking accesses to his online résumé. A revised version of the original product was called PHP/FI, where FI stood for “Forms Interpreter”.

Lerdorf posted his work on the web, where it very quickly caught the attention of other developers, and the system soon took on a life of its own. To support increased functionality, Rasmus then wrote a much larger C implementation. This major revision added abilities to communicate with databases, which led to even more interest in the software, and it eventually expanded to the point where it was no longer possible for a single individual to maintain it. Nowadays there is a worldwide community involved in PHP maintenance and development, and you can follow their progress on, and freely download the latest updates for many different platforms from, the home website for PHP, located at http://php.net/.

TABLE 8.1 A brief summary of PHP history (with many intermediate versions and details missing).

Date Version Notes
1994 Original (private) Rasmus Lerdorf writes first incarnation of PHP for personal use and calls it “Personal Home Page Tools”
June 1995 1.0 Lerdorf releases source code to the public
November 1997 2.0 Now called PHP/FI2 (FI = “Forms Interpreter”), and contained many features that are still part of PHP
June 1998 3.0 Development has moved from one person to a team
May 2000 4.0 Based on a new parser called the Zend Engine
July 2004 5.0 Based on the new Zend Engine II
August 2014 5.6 Many improvements over 5.0
N/A 6.0 This version, which was supposed to incorporate core Unicode support, was eventually abandoned
November 2015 7.0 Based on Zend Engine III, with many more improvements

See the end-of-chapter References for further information, and TABLE 8.1 for more details of the PHP language development timeline.

Web developers owe a debt of gratitude to Rasmus Lerdorf for making the source code of PHP public, since the resulting vibrant online PHP community has produced many significant improvements in the language itself, as well as facilities that permit PHP to communicate with a wide variety of database implementations. The use of PHP has far outgrown its original motivation of creating PHPs. In fact, that original name has receded into obscurity, since more users now prefer to use the recursive name PHP: Hypertext Preprocessor. This definition describes the role of PHP more accurately, since PHP scripts are used for “preprocessing” a web page (on the server) to dynamically create a hypertext document (before it is sent to the browser). HTML markup constructed via PHP, using data from server-side databases that is also obtained via PHP, allows programmers to develop very dynamic and timely web pages.

8.2 PHP as a Server-Side Scripting Language

All current major web server software packages are capable of providing access to a PHP interpreter on the server side of the client-server architecture. This does not mean that you, as a web developer, automatically have access to PHP, even if you have an Internet Service Provider. PHP has to be activated and configured on the server, so you need to check with your system administrator to make sure that PHP is enabled for your web server.

A web server may spawn a separate operating system “process” to handle PHP requests, or the server software itself may have an “internal” module that deals with PHP scripts. As long as PHP is available, which of these options is actually in use will generally be “transparent to the user”.

Because of its PHP requirement, this chapter’s version of our Nature’s Source website (found in ch08/nature) cannot be properly viewed unless it’s being “served” by a PHP-aware web server. If you wish to test your PHP pages “locally”, before uploading them to your server (always a good idea, of course), you can install a web server such as Apache, as well as PHP, on your personal computer, and place our files, with any modifications you have made to them, in a location accessible to that server. See the end-of-chapter References for further information. And, of course, you can always view and interact with, but not modify, the authors’ installation at http://cs.smu.ca/webbook2e/ch08.

A typical PHP web page will contain the usual HTML markup you have seen, but this markup will also be interspersed with instructions in the PHP programming language. A PHP-enabled web server will run all the embedded PHP instructions in a web page document as part of its “preprocessing” of that web page. These PHP instructions will create additional HTML markup. All of the HTML—that generated by PHP, plus whatever other markup was present on the web page—is then sent to the client. Note immediately this major difference between JavaScript and PHP: JavaScript code is downloaded from the server with the HTML and run in the browser, while PHP code is run on the server and it is the output of this run, along with whatever other HTML the document contains, that is downloaded to the browser. When PHP is processing a document, at any given time it may be in one of two modes:

  1. read mode (also called copy mode), if it is just reading HTML markup from the document, or

  2. interpret mode (also called execute mode or translate mode) if it is interpreting an embedded PHP script to generate additional markup for inclusion into the page

This means that the client computer is not aware of any of the embedded PHP instructions, since they have “disappeared” by the time the client receives the page from the server. It also means that the use of PHP does not require any special plug-ins on the client side to work with PHP script output. Finally, all the PHP programming code is “hidden” from the client, which helps with the security issue since that code may contain additional information about data storage on the server, or other sensitive information.

8.3 PHP Script Structure and General Syntax: A Simple First Example

Before we start incorporating PHP into the pages of our Nature’s Source website, it will be useful to examine a simple example in isolation. Moreover, we shall later incorporate the output of code similar to what we see in this example into our web pages. The example in question is found in the file ch08/welcome.php, which is shown in FIGURE 8.1. The browser display of this file can be seen in FIGURE 8.2.

FIGURE 8.1 ch08/welcome.php

A very short PHP script embedded in the body of an HTML document. The script places a Welcome message, with the current date and time, into the markup, on the server, before the page is sent to the browser for display.

From Figure 8.1 we see that the content of welcome.php is a normal HTML document, except for the content of the body element, which contains some “ordinary” HTML (an h2 element in line 9 and an h6 element in lines 16–17), as well as a short PHP script in lines 10–15. This is typical, but in a more complicated example there could also be JavaScript code and several additional PHP scripts embedded in the document body. Note that any HTML document file that contains PHP code should be given a .php extension, as we have done in this case. This is a helpful visual aid to programmers and an essential indicator to the server that the file must be processed by the PHP interpreter before the page is sent to the browser.

The first thing to note about the PHP script in Figure 8.1 is that the programming language statements in a PHP script are enclosed within a <?php delimiter at the beginning (line 10) and a ?> delimiter at the end (line 15). For readability these are generally placed on lines by themselves, though this is not necessary. This particular script contains just three PHP echo statements. Note that PHP statements, like JavaScript statements, are terminated by a semicolon. The purpose of an echo statement is to “echo” (or print) some output that will become part of the final HTML document that will be generated by the PHP processor and sent to the browser from the server.

In this case, the output in question consists of two HTML h3 elements. The first h3 element, which is output by the first two PHP echo statements, is the more interesting of the two.

FIGURE 8.2 graphics/ch08/displayWelcomePhp.jpg

A Firefox browser display of the final markup after the PHP script embedded in ch08/welcome.php has run.

The content of this h3 element includes some ordinary text, an instance of the HTML <br> element, the output from two calls to the PHP built-in date( ) function, and two occurrences of the character combination .

It is important to note here that the period (.) is the PHP concatenation operator for strings (the operator that combines two strings into a single string). This may take some getting used to, since many other languages, including JavaScript, use the + operator for this purpose. Study the code in Figure 8.1, compare it carefully with the corresponding display in Figure 8.2, and make sure you identify which periods in the code are concatenation operators used to join PHP strings (text enclosed in double quotes, as usual, and/or date( ) function return values, which are also strings), and which periods are simply part of the text output to be displayed.

The first call to the date( ) function returns the current day of the week and date, and its string input parameter indicates how we want this information formatted. Similarly, the second call to date( ) returns the time of day. We’ll examine the details of these function calls in a moment. Once we get the date and time information in our requested formats, and these strings have been combined with the rest of the HTML markup, the final result becomes the body of the HTML document sent to the browser.

One other thing: The two-character combination as we have used it here is not really necessary, since the output from the PHP echo statements in this case is HTML markup and, as we know, end-of-line markers other than <br> are generally ignored by HTML. So these characters may sometimes be stripped out along the way, or simply ignored at the destination. On the other hand, if the output is going to a destination that is not HTML (just ordinary text output, for example), and other end-of-line markers are in fact needed, then including this character combination should do the job of ensuring that proper line breaks will occur at the necessary places on most any platform where the message might have to be displayed. Some platforms may require both and , while others may require just one of the two. On any platform requiring only one of the two, the other of the two should, and with any luck will, simply be ignored.

8.3.1 The PHP date( ) Function

Since we have found it so useful, and you may too, let’s take a moment to discuss the built-in PHP date( ) function as we have used it. It is, of course, just one of many built-in functions provided by PHP, but a very handy one. The date( ) function can be quite complex, and you may wish to pursue further details about it and other frequently used, predefined PHP functions that we will discuss later.

In the meantime, let’s see what our calls to the date( ) function actually do. The function expects as input a string that specifies the format of the output string (i.e., the returned string value, since this is a value-returning function). The format string that we supplied in our first call to the function was "l, F jS". Unfortunately, the meaning of these symbols is not very mnemonic, and thus not easy to “guess”, so let’s explain what they mean.

First, the lowercase letter 'l' (not the digit 1, which is the first potential point of confusion) says that we want a full textual representation of the day of the week, such as Sunday, Monday, and so on. The next two characters (the comma and the blank space) are to be interpreted literally to give us a comma and a blank space following the day of the week in the output. Then the character F says we also want the full textual representation of the month, such as January, February, and so on. This is again followed by a literal blank space. Finally, the two-character sequence jS gives us the numerical date with an appropriate suffix appended, such as 1st, 2nd, 3rd, or 4th. The character j gives us the date, while the S character gives us the appropriate suffix (st, nd, rd, or th). As we said, somewhat demonic, rather than mnemonic.

Our second call to date( ) has as its input parameter the string "g:ia", which in fact gives us a time rather than a date, and things are no better here on the mnemonic front. The g gives us the current hour using a 12-hour format, without leading zeros, the i gives us the minutes in the current hour, with a leading zero if required, and the a appends a lowercase am or pm, as appropriate. The colon (:) is a literal value used to separate hours and minutes in the output.

See the end-of-chapter References for a link to a description of all the many ways you can describe the kind of output you want from the PHP date( ) function.

8.3.2 Generating and Displaying the Output from welcome.php

If you view the web page generated by welcome.php now, you should see something like what is shown in Figure 8.2. But, if you then choose the “view source” option of your browser, you will not see any PHP code. This should not be surprising, given what we have said earlier. Only the HTML markup resulting from the execution of the PHP code will appear as the source of the web page. As mentioned before, this ensures that clients cannot access the PHP code, which may reveal confidential information about the data stored on the server.

8.4 Why We Need AJAX and How We Use It: Two More Examples

In this section we introduce the basic ideas and functionality of AJAX, and show how a very simple application of these ideas can be very useful on our Nature’s Source website.

8.4.1 What Is AJAX?

Under “normal” circumstances, when a browser sends information to a server and the server responds by sending a page back to the browser, the entire page must be redisplayed in the browser, even if only a small portion of that page has actually changed. This can cause browser response to slow down and generally appear to be much less satisfying to a user than a typical desktop application. A technology called AJAX can be used to help alleviate this situation. JavaScript (in conjunction with XML, which we will introduce briefly in a later chapter) can be used to communicate with the server and update only the changed part of a web page, thus speeding up the page-refresh process.

Note that AJAX is not a distinct new technology, but simply a way of combining a number of previously existing technologies. For the insight that spawned AJAX we are indebted (as we have pointed out in Chapter 6) to Jesse James Garrett, who also gave us the acronym.

8.4.2 A Problem We Need to Solve: A “Page Refresh” Example

We are now going to use the web page shown in FIGURE 8.3 (HTML markup and PHP script) and FIGURE 8.4 (corresponding browser display) to illustrate several things, only one of which is our need for AJAX.

Let’s begin by explaining how this page works. If you load the page into a browser, all the text will be black, but if you wait for a minute all the text will change color. At the end of each subsequent minute, one of four random colors is chosen and the text appears in that color. This is because the entire page is being “refreshed” every 60 seconds, which is accomplished by the meta element in line 17, whose two attributes (http-equiv="refresh" and content="60") should be self-explanatory. You can arrange for any web page to be refreshed with whatever frequency you desire with a similar meta element and the value of its content attribute set to the required time interval in seconds.

The “problem” with this is that the entire page is refreshed. It’s not a problem if that’s what we want, but if only a small part of a page (the date and time, for example) needs to be updated periodically, then refreshing the entire page represents a lot of wasted effort (and bandwidth). Sometimes the “problem” is just this wasted effort and bandwidth, but a complete page refresh can be a problem in other ways as well. For example, if a user is filling out a form and suddenly the page refreshes, the user may lose some or all of the data entered into the form and will need to start over and try to enter all the form data and submit it before the next refresh. This is likely to generate unhappy users, something no e-commerce website should have.

FIGURE 8.3 ch08/welcome_refresh.php

A second version of our Welcome message page, in which the entire page is “refreshed” every 60 seconds. The time is updated, as is the date (if necessary), and a randomly chosen text color is applied to the entire page. The $_SESSION array is used to monitor the refresh count.

FIGURE 8.4 graphics/ch08/displayWelcome_RefreshPhp.jpg

A Firefox browser display of ch08/welcome_refresh.php after at least one refresh has taken place and the color green has been applied to all text on the page.

This is the problem that AJAX solves for us, as we will see in the next example. However, before we leave this example we want to discuss some other aspects of PHP that it illustrates for us.

PHP Sessions and the PHP $_SESSION Superglobal Array Variable

Web pages have no memory. That is, if you load a web page into your browser and then load a second page by clicking on a link in the first page (or by just entering a new URL in your browser’s address box), the new page has no idea how you got there or where you came from. This is the default situation, which is sometimes expressed more formally by saying that the HyperText Transfer Protocol (HTTP) protocol is a stateless protocol. This default behavior can be quite limiting, since it does not allow information to be passed from one page to another as a user browses around a given website. However, e-commerce websites in particular, among many other kinds of websites, do need to keep track of what users are doing as they move from page to page while viewing, choosing, and buying products, for example.

This is another problem for which we need a solution, and in our case the solution is a PHP session. When a PHP session is created, a PHP superglobal variable named $_SESSION is also created on the server. This variable is a PHP array variable that can be used by the current and subsequent PHP scripts during the same “session” to store and retrieve information. In other words, this $_SESSION array variable provides a mechanism that allows web pages to communicate as the PHP scripts on those pages execute. It can also give a page “memory”, since if a page that was previously loaded is loaded again, it can “recall” (i.e., refer to) information that was previously stored in the $_SESSION array, either by itself or some other page.

In line 9 of Figure 8.3 the call to the session_start( ) function sets up a PHP session and the $_SESSION array becomes available. If there is already a session in progress, this call means that this current script simply “joins the session” and has full access to the already-existing information in the $_SESSION variable.

Note that the array variable name $_SESSION begins with a $. This is true of all PHP variables and is part of the Perl legacy. For another example, the “ordinary” (non-array) variable $greetingColor in line 23 also begins with a $. Like JavaScript variables, PHP variables are case-sensitive and “enjoy” the convenience of dynamic typing. That is, a variable takes on the type of whatever value is currently assigned to it. Superglobals like $_SESSION also have an underscore (_) as their second character, and all letters in the name are uppercase. We discuss two other superglobals, $_GET and $_POST, in a later section.

Arrays in PHP can be used just like the arrays in JavaScript, but PHP arrays are actually much more flexible. In particular, we can treat them as associative arrays. This means that we don’t have to restrict ourselves to using non-negative integers as index values. We can also use strings, as we do when we perform the initialization in line 11 of Figure 8.3:

$_SESSION['pageRefreshCount'] = 0;

Think of this either as “associating” the numerical value 0 with the string value 'pageRefresh-Count', or as creating a key/value pair in which 'pageRefreshCount' is the key and 0 is the value. Note that before doing this initialization we use the PHP built-in function isset( ) to make sure the location in the array where we’d like to store the 0 does not already have a value. We make the test using a PHP if-statement. The syntax of the if-statement (or the if..else-statement) in PHP is the same as it is in any C-based programming language, and we have already seen that syntax in JavaScript.

How the Page Works

In the script of Figure 8.3 we have a simple use for the $_SESSION superglobal. We just want to keep track of how many refreshes have taken place. Let’s describe the execution flow. The first time the page is loaded we start (or join) the session and initialize the refresh count to 0 in lines 9–11. Then, in line 23, we explicitly set the color to be used for the page text to be black, though this is in fact the default color. Next, the test in the if-statement in line 24 fails because the “refresh count” at this point is 0, so we do not change the color of the text. (We discuss how the text color is changed by this if-statement shortly.)

Next, in line 36 the refresh count is incremented so that it will not be 0 on any subsequent loading of this page. Then the date and time information is displayed (lines 38–41), using black as the text color.

The next question to be answered is this: How will the browser know what color to use for the text when it displays the date and time information? The answer lies in the rather mysterious line 37 of Figure 8.3. In that line the PHP script sends to the browser (via an echo-statement) a “hidden” p element, which is not displayed in the browser because of its hidden attribute, but whose content will be the color the browser is to use for the page text when the page is displayed. The browser retrieves this color via the JavaScript in lines 49–53, that is, by first getting a DOM object reference to the “hidden” paragraph in the usual way using getElementByID( ) and the id value of that hidden paragraph, after which the innerHTML property of that object gives the required color. It is hiddenParagraph.innerHTML that refers to the content of the hidden paragraph where the required color is stored. That color is then used to set the text color of the entire page (in lines 51–52), since it is the body element that has the id value "welcome".

Actually there is a little more than this going on in line 37. First, note the use of both double quotes and single quotes. This kind of usage is common and often necessary (as in this case) in scripting languages like JavaScript and PHP that allow strings to be delimited by either type of quotation mark. But the other really important thing that shows up here for the first time is variable interpolation, which is something that takes place in PHP (but not in JavaScript). What this means (in this case, as in any analogous situation, of which we will see many more as we go along) is that the string sent by the echo statement in line 37 does not contain the name of the variable $greetingColor; it will contain instead the value of that variable. This is what happens when the variable appears inside double quotes. Note, however, that this variable interpolation (replacement of a variable by its value) does not happen if a variable appears inside single quotes.

Finally, let’s look at how the text color is chosen in the body of the if-statement in lines 26–34. This code will be executed every time the page is loaded after the first time. The first thing that happens is the call to the rand( ) function in line 26, which returns a value in the range from 1 to 100 (inclusive of both). The following nested if-statement (lines 27–34) then checks to see where within that range of values the generated random value falls, and sets the color accordingly. It is now that randomly chosen color that is passed as the content of the hidden paragraph element, as discussed above.

8.4.3 The Solution to Our Problem: An AJAX Example

In the previous section we discussed an example in which an entire page was refreshed, even though only a part of the page actually needed refreshing. In this section you will see how AJAX helps us to refresh just the part of the page that needs updating.

For this discussion we need to refer to FIGURES 8.5 and 8.6 for the markup and code, and to FIGURE 8.7 for the corresponding browser display. We begin with a high-level view. In Figure 8.5 we have a script element within the head element. This script element contains the definitions of the two JavaScript functions getCurrentTime( ) (lines 25–32) and updatePage( ) (lines 33–42) that we call later on in the second script that appears at the end of the body element in our document (lines 61–64).

FIGURE 8.5 ch08/welcome_ajax.php

A third version of our Welcome message page, in which only the date and time information is updated and given a randomly chosen color every 60 seconds, this time via AJAX communication with the server.

FIGURE 8.6 ch08/time.php

The PHP script that produces the date, time, and color choice (on the server) that is sent to the browser for inclusion in our Welcome message. This is the PHP script response to the AJAX request seen in the code of Figure 8.5.

Now let’s itemize the things that take place when this page loads:

  1. As in the previous example, we start a PHP session and initialize a counter (lines 12–14). Note that this time around we call our counter key timedateRefreshCount rather than the former pageRefreshCount because in this example it is only the time and date information that will be refreshed, not the entire page.

  2. The script element in the head element of the document defines two JavaScript functions that we call later.

  3. The complete page is displayed for the first (and only) time by lines 46–60. This display includes the content produced by the short PHP script in lines 47–50, which we have discussed previously. Note in passing, however, that the value of the id attribute of the h3 element in the PHP script output is "timedate", since we will want to refer to this later.

    FIGURE 8.7 graphics/ch08/displayWelcome_AjaxPhp.jpg

    A Firefox browser display of ch08/welcome_ajax.php after at least one AJAX request has taken place and the color red has been applied to just the (updated) date and time information lines on the page.

  4. Now we come to the script element in lines 61–64. The first thing this script does is call the JavaScript getCurrentTime( ) function, defined above in lines 25–32. This function, in turn, begins by creating an object reference of type HttpXmlRequest (line 27) and assigning it to the variable request. This is the object that will make our AJAX request to the server. To do this it needs to know the name of the script on the server to which it should make its request. We supply the name of the script to the variable url in line 28 and use this variable as one of the parameters in the function call on the next line. There is a bit of subtlety in calling the variable url, even though its value is just the name of a PHP script file. We can use only the file name because that script file is located in the same directory as the web page from which it is being called. But it could be a script that is located elsewhere at a location that would have to be given as a “real” URL for the value of the url variable.

    Next (line 29) a call to the request.open( ) function opens a connection to the script at the given url value (the second parameter), indicating the method for passing the data will be the GET method (the first parameter in the function call, and discussed in detail in section 8.6). The third parameter in the function call is the boolean value true, which in this case indicates that the connection is to be asynchronous. This means that once the connection has been made, the browser can carry on with other business and doesn’t have to wait until the connection is finished doing whatever it has to do and closes.

    The browser needs to know what to do when it hears back from the server. In this case we assign to the request.onreadystatechange property of our request object a reference to our JavaScript updatePage( ) function (line 30). But note that there are no parentheses following the function name in line 30 because we are not calling the function at that point. The function will be called only when the “ready state” of the function changes, in other words only when the browser hears back from the server.

    Finally, now that we are all set up, the AJAX request is sent to the server in line 31. The parameter is null in request.send(null) because we have no additional information to send to our server-side script.

  5. Let’s shift to a server-side view and look at the server-side PHP script time.php shown in Figure 8.6. There is really nothing here we haven’t seen before; we have just grouped, consolidated, and rearranged some of the PHP code shown in Figure 8.3. But let’s describe what it does in this new context.

    The script begins by “joining” the PHP session that has already been started by lines 12–14 in Figure 8.5. Since this is the first call to the time.php, the “time date refresh count” will be 0, so the “greeting color” will be reaffirmed to be black. The date and time are then computed and sent back to the browser, along with the hidden paragraph containing the text color. Then, just before the script ends, the count is incremented so that on subsequent runs of this script it will not be 0, and a random color will be chosen for the text of the date and time display.

  6. Now we go back to what’s happening in the browser and look again at Figure 8.5. When the time.php script sends its information back to the browser, the “ready state” of the request object will change, and that’s when our second JavaScript function update Page( ) is called. The body of this function (lines 35–41) consists of a single if-statement that tests the readyState value of the request object. It can have several values, but we want it to have the value 4, which essentially means “everything’s OK”. In that case the body of the if-statement is activated, so we get a reference to the h3 element with id value "datetime" and change its text color to whatever color came back from the server as the content of the hidden paragraph.

  7. The call to the global JavaScript function setInterval( ) in line 63 of Figure 8.5 says, “Call the getCurrentTime( ) function every 60000 milliseconds (every minute), from now on.” Henceforth, then, the whole process will repeat, and from now on some color other than black will be used. Note, however, that although a “new” random color is chosen every minute, because there are only four colors from which to choose it may well be the case that the same color appears for two (or even more) intervals in a row.

8.5 Incorporating the Welcome Message into Our Home Page with AJAX

We are now ready to incorporate our welcome message, along with the current date and time, into the home page for our Nature’s Source website, as shown in FIGURE 8.8. As you can see from that figure, this information appears at the upper right of the page, next to the logo. You have already seen, in an isolated example in the previous section, how this can be accomplished using AJAX. So here you need only to look at how the necessary code is incorporated into our Nature’s Source website.

FIGURE 8.8 graphics/ch08/nature/displayIndexPhp.jpg

A Firefox browser display of ch08/nature/index.php containing our Welcome message, which includes the current date and time produced by a client-side AJAX request and the corresponding server-side PHP script response, and is refreshed every 60 seconds. Photo: © coloroftime/iStockphoto

First, look at our revised index file in FIGURE 8.9. This file is now called index.php rather than index.html, because it now contains embedded PHP code. Note that the file contains two short PHP scripts, one in lines 5–8 and the other in line 33. These scripts contain only calls to the PHP include( ) function that is now being used to perform our “server-side includes”, but the presence of these two PHP scripts is the reason we have changed the name of the file from index.html to index.php. Note that we can use the PHP include( ) function to include either strictly HTML files, like menus.html and footer_content.html, or an HTML file that itself contains an “embedded” PHP script, like banner.php.

Second, look at banner.php in FIGURE 8.10, which replaces the previous logo.html. We see that it contains two div elements and a script element whose body is our AJAX-related JavaScript code. The first div is just the div with id value "logo" from our previous logo.html file. The second div, with id value "welcome", has the same content we saw in the body element of welcome.php, except that we changed “The time” to a friendlier “Our time” and changed the header sizes to better accommodate the message location.

FIGURE 8.9 ch08/nature/index.php

The HTML markup for the index file of this chapter’s version of our complete Nature’s Source website. Note that the header element now includes both an external PHP file and an external HTML file.

Finally, as we mentioned earlier, although we do not show it in the text, we have slightly modified the CSS files for this version of the site to style the new contents of banner.php.

FIGURE 8.10 ch08/nature/common/banner.php

The HTML markup and JavaScript code of our new banner file, which essentially replaces the previous logo.html and includes that logo as well as the necessary code to handle the AJAX request for a time and date update.

The net effect of all these changes is that the Welcome! greeting (with the periodically updating date and time) that we see in Figure 8.8 appears to the right of our logo on each of our website’s pages because banner.php is included at the beginning of each page.

8.6 Understanding the GET and POST “Methods”

In the next section we will begin our discussion of the “back end” or “server-side” of our website functionality. We will start with our feedback form, but for that discussion, as well as for the discussion of our revised BMI form later in this chapter, and our e-store scripts in Chapter 10, we need to understand more about how data is transmitted from client to server.

When data is transmitted from a form on the client to the server, the opening form tag will have two essential attributes that relate to the processing of the form data: the action attribute and the method attribute. Here is the opening form tag from the current version of our feedback form, found in lines 13–14 of ch08/nature/pages/feedbackForm.php:

<form id="contactForm"
  action="scripts/feedbackFormProcess.php"
  method="post">

The value of the action attribute is the server-side program (a PHP script in our case) that will process the data from the form, and the value of the method attribute determines how the data from the form will be passed from the client and made available to that script on the server. We will come back to this feedbackForm.php later, but in this section we want to discuss several small examples isolated from any other distractions on our Nature’s Source website to highlight just the data-transfer process.

The two values of the method attribute that we need to understand in this context are "GET" and "POST", which we often refer to as “the GET method” and “the POST method”. These values are case-insensitive, but when we discuss them here and later in the text we use all caps to help them stand out. In actual markup you may see either (uppercase in line 23 of Figure 8.10 and lowercase in line 18 of FIGURE 8.11). Note that the term method as used here has nothing to do with the way we use the term when we speak of “calling a method” in a programming language such as PHP or JavaScript. That’s why we put the word in quotes in the title of this section.

8.6.1 An Example Illustrating the GET Method

Look first at test_get.html in Figure 8.11, in which the important things to note are method="get" in line 18, and "value1" and "value2" as the values of the name attributes for the two input elements (lines 19 and 20). Second, look at the corresponding display in FIGURE 8.12, in which the numerical values 2 and 5 have been entered into the form. If we now click on the Submit button, we will get the web page response shown in FIGURE 8.13 that is produced by the PHP script shown in FIGURE 8.14.

Look carefully at the content of the browser address bar in Figure 8.13, where you see this:

cs.smu.ca/webbook2e/ch08/test_get.php?value1=2&value2=5&submit=Submit

This is the URL of the script that processes the form data from test_get.html, but with some additional information tacked onto its end. What you’re seeing here is a typical example of how the GET method transfers form data from client (the browser) to server. Note first the two key/value pairs: value1=2 and value2=5. Now value1 and value2 are the “values” of the name attributes of the two input elements that accept the two numbers seen in the form of test_get.html (lines 19 and 20 of Figure 8.11), and 2 and 5 are the numbers we have entered into the textboxes created by those two form elements (see Figure 8.12).

FIGURE 8.11 ch08/test_get.html

The HTML markup for a page with a simple form requesting two input values, as shown in Figure 8.12.

If more form data was being submitted by the GET method, you would see more of these key/value pairs. The other important part of the syntax is this: The key/value pairs are separated by an ampersand character (&), and the sequence of key/value pairs is separated from the URL itself by a question mark character (?). Note that you also see at the very end of the URL the key/value pair submit=Submit. Even though we do not use this data on the server side, the information is sent simply because the corresponding input element has a name attribute (line 21 of Figure 8.11). From this you should be able to see why it is so important for any form control that has data that needs to be transferred to the server to have a name attribute.

So that’s one way that data can be transferred from client to server. How is this data received on the server side? Now you need to look at the PHP script in Figure 8.14 that receives and processes the data, and this is where another superglobal variable, namely $_GET comes into play. When we use the GET method to transfer our form data, the key in each key/value pair becomes a key (or “string index”) in the superglobal $_GET on the server side If this variable does not exist, it will be created. And, probably not surprisingly, the value associated with that key in the $_GET array is the value assigned to that key in the corresponding key/value pair that was passed at the end of the URL when we submitted the form. In other words, for example, in the particular example we discussed above, the value of $_GET['value1'] is 2 and the value of $_GET['value2'] is 5.

FIGURE 8.12 graphics/ch08/displayTest_GetHtml.jpg

A Firefox browser display of ch08/test_get.html, with the two requested values filled in and the form ready to be submitted.

In line 12 of Figure 8.14 we use these values to perform a simple calculation and output the result. Nothing unusual there. However, note carefully line 10 of Figure 8.14, in which we simply display these two values. In this case the array values appear within a double-quoted string and now it is important that the key values of the array components within the square brackets not be quoted, if we want to be sure the interpolation happens properly.

You will encounter this difference in the use of quotes quite frequently as time goes on, so you may want to come back and revisit this example. Be sure to read the comments in lines 14 –19 of Figure 8.14, which also summarize what we might think of as a “best practice” for this situation.

Before we leave this example, we should point out that we also use it to illustrate the scope of a variable declared within a PHP function (even though this has nothing to do with GET or POST). Unlike JavaScript, PHP has no var keyword. In JavaScript we recommended always declaring a variable with the var keyword. This would ensure that a variable declared and used inside a function could only be seen inside that function and thus could not be inadvertently changed by something outside the function. Even without a var keyword, a variable declared inside a PHP function is still “local” to that function and cannot be seen outside the function. You should convince yourself that the rest of the script in Figure 8.14 (lines 21–33) illustrates this fact. Note in particular the definition of a simple PHP user-defined function, which is completely analogous to function definitions in JavaScript.

FIGURE 8.13 graphics/ch08/displayTest_GetPhp.jpg

A Firefox browser display of the page output produced by the script in Figure 8.14 when the form in Figure 8.12 is submitted.

8.6.2 An Example Illustrating the POST Method

In Figures 8.11 to 8.14 we illustrate the GET method for transferring data from client to server. We also have a similar example illustrating the POST method, but the differences are not sufficient to justify another four figures here in the text. However, you should run the example, study the corresponding files, compare what you see with the analogous displays in Figures 8.11 to 8.14, and we will point out here the only major differences you should observe.

The two files that comprise the example are test_post.html and test_post.php, which correspond to the test_get.html and test_get.php files from the previous example. If you now load test_post.html, you will get a display with a form similar to what you see in Figure 8.12. The markup in test_post.html will, of course, have method="post" instead of method="get" in its opening form tag. If you enter two values and click Submit, you will get a display that looks like just the first two lines of Figure 8.13, since we do not repeat the last part of that example.

FIGURE 8.14 ch08/test_get.php

The PHP script that produces the page shown in Figure 8.13 when the form shown in Figure 8.12 is submitted.

The important thing to do at this point is to look at the content of the browser address window of your display. This time you will see only the URL of the test_post.php file, with no data attached to the end of that URL. That’s the major visible difference between GET and POST. In the case of the POST method, the data is transferred “behind the scenes” and is not visible in the address window.

8.6.3 An Example Illustrating That a Form Is Unnecessary and GET Is the Default

In the previous two examples we have illustrated how to submit form data to a script on the server, first by the GET method, and second by the POST method. However, it is possible to pass data directly to a PHP script without using a form, and often very convenient and useful to be able to do so. All we have to do is attach the data to the end of the script URL using the same syntax that we have already seen in the context of the GET method. The script can then access the passed data using the $_GET superglobal. We sometimes refer to this scenario by saying that GET is the “default” data-transfer mechanism, since we do not have to specify anywhere that we are actually using the GET method. This technique is very useful if several scripts are running on the server, are cooperating to perform a particular task, and some data needs to be passed from one script to another. Chapter 10 will illustrate this at several points.

This is illustrated by FIGURE 8.15 (display) and FIGURE 8.16 (script). Figure 8.15 is obtained by loading the script in Figure 8.16 with the data you see at the end of its URL in the browser address window shown in Figure 8.15. The output in Figure 8.15 is produced by the PHP code in lines 29–37 of Figure 8.16. The new thing in this code is line 33. We said previously that superglobal array keys should not be single-quoted when they appear within double quotes. However, the required interpolation will happen if we enclose the array component within braces (curly brackets), as we do here. We do not recommend this; we show it only because you may run into it and wonder what on earth is going on.

FIGURE 8.15 graphics/ch08/displayGet_Is_The_DefaultPhp.jpg

A Firefox browser display of the output of the PHP script shown in Figure 8.16 when it is run with the input data seen at the end of the URL in the browser address box of Figure 8.15.

FIGURE 8.16 ch08/get_is_the_default.php

A PHP script that illustrates (among other things) that GET is the default method used to transfer data to a server-side script when that data is attached to the end of the URL of the script.

And finally, before leaving this example, note that we have again taken the opportunity to illustrate a couple of new and useful PHP features, in this case to make our script a little more “user-friendly”. You can see what we mean if you just load the script with no data at the end of its URL.

First, if you look at the if-statement starting in line 18 of Figure 8.16, you will see the built-in PHP count( ) function being used to check the size of the superglobal array $_GET. If the function returns a value of 0, that means the array is empty, and thus no data has been passed to the script. In this case, the body of the if-statement is executed, so the user instructions are output by the echo-statement and then the script terminates immediately with the exit(0) function call.

Here the echo-statement itself (lines 20–26) is perhaps more interesting than any we’ve yet seen, and contains what PHP (and some other languages) call a here document. This is kind of an odd name, so just think of it as saying this: here’s some text . . . just output it! Note that the text to output is not a string in the usual sense; that is, it is not enclosed in quotes of any kind. Instead, its beginning is indicated by the <<<INFO marker, and its end by the INFO; marker, where INFO is just a programmer chosen name, capitalized for easier visibility. The text is output “as is”, but note that in this case the text is going to an HTML document, which means that we can include HTML tags (like <pre> and <code>) and expect to have them properly dealt with at the destination.

This example also illustrates the usual syntax for a here document, but we should point out that the closing delimiter (INFO; in this case) must use the same name as the opening delimiter, must be on a line by itself, must start at the left margin, and must have a semicolon (;) at the end (see line 26 of Figure 8.16).

8.6.4 Guidelines for Using GET and POST

Since we now have these two methods—GET and POST—for transferring data, an obvious question arises: When do we use each? If you think back to the examples we used to illustrate these two methods, you may be able to make an intelligent guess at the answer.

Recall that when we use GET, the information sent appears in the browser address window at the end of the relevant URL. From this we can conclude that we should not use GET for any situation in which we would not want a user (or someone looking over a user’s shoulder) to see the information we are sending. This is just a simple common-sense security precaution.

Somewhat less obvious, but also true, is that when using GET the amount of data we can send is subject to a limit that may depend on both the client and the server, but essentially (once again) because all the data has to be tacked on to the end of the URL.

Both of these problems are solved by using POST. The GET security issue is not present when using POST, because the data transferred is not seen by the user. And the limitation on the amount of data transferred when using GET is not an issue either, since there is virtually no limit on the amount of data that can be transferred using the POST method.

And now you’ll be asking the following question: So why don’t we always just use POST? Well, it has to be admitted that GET is very convenient, especially since we can use it without the bother of setting up a form from which to send the data.

So, the web community seems to have settled on the following guidelines for the use of GET and POST:

  1. Use POST if you are transferring a lot of data.

  2. Use POST if you don’t want the information you are sending to be visible in the browser’s address box.

  3. Use POST if the information you are sending is going to change something at the destination (the content of a database, for example).

  4. Use GET if you are just retrieving some information from the destination (getting information from a database, for example).

  5. Use GET for short communication between scripts on the server.

  6. Definitely use GET if you are sending small amounts of data, you don’t care who sees it, and you don’t want or need to bother setting up a form.

8.7 Implementing the Server-Side Functionality of Our Feedback Form

Now we continue putting PHP to work in the ongoing development of our e-commerce website. We start by implementing the remaining part of our website’s feedback facility. This will involve sending emails (to both the business and the client), preparing a browser display for immediate confirmation to the client, and storing information on disk (on the server) for future reference by the business, if required.

Recall that we created the feedback form itself in Chapter 5 and then, in Chapters 6 and 7, we showed how we could provide data validation support for that form using JavaScript and/or HTML5. However, when a user “submitted” the feedback form, all that happened was the validation of the data followed by a brief report to the user that the data was “OK”; there was no actual “submission” or any other communication between the customer and the business.

Client-side JavaScript programming does not allow you either to send emails or to upload information to the server, and there is good reason for such restrictions. If such activities were permitted, malicious web programmers could entice clients to their websites and when those users downloaded web pages from such sites, those pages could contain JavaScript that would use the client computer to send out spam, worms, viruses, or other kinds of malware. The origin of such emails could only lead forensic investigators back to the client’s computer, and it might be very difficult to establish the true origin of such unwelcome software. Hence, any emails that are triggered by a user’s interaction are best sent directly from the web server. This is achieved through server-side programming. So, we will now use our feedback form to demonstrate the following:

  • How to upload to the web server the information that has been entered into the form

  • How to send email based on that information (to the business, as well as to the user)

  • How to confirm to the user that the submission has been made, with a browser display based on the submitted data

  • How to store the uploaded information in a file on the web server, for future reference by the business if desired

8.7.1 What Happens When the User Clicks Send Feedback

FIGURE 8.17 shows this chapter’s feedback form all filled out and ready to be submitted. When the user clicks the Send Feedback button, the first thing that happens is the validation of the form data. If there is a problem with any of the data items being validated, the form data will not be submitted. Instead, the user will get a message of the type previously seen, and will have to correct the offending data item and resubmit.

On the other hand, if all of the data is valid, the data from the form will be sent to the server for processing by the PHP script shown in FIGURE 8.18, after which the following four things will happen:

  • The PHP script sends an email to the business, like the one shown in FIGURE 8.19.

  • The PHP script also sends a second email to the client as a permanent confirmation of the feedback submission. This consists of a message like the one shown in FIGURE 8.20.

  • The user also gets an immediate browser-display confirmation that the feedback submission has been received, which is shown in FIGURE 8.21.

  • Finally, a copy of the email message shown in Figure 8.19 is appended to a textfile on the server’s disk, which contains all previous user feedback submissions from this form. This version of the message looks like the sample shown in FIGURE 8.22. Note that the date of submission has been prepended to the version of the message stored on disk.

FIGURE 8.17 graphics/ch08/nature/displayFeedbackFormPhp.jpg

A Firefox browser display of ch08/nature/pages/feedbackForm.php, with the form completely filled out with valid information and ready to be submitted.

FIGURE 8.18 ch08/nature/scripts/feedbackFormProcess.php

The PHP script that processes submitted feedback form data such as that shown in Figure 8.17.

FIGURE 8.19 graphics/ch08/nature/displayFeedbackFormProcessPhpEmailBusiness.jpg

A roundcube web email client display showing the email received by the business as a result of submitting the form data shown in Figure 8.17.

FIGURE 8.20 graphics/ch08/nature/displayFeedbackFormProcessPhpEmailClient.jpg

A roundcube web email client display showing the email received by the user (the business client) as a result of submitting the form data shown in Figure 8.17.

In the following sections we discuss in detail how each of these items is constructed and sent to its required destination.

8.7.2 Uploading the Feedback Form Data from the Client to the Server

We developed our feedback form and its data validation over Chapters 5, 6, and 7, but only now do we get to finally submit the form and have it processed on the server. The current version of our form is found in the file ch08/nature/pages/feedbackForm.php . We do not reproduce that entire file here. Instead we just remind you that, as we mentioned earlier, the opening form tag now looks like this (lines 13–14 of the file):

FIGURE 8.21 graphics/ch08/nature/displayFeedbackFormProcessPhpBrowser.jpg

A Firefox browser display of the web page that provides immediate confirmation that feedback has been received, after submission of the form data shown in Figure 8.17.

FIGURE 8.22 ch08/nature/data/feedback.txt

The feedback message, with date of submission, as it is stored (for the business) on the server in the log file ch08/nature/data/feedback.txt.

<form id="contactForm"
  action="scripts/feedbackFormProcess.php"
  method="post">

Note the absence of an onsubmit attribute and any call to a JavaScript function, because the validation is now being done via the HTML5 pattern attribute. The value of the action attribute of the form element is now a call to the PHP script feedbackFormProcess.php, which lives on the server (in ch08/nature/scripts), and which will process the data that is sent to the server from this form. And also, as we discussed in detail earlier, the method attribute of the form tag has the recommended value of "post" when we are sending information that is going to be stored on the server.

8.7.3 An Overview of the PHP Code That Processes the Feedback Form Data

It’s now time to look closely at the PHP code that makes all of this possible: the two emails, the browser display confirming the submission, and a log of the submission being recorded on the server. The relevant PHP script is ch08/nature/scripts/feedbackFormProcess.php, shown in Figure 8.18.

Remember as well that in this context we will not use an integer index on the server side to access any value in the $_POST array. Instead we will think of the names we gave the form controls in our HTML document form (using their name attributes) as the keys to provide access to the corresponding data values input by the user. For example, we will use $_POST['firstName'] for access to the user’s first name because we gave the attribute name='firstName' to the input element into which the user entered his or her first name.

The script essentially consists of string manipulations to dynamically create the two email messages, the web page reply, and the log message. The message is slightly different in each case, depending on the recipient and where it is to be sent. Note that we have inserted descriptive comments to describe the script as a whole, as well as the various logical subsections of the script. The two forward slashes (//) that we used in JavaScript to give us a single-line comment are available for the same purpose in PHP as well, and the /* ... */ delimiters for multi-line comments are also available.

8.7.4 Building the Feedback Message to the Business with PHP String Literals and the $_POST Array Values

In this section we discuss the code segment in lines 12–17 of Figure 8.18 and the content of the corresponding email message of Figure 8.19. These lines construct the basic message that is sent via email to the business, and that forms the basis of all the messages we will build. This message is constructed using the text values from the input controls of our HTML feedback form, which are available as values of the $_POST array, as discussed earlier. Note once again, as we illustrated in our discussion of GET and POST, when either $_GET or $_POST is used inside double quotes, the key values inside the square brackets used with them should not be enclosed in quotes.

The complete result that is assigned to the variable $messageToBusiness is formed by joining the values from the $_POST array to the necessary “infrastructure” text items, such as

"From: "
"Email address: "

and so on. We are, in effect, putting email header information in front of the message text, because we are, after all, constructing a complete email.

Once the message has been constructed by joining all the required text items with the period (.) concatenation operator, we then assign the completed result to the variable $messageToBusiness.

8.7.5 Sending an Email Feedback Message to the Business with PHP’s mail( ) Function

We are now ready to send our message via email, and in this section we discuss the code segment from lines 21–23 of Figure 8.18, which deal with the actual sending of the email to the business, as shown in Figure 8.19.

The email is sent using the PHP built-in mail( ) function. The mail( ) function creates a message based on the Simple Mail Transfer Protocol (SMTP) specifications. SMTP is an Internet standard for sending email. The mail( ) function creates an SMTP-conforming email message using the following parameters:

  • The email address of the recipient

  • The subject of the message

  • The message itself

  • Additional strings that you may want to be appended to the header, such as From:, CC: (Carbon Copy), or BCC: (Blind Carbon Copy) fields. These fields have to be separated from the other fields, and from each other, by the sequence.

Under normal circumstances the business would be the recipient of this email message, but here we are using the email address of the book’s website as a temporary placeholder for “the business”, since we do not have an actual business email address. The subject for the email is whatever the client entered into the input element of the form with name='subject', so it is available from $_POST['subject'], and note that here the quotes enclosing the key value are needed. The message we want to send is the one we constructed above and is now the content of the variable $messageToBusiness.

The only thing still missing is any additional header lines that we may wish to add. We choose to add just a "From: " field by supplying the variable defined in line 21 as the fourth (optional) parameter to the mail( ) function:

$headerToBusiness = "From: $_POST[email]
";

Although this fourth parameter is optional, it is a good idea to include it with at least a "From: " field, because this will indicate, in the recipient’s mail program, who sent the message. This information is in the body of the message as well, of course, but without this “header” information, the mail message may appear, in the recipient’s mail program, to have been sent by a web server and may run the risk of being deleted or sent to a spam folder.

It won’t hurt to point out that in line 21 you are again seeing PHP’s variable interpolation in action, and this is a case where the key value within the square brackets should not be enclosed in single quotes.

Now that we have all four required parameters for the mail( ) function, we can issue the function call that sends the email message to the business, which we do in lines 22–23. This results in the “business” receiving the email message shown in Figure 8.19.

Of course, PHP also has to be able to access the email system on your server, which is another aspect of PHP configuration and you should confirm with your system administrator that your PHP installation has this access.

8.7.6 Modifying the Previous Message to the Business to Get One Suitable for the Client

In this section we discuss the code segment from lines 28–36 of Figure 8.18, which deal with the construction of the email to the client seen in Figure 8.20.

This part of the script builds an additional email message, based on the previous one sent to the business. This time the message is a confirmation to the client. We create this confirmation message by first prepending the message with additional text that includes a greeting to the user using the salutation chosen by the user when filling out the form and the user’s last name (lines 29–31). We finish by appending a string containing a thank-you message and a company “signature” (lines 33–36).

Our feedback form has also given the user the option of asking for a reply by checking the appropriate form checkbox whose name attribute has the value "reply". Thus in our PHP script we can check whether the variable $_POST['reply'] has been set (line 38) , and, if so, deduce that the user wants a reply and thus append another string to our email that informs the user that a reply will be forthcoming (lines 38–39).

The appending is done with the special operator .= in lines 38–39. The behavior of this operator is analogous to that of other similar operators like +=, *=, and so on, that appear in most of the C-based languages, such as JavaScript, in the sense that

$string1  .= $string2

is equivalent to this:

$string1 = $string1 . $string2

8.7.7 Sending an Email Feedback Confirmation Message to the Client with PHP’s mail( ) Function

In the code segment from lines 42–44 of Figure 8.18 we create the header for sending to the client the email message we constructed in the previous section, and then call mail( ) to actually send it.

There is nothing new going on here, but we should mention the following slight variation: For this version of the email, the subject is modified by preceding it with the string “Re:”, just to help distinguish it more quickly if, during testing, you are sending both emails to the same address, as we have done in our own testing.

8.7.8 Returning a Browser Display to the User for Immediate Confirmation of Feedback Submission

In this section we discuss the code segment from lines 48–54 of Figure 8.18, which produces the browser display for immediate feedback to the client seen in Figure 8.21, and which contains exactly the same textual content as the email message to the client.

However, to convert that plain text into HTML markup appropriate for display in a browser there are at least two things we need to do.

First, we need to add to each instance of r the HTML tag <br> to get line breaks in the right places when the page is displayed in the browser. This we accomplish with the built-in PHP str_replace( ) function like this:

$display = str_replace("
", "<br>
", $messageToClient);

The str_replace( ) function takes three parameters. The first parameter is the “old” string that needs to be replaced; in this case that is " ". The second parameter is the new string that will replace the old string; in this case that is "<br> ". Finally, the third parameter is the original containing string that is to be modified by the replacement; in this case that is the string contained in the variable $messageToClient. The string that is returned by the call to the function str_replace( ) is stored in a variable called $display.

Second, in lines 49–53 we surround the contents of $display with appropriate HTML markup so that the displayed page will be a complete and valid HTML5 document. The final value of $display is “echoed” back to the browser for display, resulting in the (very simple) web page shown in Figure 8.21.

8.7.9 Saving the User’s Feedback on the Server with PHP File Output

In this section we discuss the final code segment of our feedbackFormProcess.php script, lines 58–66. The purpose of this final part of the script is to write the user’s feedback to a file on the server.

A distinguishing feature of server-side programming is its ability to store information obtained from the user on the server, something that cannot be done with client-side technology like JavaScript. This information storage can be achieved in at least two ways:

  • By placing the information directly into a file on disk

  • By setting up communication with some kind of database and storing the data in the form required by that database

We will be looking at the database option in the following two chapters. In this section, we will look at the simpler case of file storage.

The feedback submitted by the user has already been sent to our business via email. However, it is also a good idea for our business to log all client feedback in a file on the server, so that we have it all in one place and can go through it at a later date to process it in some way, if we wish. We will store all user feedback in a file called feedback.txt in a subdirectory called data.

Whenever we wish to use a PHP script to write data to, or read data from, a file, the first step is opening the file. We accomplish this with another built-in PHP function called fopen( ). Typically this function takes these two parameters

  • The name of a file or a URL containing the name of a file

  • The mode in which the file is to be opened

and returns a file variable that can be used to work with the file once it has been opened.

The mode depends on the type of operation(s) we want to perform on the file once it has been opened. In our case, we are opening the file data/feedback.txt with the mode value "a" (line 58). This mode means that the file will be opened in “append mode”, which in turn means that any new writing we do will take place after the existing last character of the file. In other words, we’re adding to the end of the file. If the file does not exist, it will be created and then opened for writing. TABLE 8.2 shows a list of other modes that can be used for opening a file.

Let’s get back to our usage of this function. The value returned by the function call in line 58 is stored in a variable called $fileVar. From this point on, we can refer to the file by using the variable name $fileVar, in a read or write operation for example.

TABLE 8.2 Various modes for PHP file I/O.

Mode Description Notes
"r" Read from the beginning of the file
"r+" Read and write from the beginning of the file
"w" Write from the beginning of the file Previous contents are destroyed and file is created if it does not exist already
"w+" Read and write from the beginning of the file Previous contents are destroyed and file is created if it does not exist already
"a" Write from the end of the file Create file if it doesn’t exist
"a+" Read and write from the end of the file Create file if it doesn’t exist
"x" Create a file for writing from the beginning Return an error if file already exists
"x+" Create a file for reading and writing from the beginning Return an error if file already exists

We also have another interesting (and somewhat scary) appendage to the function call (line 59):

or die("Error: Could not open the log file.")

This is actually just a handy way of saying that if the function returns an error, terminate the script after displaying the message shown in the argument of the die( ) function.

Note the path to the feedback.txt file in line 58. Because the script that is writing to this file is in the scripts subdirectory, and the data subdirectory containing feedback.txt is at the same level as the scripts subdirectory, we have to move up one level from scripts and then go down into data to reach feedback.txt.

Because we have opened the file for writing, we can use the function fwrite( ) to write to the file. The function fwrite( ) also takes two parameters:

  • The first parameter is the file variable returned by the call to fopen( ). In our case, this is the variable $fileVar.

  • The second parameter is the string that you want to write to the file.

Now, of course, we want to write to the log file the message string stored in the variable $messageToClient. However, before writing the message itself we want to write a blank line followed by a line of dashes to signal the start of a new log entry and then the date of this entry, and only then the actual message. Thus we have three calls to fwrite( ) (lines 60–66), and, as before, we use the function die( ) to terminate the program with an error message if any one of the writing operations fails for any reason. A typical entry in this log file is shown in Figure 8.22, which also illustrates an alternate date/time format.

This completes our discussion of the server-side processing of our feedback form.

8.8 Revising the Implementation of Our BMI Calculator to Calculate Server-Side

In the previous discussion of our feedback form submission, all of our server-side processing was done by a PHP script contained in the single file feedbackFormProcess.php. In this and the following sections, you will learn how to write programmer-defined PHP functions that may be stored in a separate file and then included into your main “driver” script from that file. Breaking up even a relatively small script in this way makes it more modular and helps you deal with error tracking and updating if required. In other words, it makes “script maintenance” much easier.

So, let us revisit our BMI calculator developed over Chapters 5 to 7. The actual BMI calculation in those versions of the calculator was implemented using JavaScript. The calculator accepted the user’s height and weight and displayed the user’s BMI after a short JavaScript calculation. We gave the user the option of getting a detailed BMI report, and another option of receiving it by email. Since we were working entirely within the limitations of JavaScript, we displayed the BMI information with the help of a JavaScript popup window or a new web page created by JavaScript, and were forced to omit the sending of any emails.

In this chapter, we will retain our client-side data validation, which is best done on the client side to avoid unnecessary and potentially harmful data being transferred to the server. However, once we are certain the data is valid, we will transfer that data to the server and perform the BMI computations on the server side,1 with PHP functions that are stored in a file separate from our main script. Then we will send out an email if requested, as well as return a browser display of the BMI calculation result. We will also implement the email functionality this time by using HTML encoded messages, rather than just plain text.

Thus our remaining objectives of this exercise are:

  • To write programmer-defined PHP functions, store them in a file of their own, and include that file into a main “driver” script where they can then be used

  • To perform numerical calculations in PHP

  • To learn how to send HTML-encoded email messages

8.8.1 What Happens When the User Clicks Compute your BMI

A browser display of our BMI form is shown in FIGURE 8.23, where we have entered reasonable values for the form fields. Note that we have chosen one unit from the metric system (kilograms, for weight) and one non-metric unit (inches, for height), just to remind ourselves that it doesn’t matter.

As with our feedback form, when the user clicks the Compute your BMI button on the BMI calculator form, the first thing that happens is the validation of the form data. Only if all the input data is valid will the form data be uploaded to the server for processing. Otherwise the user will have to correct the invalid data and resubmit.

If all of the input data is valid, the data from the form is sent to the server. Then the following two actions are performed by our PHP script:

  • Either a simple report containing the user’s BMI value, or a more detailed report if the user has requested one, is constructed and displayed in the browser. To get the more detailed report, the user must check the box indicating that choice on the form. An example of the detailed version is shown in FIGURE 8.24. In this case, note that the user has also checked the box requesting an email report, as the last line of the display indicates.

  • If the user has requested it by checking the corresponding checkbox, an email message containing the chosen BMI report is now sent as well. An example of the email version of the detailed report being read by the roundcube email client is shown in FIGURE 8.25. Note that this email message is in HTML form, not just a plain text email. We will discuss the creation of such messages shortly. Note that if you try the form yourself from the book’s website, for example, and cannot find the email in your INBOX, you should check your SPAM box. Email messages that are coded using HTML are often subjected to stricter spam filtering scrutiny. The problem is further exacerbated by the fact that the sender address may not match the server that is sending the email message, which is yet another reason for the spam filter to be suspicious. This is one of the curses of the proliferation of email messages. You want to make sure that the email is as user-specific as possible, so that the spam filter does not suspect a mass emailing. Also, if you experiment with the BMI form many times, a spam filter may suspect that an automatic mailer is trying to bombard you with multiple copies of the mail and start blocking the message.

FIGURE 8.23 graphics/ch08/nature/displayBmiFormPhp.jpg

A Firefox browser display of ch08/nature/pages/bmiForm.php, with the form completely filled out with valid information and ready to be submitted.

FIGURE 8.24 graphics/ch08/nature/displayBmiFormProcessPhpBrowser.jpg

A Firefox browser display of the web page report received by the user as the result of the script in Figure 8.27 processing the form data shown in Figure 8.23 after it has been submitted.

In the following sections, we discuss in detail the script that makes the decisions described in the above list and performs the required actions. But first, for the sake of completeness, let’s review the uploading of our BMI form data.

8.8.2 Uploading the BMI Form Data from the Client to the Server

As was the case with our feedback form, we also developed our BMI form and its data validation over Chapters 5, 6, and 7, but only now do we get to finally submit the form and have it processed on the server. The current version of our form is found in the file ch08/nature/pages/bmiForm.php. Once again we do not reproduce that entire file here, but instead just show the revised opening form tag (from lines 16–17 of the file):

<form id="bmiForm" onsubmit="return bmiFormValidate( )" action="scripts/bmiFormProcess.php" method="post">

FIGURE 8.25 graphics/ch08/nature/displayBmiFormProcessPhpEmail.jpg

A roundcube web email client display showing the email received by the user (the business client) as a result of submitting the form data shown in Figure 8.23.

Unlike our feedback form, this form retains an onsubmit attribute since its data is still being validated by JavaScript. Note in particular the keyword return in front of the call to bmiFormValidate( ) in the value of the onsubmit attribute. The form will not be submitted if this return is not present, even if the function returns a value of true.

The value of the action attribute of the form element is now a call to the PHP script bmiFormProcess.php, which lives on the server (in ch08/nature/scripts), and which will process the data that is sent to the server from this form. And once again the method attribute of the form tag has the recommended value of "post" when we are sending information that is going to be stored on the server.

As you will see shortly, our complete PHP script on this occasion is actually split over two files—bmiFormProcess.php and bmiCalculate.php—but only our higher-level “driver” script in bmiFormProcess.php appears as the value of the action attribute, since the driver script itself takes care of the necessary access to the other script file.

8.8.3 An Overview of the “Driver” Script That Processes the BMI Form Data

Begin by looking at our PHP “driver” script in the file bmiFormProcss.php, which is shown in FIGURE 8.26. Note first of all that in line 14 of Figure 8.26 we perform a PHP server-side include that includes into this script the contents of the file bmiCalculate.php, which is shown in FIGURE 8.27, and which lives in the same directory as bmiFormProcss.php.

We have already seen how one PHP script can include another. In this case, we can view our use of this server-side include facility as helping us to practice information hiding, since we are, in effect, “hiding” some of our implementation details (some programmer-defined functions, in fact) in the included file.

FIGURE 8.26 ch08/nature/scripts/bmiFormProcess.php

The high-level “driver” PHP script, which processes form data such as that shown in Figure 8.23 after the form is submitted.

FIGURE 8.27 ch08/nature/scripts/bmiCalculate.php

The lower-level PHP functions that now perform, on the server side, the BMI calculations that were formerly performed on the client side

The “higher-level” functions detailedMessage( ), simpleMessage( ), and mailBMI( ) that are called by the “driver” script in bmiFormProcess.php are defined in the file bmiCalculate.php, along with some auxiliary “lower-level” functions used by these higher-level functions but not called directly from our driver script. We will discuss all of these functions in detail in subsequent sections, but before doing that we need to make some general remarks about programmer-defined functions in PHP.

The first thing to note is that the general format of a function definition in PHP is completely analogous to what we saw in JavaScript:

function nameOfFunction(parameter_list)
{
   ... PHP code to perform whatever the function does ...
}

The first line is the header of the function, and again it begins with the keyword function, which indicates the beginning of a function definition. This keyword is followed by the name of the function, which should (as always) be well chosen to indicate the purpose of the function. This, in turn, is followed by a comma-separated list of parameters the function should receive when it is called, enclosed in parentheses.

The parameters listed in the parentheses differ from their JavaScript equivalents in that each name has to be preceded by a $ sign. In this respect PHP parameters are just like PHP variables. The PHP code that actually performs the task of the function is, as usual, called the function body and is enclosed in the usual pair of braces {. . .} immediately following the function header.

The rest of the PHP script in bmiFormProcess.php is relatively simple. The variable $message is used to store the HTML markup that will be used for browser display as well as for emailing. If the user has requested a detailed report, the variable $_POST['details'] will be set, and we will assign the value returned by the call to the function detailedMessage( ) to the variable $message (lines 16–17). On the other hand, if the user did not check the checkbox named details, the value of the variable $_POST['details'] will not be set, and the variable $message will be assigned the value returned by the call to the function simpleMessage( ) (lines 19–20). In either case, the variable $message is then echoed to a dynamically generated web page similar to the one displayed in Figure 8.24.

The next decision to be made in our bmiFormProcess.php script is whether to send an email or not. This decision is based on whether the user has checked the checkbox named wantMail. If it is checked, then the corresponding variable $_POST['wantMail'] in our PHP script will be set, and we therefore call the function mailBMI( ) to build and send an HTML-encoded email report (line 24). The function takes two parameters:

  • $_POST['email'], which contains the value from the textbox named email in the form

  • $message, which contains the message we just generated by one or the other of the two message-generating function calls

In this case we also echo a message to the end of the dynamically created web page saying that the BMI report has also been sent via email (line 25).

This completes the overview discussion of our driver script. In the following sections we proceed with a top-down discussion of the programmer-defined functions called by this driver script, namely detailedMessage( ), simpleMessage( ), and mailBMI( ), as well as the lower-level programmer-defined functions that compute the BMI value.

8.8.4 Building the BMI Report Message with Programmer-Defined PHP Functions

We begin our study of the code from bmiCalculate.php by looking at the two functions simpleMessage( ) and detailedMessage( ), shown in lines 10–43 of Figure 8.27.

Consider the function detailedMessage( ) in lines 19–43 first. This function takes four parameters: $height, $heightUnit, $weight, and $weightUnit. In the body of the function, the very first statement (line 22) is a call to the built-in PHP function sprintf( ). We use it here to format the numerical value and return the result as a string. We should mention that this function is similar to the function by the same name in the programming language C, on the off chance you may have seen it there. Note that here we are making good use of the appropriate built-in PHP function for this particular task, while in JavaScript we wrote our own (for purposes of illustration, as you may recall).

The function can take a variable number of parameters. In our case, we have two:

  • The first parameter must be a string indicating a format specification for the number to be printed (the second parameter). We are using the string "%.lf", which means that the value given by the second parameter should be printed as a floating-point value (real number) with one place after the decimal. For a link to details on other formatting options, see the end-of-chapter References.

  • The second argument in our case is the actual value that will be printed. It will be the value returned by a call to another programmer-defined function called calculateBMI( ), which also takes four parameters, $height, $heightUnit, $weight, and $weightUnit, and returns the value of the BMI. We discuss this function in the following section.

The string returned by the call to the function sprintf( ) is stored in a variable called $bmi (line 22). The next statement in the function detailedMessage( ) (lines 24–29) builds the HTML-encoded message (i.e., a message containing HTML markup) using the four values that were passed to the function as well as the properly formatted value of the BMI given by the variable $bmi. The complete string thus formed is stored in a variable called $text. Note that in this case, in the interests of brevity and simplicity, we do not bother to create a valid HTML5 page for the display.

Next, based on the range within which the BMI value lies, a message about whether the BMI is low, high, or reasonable is appended via a compound conditional statement. This conditional is really a sequence of nested if-statements of the kind also available in JavaScript.

The final message in the variable $text is returned to the calling function.

The function simpleMessage( ) returns a simpler report, but does similar computations. It contains nothing that requires further discussion, but you should confirm this by reading through its code in any case.

Before we leave this part of the discussion, line 24 of Figure 8.27 deserves some additional comment. Note that the value of the src attribute is an absolute path to the logo image file. In fact, it is a complete URL to that file. As you know, in earlier chapters we have emphasized that relative paths are always to be preferred to absolute paths, but sometimes you just cannot use a relative path, and this is one of those times. Remember that we are preparing some text that may be sent as part of an email message to a user who could be anywhere, and a relative path in that user’s email will be meaningless to that user, so the user’s email program needs to know where (on the Internet) the image file is located. We could have used the full URL to the logo image file in ch08/nature/images, but to make the URL somewhat shorter we have made a new images directory in our home directory and placed a copy of the logo image file there.

8.8.5 Computing the BMI Value: Numerical Computations in PHP, and More Programmer-Defined Functions

In previous sections, we dealt primarily with the string manipulations needed to create dynamic web pages and send emails. In this section, we will look more closely at numerical computations in PHP, which we choose to perform with programmer-defined functions in the same way we did in JavaScript. In fact, what we do here is remarkably similar to what we already did in JavaScript.

As we have already observed, the numerical computations used by the functions simple-Message( ) and detailedMessage( ) are performed by the function calculateBMI( ) (lines 51–58 of Figure 8.27), which takes the four parameters, $height, $heightUnit, $weight, and $weightUnit, and returns the BMI value. Note that prior to calling this function, all input data entered by the user has been validated client-side, so we can assume that the fields height and weight are numbers lying within a reasonable range.

The BMI calculation can be done in various ways, but before doing any calculations we choose to convert all values to the metric system, if they are not metric already. Hence, if the user has entered the height in inches, it is converted to centimeters using the function inchesToCentimetres( ) (line 46) in the first conditional statement (line 53). Similarly, if the user has entered weight in pounds, it is converted to kilograms using the function poundsToKilograms( ) (line 47) in the second conditional statement (line 54). The function calculateBMI( ) then converts the centimeters to meters by dividing the height by 100 and the BMI is simply calculated (in a metric-unit calculation) as the ratio of the weight to the square of the height (lines 55–56).

The functions inchesToCentimetres( ) and poundsToKilograms( ) return the centimeter or kilogram equivalent of inches or pounds using appropriate factors.

In these functions you see the arithmetic operators for multiplication (*) and division (/) in action, and you will be relieved to learn that the usual operators for addition (+), subtraction (-), and modulus (%) are also available in PHP, all conforming to the usual precedence rules, again as in JavaScript.

8.8.6 Building and Sending an HTML-Encoded Email BMI Report to the User with Another Programmer-Defined Function

The email messages that we sent to the business (Figure 8.19) and the client (Figure 8.20) from our feedback form were simple text messages. However, the email message shown in Figure 8.25 is in HTML format. The built-in PHP function mail( ) can actually be used to send any type of mail that is normally sent through most email clients (including HTML email).

Our programmer-defined function mailBMI( ) to handle this is shown in lines 60–67 of Figure 8.27. This function has a little more work to do before it calls the built-in function mail( ) that sends the HTML version of the BMI report, so it needs the following two parameters:

  • The email address of the recipient (obtained directly from the submitted form in $_POST['email'], as shown in the call to this function in line 24 of Figure 8.26)

  • Our HTML-encoded BMI report

To get the second parameter in the proper form so that the message is sent as HTML rather than plain text by mail( ), we need to make that message conform to the requirements of the SMTP for such messages.

Here this means that we have to provide an appropriate header, which we do in lines 63–64 of Figure 8.27, which will have the effect of notifying the recipient’s email client that this is an HTML email. The rest of the header is the same as before, and again contains the "From: " address (line 65).

Finally, our programmer-defined function mailBMI( ) then calls the built-in PHP function mail( ) to send the message. You should note that some recipients may not receive the message as HTML, either because their email program cannot handle it or because they have this feature turned off in that program. This is less of a problem nowadays but still one to consider.

This completes our discussion of the programmer-defined functions called either directly or indirectly from our driver script bmiFormProcess.php.

8.9 PHP Development and Testing

As with any programming language, writing PHP code will not always go smoothly. You will occasionally discover, sadly, that your code does not do what you wanted it to do. Or, even worse, it may cause your page to “crash” and not display properly or not display at all.

PHP does not as yet have a built-in debugger, so if there are semantic errors that simply cause your script to behave improperly you may find the old-fashioned debugging method of inserting output statements to display variable values at various execution points very helpful.

On the other hand, when you are beginning to program in PHP you may find that your problems tend to be syntax-related issues, and here PHP can be quite helpful by displaying an appropriate error message. For example, suppose that in line 12 of Figure 8.1 you change the name of the date( ) function to datf( ). Then, instead of the complete page, including the welcome message and date shown in Figure 8.2, you will likely see only a partially displayed page, and then an error message something like the following:

Fatal error: Call to undefined function datf( ) in
welcome.php on line 12

This happens because you asked the PHP processor to call a function that it does not recognize, and the result is that the page rendering stops at that point. This can be frustrating, but you should regard it as a good thing, since you would not want your pages showing up on your users’ screens with incorrect and potentially embarrassing information on them. It’s much better to catch such problems at the development stage, and when PHP is set up to show us such errors we should take advantage of the assistance it provides. See the end-of-chapter References section for more on PHP error levels and error reporting.

Another “quick and dirty” (though quite useful) technique is the use of the “or die( )” construct as illustrated in lines 58–66 of Figure 8.18. This can be useful if something is going wrong with your server-side activity, such as your attempt to open, read from, or write to, a file, or to access a database. These sorts of errors are the kind we will encounter and have to deal with when we start using PHP to communicate with our database in Chapter 10.

If your PHP script fails for any reason, it will (by default, if configured to do so) send to the browser a message containing the name of the file in which the offending script is located, the line number where the error occurred, and a message that (one hopes) describes the problem, as mentioned above. This is excellent default behavior to leave in place, but if you wish to do so there are ways to adjust the “level” of error reporting that PHP provides, and there may be some errors you wish to ignore from time to time. The error_reporting( ) function allows you to set the error level for a particular script, and even turn it off completely should you really wish to live dangerously and do so. Follow the link given in the References for further information on this function.

For the sake of brevity, we did not revalidate on the server any of the data sent from our forms on the client side. However, you can never be too careful, and server-side validation as well as client-side validation of user-entered data is something you should consider implementing in a production website.

Summary

Note that in this summary we state some comparisons with JavaScript that assume you are familiar with that language up to the level of the coverage in the earlier chapters of this text.

PHP, invented by Rasmus Lerdorf in the mid-1990s, is one of the most widely used non-proprietary server-side technologies in use on the web today. It is an interpreted programming language designed specifically for preprocessing data on the server side and sending the results of that preprocessing back to a browser on the client side as HTML markup. As a programming language, it is another in the C-based category of languages, though it inherits much of its syntax more directly from Perl and has much in common with JavaScript as well.

One or more PHP scripts may be embedded within HTML markup, as long as each one is enclosed in <?php...?> delimiters, in which case the script is executed on the server and its output is returned to the browser, along with whatever normal HTML was in the document, to be rendered for viewing by the user. Thus the user cannot see the PHP script code by choosing the “view source” option in the browser. Additional scripts or portions of a script may also be contained in one or more separate files and included into another script located within an HTML page.

All of the standard decision making and looping control constructs from JavaScript are available in PHP. PHP also has the usual arithmetic operators and the two scalar numerical types integer and double. The two other scalar types in PHP are string and boolean, and there are two compound types, array and object. We have not used object. Like JavaScript, PHP is dynamically typed, which means that a variable has the type of the value most recently assigned to it, and if a variable has no value at all its type is the special type null. The null type has only a single value, which is also NULL (or null, since keywords are case-insensitive).

Text output from a PHP script is usually accomplished with the echo-statement. A here document is a very convenient way of outputting a large amount of text. PHP strings can use single or double quotes, but you must remember that variables within double quotes are replaced by their values, a process called variable interpolation.

PHP also has functions, both built-in and programmer-defined, which are similar to those found in JavaScript and which can and should be used to modularize your code for enhanced readability. Variables declared in a function are local to that function. Some useful PHP built-in functions, listed alphabetically rather than in the order we encountered them, include count( ), date( ), die( ), error_reporting( ), exit( ), fopen( ), fwrite( ), include( ), mail( ), rand( ), replace( ), and sprintf( ).

We again used the JavaScript function, setInterval( )to execute another JavaScript function periodically. In this case it was in the context of the AJAX technology, which we put to good use to refresh the time and date on the pages of our Nature’s Source website.

The PHP script that will process the form data submitted from the browser on the client side must be supplied as the value of the action attribute of the HTML form element. The POST method is the recommended method for submitting form data. The GET method, in which the passed data appears at the end of the processing script’s URL, can also be used for small amounts of data if security is not an issue, especially if you don’t want the bother of setting up a form to collect the data.

On the server side, data passed to a script should be accessed via the superglobals $_POST or $_GET (depending on which method was used to pass the data). These are associative arrays in which we access the values by keys, which may be strings. We must be careful how we use quotes when working with these arrays.

We introduced the idea of a PHP session, and used one to keep track of the date and time refreshes on our website. This required using another superglobal, namely $_SESSION.

It is a good idea to validate form data on the client side before submitting it to the server for processing. When doing this with a boolean validation function as the value of the onsubmit attribute of the form element, you must remember to include the keyword return in front of the function name. Without it, the data will not be uploaded even if the function returns true. Though we did not do it, it is also a good idea to validate, or revalidate, form data on the server side.

You also saw how to create and send an email message that appears as an HTML page in the user’s email client.

Some differences in PHP, as compared with JavaScript, include the following:

  1. PHP has an additional kind of single-line comment introduced by the # character (i.e., in addition to the // and /*...*/ comments found in JavaScript that are also available in PHP).

  2. All PHP variables, including array names, begin with the dollar sign character ($).

  3. PHP has case-sensitive variable names, but reserved words and function names that are case-insensitive.

  4. The string concatenation operator is the period (.), not the plus operator (+).

  5. PHP arrays are unlike arrays in JavaScript or any other language. Among the differences is the fact that you can arrange to access elements of the same array with either a numerical or string index.

  6. The contents of an external JavaScript file are not enclosed in a <script>... </script> tag pair, but the contents of an external PHP file are enclosed in <?php...?> delimiters.

Quick Questions to Test Your Basic Knowledge

  1. Who was the original developer of PHP?

  2. What did the acronym PHP stand for in the beginning, and what do most people think it stands for now?

  3. What is the major difference between how JavaScript is used and how PHP is used in web programming? Hint: Perhaps we should ask what the major difference is in where they are used.

  4. What are the opening and closing delimiters for a PHP script?

  5. We have seen that there is more than one way to make CSS styles available to our HTML documents and more than one way to make JavaScript scripts available to our HTML documents. How many ways can you think of to make a PHP script available to your HTML documents, what are they, which is preferred, and why?

  6. What is the difference between the case-sensitivity of PHP and that of JavaScript?

  7. What is the major difference between variable names in PHP and variable names in JavaScript?

  8. What is the difference between the way two strings are combined (concatenated) in JavaScript and in PHP?

  9. How does the .= operator work?

  10. We could have used JavaScript to display the date and time on our pages so that the pages would look the same as they do using our PHP scripts. Why would this not be a good idea?

  11. Why did we “feel the need” to employ AJAX with PHP on our web pages?

  12. What is the name of the type of object that we need to create in order to make an AJAX request?

  13. What is a PHP session?

  14. What is a PHP superglobal?

  15. What is the name of the superglobal we use when working with a PHP session?

  16. What are the names of the two “methods” used to transfer data from a form in the browser to a server-side PHP script that will process the data?

  17. What is the name of the superglobal we would use to access the data that had been passed to a PHP script by appending it to the end of the script’s URL?

  18. What was the purpose of inserting the two-character combination into some of the text output of our PHP scripts?

  19. What happens, or at least what should happen, in a testing environment when your PHP script contains a syntax error?

  20. In what context might we use the PHP die( ) function?

  21. For what purpose did we use the JavaScript setInterval( ) function this time?

  22. How, and for what reason, did we use a “hidden” HTML element?

  23. What are the possible values that might be returned by the PHP function call rand(15, 20)?

  24. When we have a reference to an HTML DOM object, and want the content of the corresponding HTML element, what property of that object do we use?

Short Exercises to Improve Your Basic Understanding

  1. Revise ch08/welcome.php so that the script contains just a single echo statement.

  2. Confirm our claim that a misspelling of the date( ) function (in ch08/welcome.php, for example) will generate a PHP error similar to the one described. If this does not happen, your PHP installation may not be set up to display such errors, and you may want to speak to your administrator, or take steps yourself to make this happen.

  3. This exercise is best done on a desktop PC where you have more “real estate”. Open three different browser windows, and enter one of the three URLs—of welcome.php, welcome_refresh.php, and welcome_ajax.php—in each of the three windows, without actually loading any of the three pages just yet. When you have done this, load all three pages as quickly as you can and start counting. After about a minute, the first page will still be black, the second page should be entirely in some new color, and the third page should have just the two lines with the date and time in some new color. Wait a couple more minutes at least, and make sure you understand what you are seeing.

  4. In both our “full-page” refresh example and our “time-and-date-only” refresh example using AJAX, we used a counter in the $_SESSION array to keep track of the number of refreshes. However, we were really only interested in whether the page had been refreshed or not. Rewrite either or both of these examples to use a boolean array value rather than the counter array value that we did use.

  5. In test_get.php as shown in Figure 8.14, insert single quotes from around value1 and value2 in line 10 and try the example again to see if that makes any difference. Then undo that change and next remove the single quotes from around value1 and value2 in line 12 to see if that makes any difference when you run the example one more time.

  6. We went to some extra effort to make the browser display page confirming a feedback form submission a valid HTML5 page, but we did not do this for the browser display page reporting the BMI calculation. Revise the bmiCalculate.php script shown in Figure 8.27 so that the resulting page shown in Figure 8.24 is a valid HTML5 page.

  7. Trace through all the decision paths in the filling out both the feedback form and the BMI form.

  8. Confirm that you need the return in return bmiFormValidate( )in line 16 of the file ch08/nature/pages/bmiForm.php.

  9. Check to see what, if anything, happens when you remove the <?php...?> delimiters from the included file ch08/nature/scripts/bmiCalculate.php.

  10. Remove line 14 containing the include( ) function call in bmiFormProcess.php from its current location and put it in a new one-line PHP script in the head of the file. Test the revised script to see if it works as before. If not, explain why not; if so, explain why we might want to do this.

Exercises on the Parallel Project

  1. Modify the pages of your developing business website to include a welcome message with the date and time at your business location that is dynamically produced on the server for display in the user’s browser. This feature is analogous to what is seen in this chapter’s version of our Nature’s Source website, and your version should use both PHP and AJAX in the same way that we did.

  2. Implement server-side PHP processing for your own feedback form that is analogous to what we described in this chapter. That is, when the user fills out and submits your feedback form, the following things should happen:

    • Your business receives an email version of the feedback.

    • The user receives an email confirmation of the feedback.

    • The user gets an immediate browser display confirming the feedback submission.

    • A dated copy of the feedback is stored on the server.

    Use a textfile called feedback.txt in a subdirectory called data to log your feedback messages. Also, since your business may not yet actually be up and running and have a bona fide email address, the “business email address” can be your own email address. In fact, for testing purposes, you can be both customer and business, but the messages received should be at least slightly different in each case so that they may be distinguished from one another. This too is what we did in the text.

  3. If there is time, implement in a similar manner the server-side PHP processing for your previously developed order form that provides the same four features described above for your feedback form. In this case, the output should include a summary of the input data, as well as the results of any calculations involving that input data. Each part of the output should be presented in a reasonable format appropriate for that part of the output (email, web page, or file on disk).

What Else You May Want or Need to Know

  1. We have used the PHP script delimiters <?php ... ?> to separate PHP code from non-PHP code. We recommend consistent use of these delimiters, though you can also expect to see the short-form delimiters <? ... ?> used as well. However, these are less portable since their use can be disabled in the PHP configuration.

  2. The use of # as a single-line comment delimiter, the use of the $ to start a variable name, and the here document are all features that are inherited directly from the Perl programming language, of which PHP may be regarded as a direct descendant.

  3. When you are trying to understand how a PHP script works, be careful to distinguish between PHP’s read mode and its execution mode. Only PHP code that is enclosed between proper PHP code delimiters will cause the PHP processor to be invoked to process that code. This is execution mode. Anything else is simply read and forwarded on to the browser (this is read mode).

  4. We have used the include( ) function to include external files into our HTML files or into PHP scripts. An alternative is the require( ) function. The main difference is that if there is a problem, require( ) will report an error and terminate the script, while include( ) will report a warning and let the script continue. Thus include( ) takes a more “relaxed” approach and is perhaps more useful from a development standpoint.

  5. Before version 4.1 of PHP, it was common (and perhaps still is) to make use of the fact that a value of a name attribute of a form element from a form on the client side will show up as a variable name (beginning with a $, of course) in your PHP script on the server side, and the value of that variable will be the data submitted by the user via that element. For example, if we were making use of this facility, instead of accessing$_POST['firstName'] we would simply access $firstName.

    This may seem to be very convenient, in fact more convenient than using a superglobal, but it also turns out to be less secure. For that reason, in order to make use of this feature, the register_globals directive must be turned on in the PHP configuration file, and starting with PHP 4.2, register_globals has been turned off by default. Moreover, by the time you read this, if PHP 6 or a later version is available, and you are using it, you may find that this feature has simply gone away entirely.

  6. Recall that JavaScript is not permitted to read from and write to files, for obvious security reasons, since it is downloaded from the web and runs in the user’s web browser. PHP, on the other hand, runs on the server and, therefore, is not subject to the same restrictions. We used PHP for very simple file output, appending each new feedback item to a file of text, but other file operations are possible, as indicated by various I/O modes shown in Table 8.2.

  7. Just as there are many JavaScript frameworks freely available for download, as we mentioned in previous chapters, there are also numerous PHP frameworks available for download as well, such as CakePHP and Zend. On the other hand, one cannot obtain PHP code from sites on the web in the same way one can find JavaScript code, because PHP code has “disappeared” from a web page by the time that page has reached the browser. Nevertheless, there are also many PHP scripts that you might find useful and which are freely available for download from various web repositories. See the References for some relevant links.

References

  • 1. We refer you again to the authors’ version of our Nature’s Source website, since you cannot get the full effect of this chapter’s version of the website simply by loading the home page from a copy of the website on your PC, unless it is being “served” by a web server on that PC. This is because the PHP these pages contain will not be activated unless the pages are served from a PHP-aware web browser. This is analogous to the situation back in Chapter 3 when we first started using SSI. If you have the necessary setup of your own, or if your instructor has set one up and installed our files, fine. If not, you can go to our website and load the index file for the Chapter 8 version of our Nature’s Source website from this location:

    http://cs.smu.ca/webbook2e/ch08/nature
    
  • 2. The ultimate source of PHP information, including the latest downloads and up-to-date information on language and library developments is, of course, the “home” of PHP, which you can find here:

    http://www.php.net
    

    For example, a comprehensive listing of PHP functions can be found at this location:

    http://www.php.net/manual/en/language.functions.php
    
  • Information on some of the particular functions we have used can be found at these locations:

    http://ca.php.net/manual/en/function.date.php
    
    http://ca.php.net/manual/en/function.include.php
    
    http://ca.php.net/manual/en/function.sprintf.php
    
    http://ca.php.net/manual/en/function.mail.php
    
  • And, from the form of these few links, if there is another PHP built-in function about which you need information, you can probably guess where to go for that information. Also, information on the here document (or heredoc) and the use of quotes when working with arrays can be found here:

    http://php.net/manual/en/language.types.string.php
    
    http://php.net/manual/en/language.types.array.php
    
  • 3. As they usually do for important web technologies, the W3Schools folks provide a PHP tutorial with lots of useful examples and a PHP reference at their site:

    http://www.w3schools.com
    
  • 4. Another PHP tutorial site, similar in approach to that of W3Schools but perhaps with some additional detail, can be found here:

    http://www.tizag.com/phpT/
    
  • 5. Here is a page containing a table showing a number of different PHP frameworks and their features:

    http://www.phpframeworks.com/
    
  • 6. Here are a couple of links to sites containing free PHP scripts that you might find useful:

    http://gscripts.net/
    
    http://www.hotscripts.com/
    

    A Google search will turn up many other similar sites.

  • 7. Our Table 8.1 gives just a very brief summary of PHP history. Like many other web technologies, its history can reasonably be described as “tortured”. You may find it interesting to check out further details on Wikipedia at this link:

    https://en.wikipedia.org/wiki/PHP#History
    
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.156.35