On the CD This section contains PHP and ASP implementations of a use of files for keeping scores, and a PHP implementation for uploading files such as image files illustrating products. The projects demonstrated here involve the use of files. The CD-ROM contains the code for the projects in the folder named chapter12code.
The demonstration of reading and writing to files will use a text file with records consisting of a name and a number in character format. The two fields will be separated by commas. An example of such a file is the following:
Jeanine,98 Aviva,101 Daniel,110 Mike,140 Ted,134 Judy,200 Mike,300 Mike,300 Willie,200 Willie,200 JM,132
This file could be the scores for a game. There is no attempt to order the scores (see the Exercises section). The script displays the entire contents of the file using a table for formatting. The script displays a form in which your user can type in a player name and a score and submit this information to the file. The term handle is taken from the slang used in game playing. Figure 12.1 shows the screen displayed with the existing scores plus the form to enter a name and score.
Figure 12.1: Display of scores plus form.
Because the code in these examples is not lengthy, and also to give you examples of both approaches, the examples in this chapter return to the technique of using one script to be both the presenter of a form and the script that handles the form.
The file resides in the same folder as the script. If you have chosen to place your PHP scripts in one folder and your ASP scripts in another, you will need to make an adjustment, either in your practice or in your coding to get the correct string containing the file address.
The outline for the PHP and the ASP files is the same:
HTML starting tags
Variables set to generate the file address
displayfile function
handleform function
displayform function
Main body: if test checking if form has been submitted
If submitted, call handleform. Check return code and display appropriate message
Else (not submitted): displayfile. Check return code and display appropriate message. Call displayform.
HTML closing tags
In both cases, you will see that the scripts go into and out of PHP or ASP independently of the bracketing defined by the function definitions and the if and else clauses. You might find this lack of proper nesting disconcerting, but this is standard practice for middleware programming.
In this operation, the script does the bulk of the work in the functions. The displayfile function and the handleform function each open and close the file. You might ask, “why not open the file, do all the processing, and then close it?” The reason to avoid this approach is that it is best to open and close the file as quickly as possible. This would allow more users to access the file.
What is done outside and prior to the function definitions or function calling code is generating the file address. The built-in variable $PATH_TRANSLATED furnishes the address of this script. The code uses regular expressions to remove the filename to produce what is named $stub, signifying that it is the stub of the address. The next statement concatenates the name of the file. The resulting $filen variable is declared as global in each of the functions so code inside the function can access the variable already defined. The code is shown in Table 12.3.
<html><head><title>File reading & writing</title></head><body> | HTML tags |
<?php | Start PHP |
$abspath = $PATH_TRANSLATED; | Define $abspath using a built-in PHP variable giving the path to this script |
$stub=ereg_replace("\\filetest.php","\\",$abspath); | Use the regular expression to take off the name of this script |
$filen = $stub . "scores.txt"; | Add the filename scores.text to the stub produced in the prior line |
function displayfile() { | displayfile function header |
global $filen; | Specify that $filen is to be the global variable |
$open = @fopen($filen,"r"); | Attempt to open the file for reading. The @ will prevent an error triggered by a missing file |
if ($open) { | If test to check if a file was opened |
?> | Leave PHP temporarily |
<table> | HTML table tag |
<tr><td>Player </td><td> Score </td></tr> | HTML for first line of table |
<? | Get back into PHP |
$filecontents = file($filen); | Read the entire file into $filecontents |
for ($n=0;$n<count($filecontents); $n++) { | For loop: it will iterate for as many elements as there are in $filecontents |
$record = explode(",", $filecontents[$n]); | Based on comma as the delimiter, define $record to be the array based on the parts of the $nth element in $filecontents |
print ("<tr><td>".$record[0]. "</td>"); | Output the first part (it will be the name) as an item in the table |
print ("<td>".$record[1]. "</td></tr>\n"); | Output the second part (it will be the score) as an item in the table. Output a line break for the HTML |
| Close the for loop |
print("</table>"); | Output the closing table tag |
fclose($open); | Close the file |
$ok = TRUE; | Set $ok to be true to be the return value |
} | Close if a file was opened |
else {$ok = FALSE;} | The else clause: a file was not opened: set $ok to false |
return $ok; | Return $ok |
} | Ends the definition of the function displayfile |
function handleform(){ | handleform file function header |
global $player; | Specify that $player is to be the global variable. It is a value sent from the form. |
global $filen; | Specify $filen as the global variable. It was set at the start of this script |
global $score; | Specify that $score is to be the global variable. It is a value sent from the form |
$open=@fopen($filen,"a"); | Open the file for appending to the end |
if ($open) { | If test: was a file opened |
fwrite($open,"$player,$score\n"); | Write out a string holding the two values from the form, separated by a comma and ending in a line break character |
fclose($open); | Close the file |
$ok=TRUE; | Set the variable to be used as a return value to true |
} | Ends if the file open was okay |
else {$ok=FALSE; } | The else clause: the file open was not okay |
return $ok; | Return the return code variable |
} | Ends the function definition |
function displayform() { | displayform function header |
?> | Leave PHP temporarily |
<form action="filetest.php" method=get> | HTML form tag |
Player handle <input type=text | name='player'>Specify tag for player’s name |
<br> Score <input type=text name='score'><br> | Specify tag for score |
<input type=hidden name='submitted' value = 'TRUE'> | Set up a hidden tag to use to check if form has been submitted |
<input type=submit name='submit' value='submit entry'> | Tag for the Submit button |
</form> | HTML form close |
<? | Restart PHP |
} | Ends definition of displayform function |
if (@$submitted) { | This is the body of the script. The if test to see if the form has been submitted or needs to be displayed |
if (handleform()) { | Positive clause: this is a call to the handleform function. An if tests checks its return value |
print("entry made"); | Positive: output that an entry was made |
} | Close positive clause |
else {print ("entry not made"); | Negative (on return of handleform): output that an entry was not made |
} | Close negative clause |
} | Close the clause on the form being submitted |
else { | Else: need to display the existing data in the file and then display the form |
if (!displayfile()){ | Call displayfile. If it is the case that it returned a false value— |
print ("NO PLAYER SCORES<br>");} | Output no player scores, meaning no file found |
displayform(); | Call to displayform |
} | Close else clause for test of if submitted |
?> | Close PHP |
</body></html> | Closing HTML tags |
The ASP script shown here uses the ReadLine method. This method is called to prepare the output for each row of the HTML table. The overall structure of the script including the function definitions is similar to the PHP script. As was the case with the PHP script, there is code at the start to define the address (filepath) to the scores.txt file. In this case, the built-in variable to obtain the path to the script is one of the ServerVariables collection of the Request object.
The ASP system uses two objects for file handling: a file system object and a file stream object. The OpenTextFile method of the file system object can be used with one, two, three, or four parameters:
fso.OpenTextFile(filepath, mode, create_option, format_option);
In the code that follows, the method is used two times. The first time there is just the first parameter, indicating that the mode is the default, which is 1 for read. The second time, the first two parameters are specified. The mode is set to 8, indicating the append mode for adding lines at the end of the file. The value of the mode for writing a file, meaning erasing anything already there, is 2. The create_option specifies what is to be done if the file does not exist. A value of false, the default, means to do nothing. A value of true means to create the file. A format_option of 1 means Unicode. This might become more important in the future. A format_option of 2 means to use the system default. The default format is 0 for ASCII. The code is shown in Table 12.4.
<html><head><title>File reading & writing </title></head><body> | HTML tags |
<%@ Language=JavaScript %> | Set JavaScript as language |
<% | Start ASP |
var abspath=String(Request. ServerVariables("PATH_TRANSLATED")); | Define a string to be the address of this script |
var filepath=abspath.replace(/\\\w*\.asp/,"\\") + "scores.txt"; | Using the replace method for any string, create the filepath for the scores.txt file |
function displayfile() { | The header for displayfile function |
fso=new ActiveXObject("Scripting. FileSystemObject"); | Define fso to be a file system object |
if (!fso.FileExists(filepath)) { | Check if the file exists and |
return(false); } | if it does not, return false |
Else { | Start the other clause: the file does exist |
file_stream=fso.OpenTextFile(filepath); | Set file_stream to be a file_stream object connecting to the desired file |
%> | End ASP temporarily |
<table> | HTML table tag |
<tr><td>Player </td><td> Score </td></tr> | HTML for first row of table |
<% | Restart ASP |
ok = false; | Set ok to false. If things go well, this will be set to true |
while (!file_stream.AtEndOfStream) { | While loop: this will iterate until the end of the file is reached |
ok = true; | Set ok to true |
record = file_stream.ReadLine(); | Read in one line of the file. The variable record is a string |
recorda = record.split(","); | Make recorda an array holding the two parts of the line from the file |
Response.Write("<tr><td>" + recorda[0]+ "</td>"); | Output what is the player name as a table item |
Response.Write("<td>"+recorda[1] + "</td></tr>\n"); | Output what is the score as a table item |
} | End the while loop |
Response.Write("</table>"); | Output the table close |
file_stream.close(); | Close the file |
return ok; | Return ok as the return code |
} | End the ELSE (there was a file) |
} | End the definition of displayfile |
function handleform(){ | The handleform function header |
ok = true; | Set ok to true |
var player = String(Request ("player")); | Extract the player form data |
var score = String(Request ("score")); | Extract the score form data |
fso=new ActiveXObject("Scripting.FileSystemObject"); | Define fso to be a file system object |
file_stream=fso.OpenTextFile(filepath, 8); // 8 for append | Define file_stream to be a file stream object connecting to the file address held in filepath. The 8 indicates append |
file_stream.Write(player + "," + score + "\n"); | Write out the data as a string with a comma separating the two items and a line break at the end |
return ok; | Return ok |
} | End the definition of handleform |
function displayform() { | The displayform function |
%> | End ASP temporarily |
<form action="filetest.asp" method=get> | HTML form tag |
Player handle <input type=text name='player'> | Player input tag |
<br> Score <input type=text name='score'><br> | Score input tag |
<input type=hidden name='submitted' value = 'TRUE'> | Set up submitted as hidden form input |
<input type=submit name='submit' value='submit entry'> | Set up Submit button |
</form> | HTML form end |
<% | Restart ASP |
} | End definition of displayform function |
var submitted = String(Request("submitted")); | Main body of file: extract the submitted form input |
if (submitted!="undefined") { | Check if form submitted |
if (handleform()) { | If form was submitted, call handleform. Do an if test on the return value |
Response.Write("entry made"); | Positive case (true return by handleform): output entry made |
} | End positive case |
else {Response.Write ("entry not made"); | Negative case: output that entry was not made |
} | End negative case |
} | End form being submitted |
else { | Else clause: form wasn’t submitted |
if (!displayfile()){ | Call displayfile. If the return value was false— |
Response.Write ("NO PLAYER SCORES<br>");} | Output that there was no player scores |
displayform(); | Call displayform function |
} | Close the else clause on submitted |
%> | End ASP |
</body></html> | HTML closing tags |
The uploading of an entire file based on user information is considered more threatening to system integrity than accepting individual pieces of information and storing them in files or databases. However, situations exist in which you might want to provide this function. For example, the shopping cart application described later in this text provides a way for users (store employees) to add a product to the online catalog. Product information includes a picture of the product, and the picture is held in an image file.
The script is a stand-alone file for uploading any file. The person at the client computer indicates the file using a form as shown in Figure 12.2.
Figure 12.2: Form for specifying file to upload.
The organization of the script is:
HTML tags
If form submitted (indicated by definition of $file)
Print out messages
Generate address for file within same folder as script
Copy file over from a temporary location to this folder
Print out messages depending on success of copy operation
In any case, display form.
The form will get displayed again after the upload. This is different from the other situations in which an if/else construction either handled the form input or displayed the form.
The filename used on the system is obtained from the file specified by the user. One way of adding some security to this procedure would be for the script to create the filename. This would prevent a malicious user from uploading a substitute for a file used by the system for another purpose.
The file begins with the usual HTML opening tags and then starts PHP:
<html> <head><title>File upload test </title> </head> <body> <?php
The $file in the next line refers to form input. This HTML form is shown a little later. If the value is defined, indicating that the file has been submitted using the form, then the true clause for the if is executed.
if (@$file) {
The presence of a form input tag of type “file” creates the $file_name and the $file_size variables with the name of the file as on the client computer and the size of the file. The code in this script outputs this information. In some applications, you might choose not to bother the user with this information.
print ("uploading file named $file_name <br>"); print ("File size is $file_size <br>");
The next lines of code are similar to that shown for the reading and writing to an existing file. The code is determining a place for the file to be placed.
$abspath = $PATH_TRANSLATED; $stub=ereg_replace("\\fileupload.php","\\",$abspath); $fullname = $stub . $file_name; print ("fullname is: $fullname.<br>");
The next step is to copy the file to its designated home. At this point in the execution of the script, the file is in a temporary area and will not be accessible unless it is copied. The call to the copy function is done within an if test.
if (copy($file,$fullname)) { print ("file successfully uploaded. <br>"); } else { print ("file could not be copied."); }
The unlink operation removes the connection to the temporary file.
unlink($file);
The bracket ends the clause for the true condition on the existence of $file; that is, the handling of the form data.
}
The next part of the script displays the HTML form. The user is given the chance to specify a file to be uploaded to the server, starting with a message:
print ("<br>upload a file to the server<br>\n");
The form can be expressed using plain HTML so PHP coding is ended.
?>
The form tag has what probably is a new attribute to you: the ENCTYPE. This is required when the form data is something in addition to plain text as input in textboxes, radio boxes, and so on.
<form action='fileupload.php’ method=POST ENCTYPE="multipart/form-data">
The file type of input form does what you would suppose it to do: provide a way for a user to specify a file. The next input tag sets up the Submit button, and the rest of the HTML is the usual closing up of form, body, and html.
File <input type=file name="file"><br> <input type=submit name="submit" value="upload file"> </form> </body> </html>
As you can see in Figure 12.3, a Browse button comes “for free” along with the ENCTYPE attribute and the input type=file tag. Click on it and you will see the usual Windows browsing windows. For example, here is a screen capture after clicking on the Browse button. A file named dragon.jpg was selected. The next step is to click on the Open button shown in Figure 12.3.
Figure 12.3: Window to browse and specify file for uploading.
Figure 12.4 shows the resulting message.
Figure 12.4: Screen showing message plus form for new upload.
You can see the messages produced by the file handling part of the script followed by the display of the form.