Phát triển web với PHP và MySQL - p 9 ppt

10 293 0
Phát triển web với PHP và MySQL - p 9 ppt

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

Thông tin tài liệu

If the filename you use begins with ftp://, a passive mode FTP connection will be opened to the server you specify and a pointer to the start of the file will be returned. If the filename you use begins with http://, an HTTP connection will be opened to the server you specify and a pointer to the response will be returned. When using HTTP mode, you must specify trailing slashes on directory names, as shown in the following: http://www.server.com/ not http://www.server.com When you specify the latter form of address (without the slash), a Web server will normally use an HTTP redirect to send you to the first address (with the slash). Try it in your browser. The fopen() function does not support HTTP redirects, so you must specify URLs that refer to directories with a trailing slash. Remember that the domain names in your URL are not case sensitive, but the path and file- name might be. Problems Opening Files A common error you might make while trying to open a file is trying to open a file you don’t have permission to read or write to. PHP will give you a warning similar to the one shown in Figure 2.2. Storing and Retrieving Data C HAPTER 2 2 STORING AND RETRIEVING DATA 55 FIGURE 2.2 PHP will specifically warn you when a file can’t be opened. 04 7842 CH02 3/6/01 3:37 PM Page 55 If you get this error, you need to make sure that the user that the script runs as has permission to access the file you are trying to use. Depending on how your server is set up, the script might be running as the Web server user or as the owner of the directory that the script is in. On most systems, the script will run as the Web server user. If your script was on a UNIX sys- tem in the ~/public_html/chapter2/ directory, you would create a world writeable directory in which to store the order by typing the following: mkdir ~/orders chmod 777 ~/orders Bear in mind that directories and files that anybody can write to are dangerous. You should not have directories that are accessible directly from the Web as writable. For this reason, our orders directory is two subdirectories back, above the public_html directory. We will talk more about security later in Chapter 13, “E-commerce Security Issues.” Incorrect permission settings is probably the most common thing that can go wrong when opening a file, but it’s not the only thing. If the file can’t be opened, you really need to know this so that you don’t try to read data from or write data to it. If the call to fopen() fails, the function will return false. You can deal with the error in a more user-friendly way by suppressing PHP’s error message and giving your own: @ $fp = fopen(“$DOCUMENT_ROOT/ /orders/orders.txt”, “a”, 1); if (!$fp) { echo “<p><strong> Your order could not be processed at this time. “ .”Please try again later.</strong></p></body></html>”; exit; } The @ symbol in front of the call to fopen() tells PHP to suppress any errors resulting from the function call. Usually it’s a good idea to know when things go wrong, but in this case we’re going to deal with that elsewhere. Note that the @ symbol needs to be at the very start of the line. You can read more about error reporting in Chapter 23, “Debugging.” The if statement tests the variable $fp to see if a valid file pointer was returned from the fopen call; if not, it prints an error message and ends script execution. Because the page will finish here, notice that we have closed the HTML tags to give valid HTML. The output when using this approach is shown in Figure 2.3. Using PHP P ART I 56 04 7842 CH02 3/6/01 3:37 PM Page 56 FIGURE 2.3 Using your own error messages instead of PHP’s can be more user friendly. Writing to a File Writing to a file in PHP is relatively simple. You can use either of the functions fwrite() (file write) or fputs() (file put string); fputs() is an alias to fwrite(). We call fwrite() in the following: fwrite($fp, $outputstring); This tells PHP to write the string stored in $outputstring to the file pointed to by $fp. We’ll discuss fwrite() in more detail before we talk about the contents of $outputstring. Parameters for fwrite() The function fwrite() actually takes three parameters but the third one is optional. The proto- type for fwrite() is int fputs(int fp, string str, int [length]); The third parameter, length, is the maximum number of bytes to write. If this parameter is supplied, fwrite() will write string to the file pointed to by fp until it reaches the end of string or has written length bytes, whichever comes first. Storing and Retrieving Data C HAPTER 2 2 STORING AND RETRIEVING DATA 57 04 7842 CH02 3/6/01 3:37 PM Page 57 File Formats When you are creating a data file like the one in our example, the format in which you store the data is completely up to you. (However, if you are planning to use the data file in another application, you may have to follow that application’s rules.) Let’s construct a string that represents one record in our data file. We can do this as follows: $outputstring = $date.”\t”.$tireqty.” tires \t”.$oilqty.” oil\t” .$sparkqty.” spark plugs\t\$”.$total .”\t”. $address.”\n”; In our simple example, we are storing each order record on a separate line in the file. We choose to write one record per line because this gives us a simple record separator in the newline charac- ter. Because newlines are invisible, we represent them with the control sequence “\n”. We will write the data fields in the same order every time and separate fields with a tab charac- ter. Again, because a tab character is invisible, it is represented by the control sequence “\t”. You may choose any sensible delimiter that is easy to read back. The separator, or delimiter, character should either be something that will certainly not occur in the input, or we should process the input to remove or escape out any instances of the delimiter. We will look at processing the input in Chapter 4, “String Manipulation and Regular Expressions.” For now, we will assume that nobody will place a tab into our order form. It is dif- ficult, but not impossible, for a user to put a tab or newline into a single line HTML input field. Using a special field separator will allow us to split the data back into separate variables more easily when we read the data back. We’ll cover this in Chapter 3, “Using Arrays,” and Chapter 4. For the time being, we’ll treat each order as a single string. After processing a few orders, the contents of the file will look something like the example shown in Listing 2.1. LISTING 2.1 orders.txt—Example of What the Orders File Might Contain 15:42, 20th April 4 tires 1 oil 6 spark plugs $434.00 22 Short St, Smalltown 15:43, 20th April 1 tires 0 oil 0 spark plugs $100.00 33 Main Rd, Newtown 15:43, 20th April 0 tires 1 oil 4 spark plugs $26.00 127 Acacia St, Springfield Closing a File When you’ve finished using a file, you need to close it. You should do this with the fclose() function as follows: fclose($fp); Using PHP P ART I 58 04 7842 CH02 3/6/01 3:37 PM Page 58 This function will return true if the file was successfully closed or false if it wasn’t. This is generally much less likely to go wrong than opening a file in the first place, so in this case we’ve chosen not to test it. Reading from a File Right now, Bob’s customers can leave their orders via the Web, but if Bob’s staff wants to look at the orders, they’ll have to open the files themselves. Let’s create a Web interface to let Bob’s staff read the files easily. The code for this interface is shown in Listing 2.2. LISTING 2.2 vieworders.php—Staff Interface to the Orders File <html> <head> <title>Bob’s Auto Parts - Customer Orders</title> </head> <body> <h1>Bob’s Auto Parts</h1> <h2>Customer Orders</h2> <? @ $fp = fopen(“$DOCUMENT_ROOT/ /orders/orders.txt”, “r”); if (!$fp) { echo “<p><strong>No orders pending.” .”Please try again later.</strong></p></body></html>”; exit; } while (!feof($fp)) { $order= fgets($fp, 100); echo $order.”<br>”; } fclose($fp); ?> </body> </html> This script follows the sequence we talked about earlier: Open the file, read from the file, close the file. The output from this script using the data file from Listing 2.1 is shown in Figure 2.4. Storing and Retrieving Data C HAPTER 2 2 STORING AND RETRIEVING DATA 59 04 7842 CH02 3/6/01 3:37 PM Page 59 FIGURE 2.4 The vieworders.php script displays all the orders currently in the orders.txt file in the browser window. Let’s look at the functions in this script in detail. Opening a File for Reading: fopen() Again, we open the file using fopen(). In this case we are opening the file for reading only, so we use the file mode “r”: $fp = fopen(“$DOCUMENT_ROOT/ /orders/orders.txt”, “r”); Knowing When to Stop: feof() In this example, we use a while loop to read from the file until the end of the file is reached. The while loop tests for the end of the file using the feof() function: while (!feof($fp)) The feof() function takes a file pointer as its single parameter. It will return true if the file pointer is at the end of the file. Although the name might seem strange, it is easy to remember if you know that feof stands for File End Of File. In this case (and generally when reading from a file), we read from the file until EOF is reached. Reading a Line at a Time: fgets(), fgetss(), and fgetcsv() In our example, we use the fgets() function to read from the file: $order= fgets($fp, 100); This function is used to read one line at a time from a file. In this case, it will read until it encounters a newline character (\n), encounters an EOF, or has read 99 bytes from the file. The maximum length read is the length specified minus one byte. Using PHP P ART I 60 04 7842 CH02 3/6/01 3:37 PM Page 60 There are many different functions that can be used to read from files. The fgets() function is useful when dealing with files that contain plain text that we want to deal with in chunks. An interesting variation on fgets() is fgetss(), which has the following prototype: string fgetss(int fp, int length, string [allowable_tags]); This is very similar to fgets() except that it will strip out any PHP and HTML tags found in the string. If you want to leave any particular tags in, you can include them in the allowable_tags string. You would use fgetss() for safety when reading a file written by somebody else or containing user input. Allowing unrestricted HTML code in the file could mess up your carefully planned formatting. Allowing unrestricted PHP could give a malicious user almost free rein on your server. The function fgetcsv() is another variation on fgets(). It has the following prototype: array fgetcsv(int fp, int length, string [delimiter]); It is used for breaking up lines of files when you have used a delimiting character, such as the tab character as we suggested earlier or a comma as commonly used by spreadsheets and other applications. If we want to reconstruct the variables from the order separately rather than as a line of text, fgetcsv() allows us to do this simply. You call it in much the same way as you would call fgets(), but you pass it the delimiter you used to separate fields. For example $order = fgetcsv($fp, 100, “\t”); would retrieve a line from the file and break it up wherever a tab (\t) was encountered. The results are returned in an array ($order in this code example). We will cover arrays in more detail in Chapter 3. The length parameter should be greater than the length in characters of the longest line in the file you are trying to read. Reading the Whole File: readfile(), fpassthru(), file() Instead of reading from a file a line at a time, we can read the whole file in one go. There are three different ways we can do this. The first uses readfile(). We can replace the entire script we wrote previously with one line: readfile(“$DOCUMENT_ROOT/ /orders/orders.txt”); A call to the readfile() function opens the file, echoes the content to standard output (the browser), and then closes the file. The prototype for readfile() is int readfile(string filename, int [use_include_path]); Storing and Retrieving Data C HAPTER 2 2 STORING AND RETRIEVING DATA 61 04 7842 CH02 3/6/01 3:37 PM Page 61 The optional second parameter specifies whether PHP should look for the file in the include_path and operates the same way as in fopen(). The function returns the total number of bytes read from the file. Secondly, you can use fpassthru(). You need to open the file using fopen() first. You can then pass the file pointer as argument to fpassthru(), which will dump the contents of the file from the pointer’s position onward to standard output. It closes the file when it is finished. You can replace the previous script with fpassthru() as follows: $fp = fopen(“$DOCUMENT_ROOT/ /orders/orders.txt”, “r”); fpassthru($fp); The function fpassthru() returns true if the read is successful and false otherwise. The third option for reading the whole file is using the file() function. This function is identi- cal to readfile() except that instead of echoing the file to standard output, it turns it into an array. We will cover this in more detail when we look at arrays in Chapter 3. Just for reference, you would call it using $filearray = file($fp); This will read the entire file into the array called $filearray. Each line of the file is stored in a separate element of the array. Reading a Character: fgetc() Another option for file processing is to read a single character at a time from a file. You can do this using the fgetc() function. It takes a file pointer as its only parameter and returns the next character in the file. We can replace the while loop in our original script with one that uses fgetc(): while (!feof($fp)) { $char = fgetc($fp); if (!feof($fp)) echo ($char==”\n” ? “<br>”: $char); } This code reads a single character from the file at a time using fgetc() and stores it in $char, until the end of the file is reached. We then do a little processing to replace the text end-of-line characters, \n, with HTML line breaks, <br>. This is just to clean up the formatting. Because browsers don’t render a newline in HTML as a newline without this code, the whole file would be printed on a single line. (Try it and see.) We use the ternary operator to do this neatly. A minor side effect of using fgetc() instead of fgets() is that it will return the EOF character whereas fgets() will not. We need to test feof() again after we’ve read the character because we don’t want to echo the EOF to the browser. Using PHP P ART I 62 04 7842 CH02 3/6/01 3:37 PM Page 62 It is not generally sensible to read a file character-by-character unless for some reason we want to process it character-by-character. Reading an Arbitrary Length: fread() The final way we can read from a file is using the fread() function to read an arbitrary num- ber of bytes from the file. This function has the following prototype: string fread(int fp, int length); The way it works is to read up to length bytes or to the end of file, whichever comes first. Other Useful File Functions There are a number of other file functions we can use that are useful from time-to-time. Checking Whether a File Is There: file_exists() If you want to check if a file exists without actually opening it, you can use file_exists(),as follows: if (file_exists(“$DOCUMENT_ROOT/ /orders/orders.txt”)) echo “There are orders waiting to be processed.”; else echo “There are currently no orders.”; Knowing How Big a File Is: filesize() You can check the size of a file with the filesize() function. It returns the size of a file in bytes: echo filesize(“$DOCUMENT_ROOT/ /orders/orders.txt”); It can be used in conjunction with fread() to read a whole file (or some fraction of the file) at a time. We can replace our entire original script with $fp = fopen(“$DOCUMENT_ROOT/ /orders/orders.txt”, “r”); echo fread( $fp, filesize(“$DOCUMENT_ROOT/ /orders/orders.txt” )); fclose( $fp ); Deleting a File: unlink() If you want to delete the order file after the orders have been processed, you can do it using unlink(). (There is no function called delete.) For example unlink(“$DOCUMENT_ROOT/ /orders/orders.txt”); This function returns false if the file could not be deleted. This will typically occur if the per- missions on the file are insufficient or if the file does not exist. Storing and Retrieving Data C HAPTER 2 2 STORING AND RETRIEVING DATA 63 04 7842 CH02 3/6/01 3:37 PM Page 63 Navigating Inside a File: rewind(), fseek(), and ftell() You can manipulate and discover the position of the file pointer inside a file using rewind(), fseek(), and ftell(). The rewind() function resets the file pointer to the beginning of the file. The ftell() function reports how far into the file the pointer is in bytes. For example, we can add the following lines to the bottom of our original script (before the fclose() command): echo “Final position of the file pointer is “.(ftell($fp)); echo “<br>”; rewind($fp); echo “After rewind, the position is “.(ftell($fp)); echo “<br>”; The output in the browser will be similar to that shown in Figure 2.5. Using PHP P ART I 64 FIGURE 2.5 After reading the orders, the file pointer points to the end of the file, an offset of 234 bytes. The call to rewind sets it back to position 0, the start of the file. The function fseek() can be used to set the file pointer to some point within the file. Its proto- type is int fseek(int fp, int offset); A call to fseek() sets the file pointer fp at a point offset bytes into the file. The rewind() function is equivalent to calling the fseek() function with an offset of zero. For example, you can use fseek() to find the middle record in a file or to perform a binary search. Often if you reach the level of complexity in a data file where you need to do these kinds of things, your life will be much easier if you used a database. 04 7842 CH02 3/6/01 3:37 PM Page 64 . browser. Using PHP P ART I 62 04 7842 CH02 3/6/01 3:37 PM Page 62 It is not generally sensible to read a file character-by-character unless for some reason we want to process it character-by-character. Reading. one is optional. The proto- type for fwrite() is int fputs(int fp, string str, int [length]); The third parameter, length, is the maximum number of bytes to write. If this parameter is supplied,. 2.4. Storing and Retrieving Data C HAPTER 2 2 STORING AND RETRIEVING DATA 59 04 7842 CH02 3/6/01 3:37 PM Page 59 FIGURE 2.4 The vieworders .php script displays all the orders currently in the

Ngày đăng: 06/07/2014, 19:20

Tài liệu cùng người dùng

Tài liệu liên quan