Beginning PHP 5.3 phần 5 pot

85 324 0
Beginning PHP 5.3 phần 5 pot

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

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

Thông tin tài liệu

Chapter 11: Working with Files and Directories 303 file_put_contents() — Writes a whole string to a file without needing to open it fpassthru() — Displays the contents of an open file readfile() — Displays the contents of a file without needing to open it fseek() — Moves the file pointer to a specific location within an open file ftell() — Returns the position of the file pointer rewind() — Moves the file pointer to the start of the file As you can see, PHP gives you many different ways to read and write to files, so you can always find a function to suit your needs! Reading and Writing Strings of Characters The fread() function can be used to read a string of characters from a file. It takes two arguments: a file handle and the number of characters to read. The function reads the specified number of characters (or less if the end of the file is reached) and returns them as a string. For example: $handle = fopen( “data.txt”, “r” ); $data = fread( $handle, 10 ); This code reads the first ten characters from data.txt and assigns them to $data as a string. When working with binary files a character is always one byte long, so ten characters equals ten bytes. However, this doesn ’ t apply when working with Unicode files, where each character may take up several bytes. In this case, reading ten characters may in fact result in reading, say, twenty bytes from the file. After fread() has finished, the file pointer, which holds the current position in the file, moves forward in the file by the number of characters read. So after the previous example code runs, the file pointer moves forward to ten characters after the start of the file. If you repeat the same call to fread() , you ’ ll get the next ten characters in the file. If there are less than ten characters left to read in the file, fread() simply reads and returns as many as there are. By the way, if you want to read only one character at a time you can use the fgetc() function. fgetc() takes a single argument — a file handle — and returns just one character from the file it points to; it returns false when it reaches the end of the file: $one_char = fgetc( $handle ); However, fgetc() is slow when working with large files. It ’ s faster to read a bunch of characters at once using fread() , or one of the other file - reading functions mentioned in this chapter. You can use the fwrite() function to write data to a file. It requires two arguments: a file handle and a string to write to the file. The function writes the contents of the string to the file, returning the number of characters written (or false if there ’ s an error). For example: $handle = fopen( “data.txt”, “w” ); fwrite( $handle, “ABCxyz” ); ❑ ❑ ❑ ❑ ❑ ❑ c11.indd 303c11.indd 303 9/21/09 9:10:12 AM9/21/09 9:10:12 AM 304 Part III: Using PHP in Practice The first line opens the file data.txt for writing, which erases any existing data in the file. (If the file doesn ’ t exist, PHP attempts to create it.) The second line writes the character string “ ABCxyz ” to the beginning of the file. As with fread() , the file pointer moves to the position after the written string; if you repeat the second line, fwrite() appends the same six characters again, so that the file contains the characters “ ABCxyzABCxyz ” . You can limit the number of characters written by specifying an integer as a third argument. The function stops writing after that many characters (or when it reaches the end of the string, whichever occurs first). For example, the following code writes the first four characters of “ abcdefghij ” (that is, “ abcd “ ) to the file: fwrite( $handle, “abcdefghij”, 4 ); Try It Out A Simple Hit Counter One very popular use for Web scripts is a hit counter, which is used to show how many times a Web page has been visited and therefore how popular the Web site is. Hit counters come in different forms, the simplest of which is a text counter. Here’s a simple script for such a counter: <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”> <html xmlns=”http://www.w3.org/1999/xhtml” xml:lang=”en” lang=”en”> <head> <title>Hit counter</title> <link rel=”stylesheet” type=”text/css” href=”common.css” /> </head> <body> <h1>A simple hit counter</h1> <?php $counterFile = “./count.dat”; if ( !file_exists( $counterFile ) ) { if ( !( $handle = fopen( $counterFile, “w” ) ) ) { die( “Cannot create the counter file.” ); } else { fwrite( $handle, 0 ); fclose( $handle ); } } if ( !( $handle = fopen( $counterFile, “r” ) ) ) { die( “Cannot read the counter file.” ); } $counter = (int) fread( $handle, 20 ); fclose( $handle ); $counter++; c11.indd 304c11.indd 304 9/21/09 9:10:12 AM9/21/09 9:10:12 AM Chapter 11: Working with Files and Directories 305 echo “<p>You’re visitor No. $counter.</p>”; if ( !( $handle = fopen( $counterFile, “w” ) ) ){ die( “Cannot open the counter file for writing.” ); } fwrite( $handle, $counter ); fclose( $handle ); ?> </body> </html> Save this script as hit_counter.php and give it a try. Figure 11-1 shows a sample run. Figure 11-1 To start with, you’ll see “You’re visitor No. 1.” If you now reload the page, you’ll see the counter change to 2. Each time you reload, the counter increments by 1. How It Works After displaying a page header, the script stores the filename of the file that will hold the hit count: $counterFile = “./count.dat“; Next, the script checks to see if the counter file exists. If it doesn’t, it is created by opening the file for writing, writing a zero to it (thereby initializing the hit count to zero), then closing it: if ( !file_exists( $counterFile ) ) { if ( !( $handle = fopen( $counterFile, “w” ) ) ) { die( “Cannot create the counter file.” ); } else { fwrite( $handle, 0 ); fclose( $handle ); } } c11.indd 305c11.indd 305 9/21/09 9:10:13 AM9/21/09 9:10:13 AM 306 Part III: Using PHP in Practice Next the counter file is opened for reading: if ( !( $handle = fopen( $counterFile, “r” ) ) ) { die( “Cannot read the counter file.” ); } The script now uses the file handle to read the hit counter value from the open file. As you can see, the script calls fread() to read up to 20 bytes from the data file (enough to store a very large integer): $counter = (int) fread( $handle, 20 ); Because fread() returns a string value, and the counter needs to be an integer value, the return value is cast into an integer using (int). (See Chapter 3 for more on type casting.) The call to fclose() closes the file referenced by the file handle $handle, freeing up the file for reading or writing by other processes: fclose( $handle ); After closing the data file, the script increments the counter and tells the visitor how many times the page has been accessed: $counter++; echo “<p>You’re visitor No. $counter.</p>”; Next the script writes the new counter value back to the data file. To do this it opens the file in write mode ( w), then calls fwrite() to write the $counter variable’s value to the file, followed by fclose() to close the open file again: if ( !( $handle = fopen( $counterFile, “w” ) ) ){ die( “Cannot open the counter file for writing.” ); } fwrite( $handle, $counter ); fclose( $handle ); Testing for the End of a File The feof() function serves a single, simple purpose: it returns true when the file pointer has reached the end of the file (or if an error occurs) and returns false otherwise. It takes just one argument — the file handle to test. Notice that feof() only returns true once the script has tried to read one or more characters past the last character in the file: // hello_world.txt contains the characters “Hello, world!” $handle = fopen( “hello_world.txt”, “r” ); $hello = fread( $handle, 13 ); echo $hello . “ < br / > ”; // Displays “Hello, world!” echo feof( $handle ) . “ < br / > ”; // Displays “” (false) $five_more_chars = fread( $handle, 5 ); c11.indd 306c11.indd 306 9/21/09 9:10:13 AM9/21/09 9:10:13 AM Chapter 11: Working with Files and Directories 307 echo $five_more_chars . “ < br / > ”; // Displays “” (or possibly a newline) echo feof( $handle ) . “ < br / > ”; // Displays “1” (true) fclose( $handle ); feof() is useful with fread() or fgetc() in a while loop when you don ’ t know how long the file is: // hello_world.txt contains the characters “Hello, world!” $handle = fopen( “hello_world.txt”, “r” ); $text = “”; while ( !feof( $handle ) ) { $text .= fread( $handle, 3 ); // Read 3 chars at a time } echo $text . “ < br / > ”; // Displays “Hello, world!” fclose( $handle ); Reading One Line at a Time Often it ’ s useful to read text from a file one line at a time. A line is a nice manageable chunk of text to process or display. For example, data files and configuration files often contain one chunk of information per line, such as a data record or a configuration setting. To read a line of text from an open file, call the fgets() function, passing in the file handle. The function reads from the current file pointer to the end of the current line, and returns the read characters as a string (or false if there was a problem, such as the end of the file being reached). Note that any end - of - line character (or characters) at the end of the line is also included in the string. You can limit the number of characters read by passing in a second, integer argument, in which case fgets() stops when it reaches that number of characters minus one (unless the end of the line is reached first). It ’ s a good idea to include this argument when reading large files that might not contain line breaks. The following example uses fgets() to read and display a three - line text file, one line at a time. The while loop exits when fgets() returns false (which means it ’ s reached the end of the file): /* milton.txt contains: The mind is its own place, and in it self Can make a Heav’n of Hell, a Hell of Heav’n. What matter where, if I be still the same, */ $handle = fopen( “milton.txt”, “r” ); $lineNumber = 1; while ( $line = fgets( $handle ) ) { echo $lineNumber++ . “: $line < br / > ”; } fclose( $handle ); c11.indd 307c11.indd 307 9/21/09 9:10:14 AM9/21/09 9:10:14 AM 308 Part III: Using PHP in Practice The code produces the following output: 1: The mind is its own place, and in it self 2: Can make a Heav’n of Hell, a Hell of Heav’n. 3: What matter where, if I be still the same, Reading CSV Files If you ’ ve ever done any work with importing and exporting data, you probably know about the comma - separated - value (CSV) data format. (CSV even has its own file extension: .csv .) In CSV files, each data record sits on its own line, and the fields within each record are separated by commas. String values are often enclosed within double quotes: “John”,”Smith”,45 “Anna”,”Clark”,37 “Bill”,”Murphy”,32 To read CSV files, you can use fgetcsv() . This function reads a line of CSV - formatted data from an open file starting from the position of the file pointer, and puts the data it finds into an array, with one field value per array element. Once you have an array of data you can easily manipulate it. To call the fgetcsv() function, pass it the file handle of an open file. You can also optionally specify: The maximum number of characters to read. You can leave this value out, or use 0, in which case PHP reads as many characters as necessary to read the whole line. However, specifying a value makes the function slightly quicker The delimiter that is used to separate each data value. The default is the comma ( , ). If you ’ re reading a tab - separated - value (TSV) file, specify “ \t ” (the tab character) for this argument instead The character that is used to enclose string values. The default is the double quote ( “ ) The character used to escape special characters. The default is the backslash ( \ ) fgetcsv() returns false if there was a problem reading the line, or if the end of the file has been reached. The following code snippet shows how you might retrieve three lines of data from a file in CSV format: /* people.csv contains: “John”,”Smith”,45 “Anna”,”Clark”,37 “Bill”,”Murphy”,32 */ $handle = fopen( “people.csv”, “r” ); while ( $record = fgetcsv( $handle, 1000 ) ) { echo “Name: {$record[0]} {$record[1]}, Age: {$record[2]} < br / > ”; } fclose( $handle ); ❑ ❑ ❑ ❑ c11.indd 308c11.indd 308 9/21/09 9:10:14 AM9/21/09 9:10:14 AM Chapter 11: Working with Files and Directories 309 This code displays: Name: John Smith, Age: 45 Name: Anna Clark, Age: 37 Name: Bill Murphy, Age: 32 PHP 5.3 introduces a new function, str_getcsv(), that reads CSV data from a string instead of from a file. This is handy if you already have your CSV data in memory. For details see http://www.php .net/manual/en/function.str-getcsv.php. Reading and Writing Entire Files Writing code to read a file line by line, or string by string, can be tedious. Fortunately, PHP provides you with some functions that can access the complete contents of a file in one go. These include: file() — For reading a whole file into an array, without needing to open it file_get_contents() and file_put_contents() — For reading and writing the contents of a file without needing to open it fpassthru() — For displaying the contents of an open file readfile() — For displaying the contents of a file without needing to open it Because these functions read the entire file into memory in one go, they should really be used for relatively small files (a few MB at most). If you ’ re working with a 100MB text file, it ’ s probably best to use fread() or fgets() to read and process the file in chunks. file() reads the contents of a file into an array, with each element containing a line from the file. It takes just one argument — a string containing the name of the file to read — and returns the array containing the lines of the file: $lines = file( “/home/chris/myfile.txt” ); The newline character remains attached at the end of each line stored in the array. This function, like most of the others described in this section, doesn ’ t require you to specify a file handle. All you need to do is pass in the filename of the file to read. The function automatically opens, reads, and, once it ’ s done, closes the file. You can optionally specify some useful flags as the second parameter to file() : Flag Description FILE_USE_INCLUDE_PATH Look for the file in the include path (see Chapter 20 for more on include paths) FILE_IGNORE_NEW_LINES Remove newline characters from the end of each line in the array FILE_SKIP_EMPTY_LINES Ignore empty lines in the file ❑ ❑ ❑ ❑ c11.indd 309c11.indd 309 9/21/09 9:10:14 AM9/21/09 9:10:14 AM 310 Part III: Using PHP in Practice As with other flags in PHP you can combine any of these flags with the bitwise OR operator (see Chapter 3 for details). For example, the following code looks for a file in the include path and, when found, reads the file, ignoring any empty lines in the file: $lines = file( “myfile.txt”, FILE_USE_INCLUDE_PATH | FILE_SKIP_EMPTY_LINES ); As with fopen() , you can also use file() to fetch files on a remote host: $lines = file( “http://www.example.com/index.html” ); foreach ( $lines as $line ) echo $line . “ < br / > ”; A related function is file_get_contents() . This does a similar job to file() , but it returns the file contents as a single string, rather than an array of lines. The end - of - line characters are included in the string: $fileContents = file_get_contents( “myfile.txt” ); If there was a problem reading the file, file_get_contents() returns false . You can pass the FILE_USE_INCLUDE_PATH flag (described earlier) as the second argument to file_get_contents(). You can also optionally pass in an offset and/or a length parameter to determine where you want the file reading to start, and how many characters you want to read. For example, the following code reads 23 characters from myfile.txt , starting at character 17: $fileContents = file_get_contents( “myfile.txt”, null, null, 17, 23 ); The first null argument avoids setting the FILE_USE_INCLUDE_PATH flag, and the second null argument avoids setting a context. Contexts are out of the scope of this book, but you can find out more about them in the online manual at http://www.php.net/manual/en/stream.contexts.php . file_put_contents() is the complement to file_get_contents() . As you ’ d imagine, it takes a string and writes it to a file: $numChars = file_put_contents( “myfile.txt”, $myString ); The function returns the number of characters written, or false if there was a problem. You can affect the behavior of the function by passing various flags as the third argument. file_put_contents() supports the same flags as file_get_contents() , as well as two additional flags: Flag Description FILE_APPEND If the file already exists, append the string to the end of the file, rather than overwriting the file. LOCK_EX Lock the file before writing to it. This ensures that other processes can ’ t write to the file at the same time. c11.indd 310c11.indd 310 9/21/09 9:10:15 AM9/21/09 9:10:15 AM Chapter 11: Working with Files and Directories 311 You can also lock files that are opened using fopen() . To do this, use flock() . See http://www .php.net/manual/en/function.flock.php for more details. fpassthru() and readfile() both take a file and output its unmodified contents straight to the Web browser. fpassthru() requires the handle of an open file to work with: $numChars = fpassthru( $handle ); readfile() instead works on an unopened file: $numChars = readfile( “myfile.txt” ); As you can see, both functions return the number of characters read (or false if there was a problem). fpassthru() reads from the current file pointer position, so if you ’ ve already read some of the file only the remaining portion of the file will be sent. You can make readfile() search the include path for the file by passing true as the second argument. Incidentally, readfile() is handy for sending binary files — such as images and PDF documents — to the Web browser for displaying or downloading. You see an example of this in Chapter 16. Random Access to File Data Using the functions you ’ ve met so far, you can only manipulate data sequentially, that is, in the same order that it is arranged in the file. However, sometimes you need to skip around the contents of an open file. For example, you might want to read a file once to search for a particular string, then return to the start of the file in order to search for another string. Of course, this is easy if you ’ ve read the entire file using, for example, file_get_contents() . However, this isn ’ t practical for large files. Fortunately, it ’ s possible to move the file pointer around within an open file, so that you can start reading or writing at any point in the file. PHP gives you three functions that let you work with the file pointer: fseek() — Repositions the file pointer to a specified point in the file rewind() — Moves the file pointer to the start of the file ftell() — Returns the current position of the file pointer ❑ ❑ ❑ c11.indd 311c11.indd 311 9/21/09 9:10:15 AM9/21/09 9:10:15 AM 312 Part III: Using PHP in Practice To use fseek() , pass the handle of the open file, and an integer offset. The file pointer moves to the specified number of characters from the start of the file (use zero to move the pointer to the first character). For example, the following code moves the pointer to the eighth character in the file (that is, seven characters after the first character) and displays the next five characters from that point: // hello_world.txt contains the characters “Hello, world!” $handle = fopen( “hello_world.txt”, “r” ); fseek( $handle, 7 ); echo fread( $handle, 5 ); // Displays “world” fclose( $handle ); To specify how the offset is calculated, you can add a third optional argument containing one of the following constants: SEEK_SET — Sets the pointer to the beginning of the file plus the specified offset (the default setting) SEEK_CUR — Sets the pointer to the current position plus the specified offset SEEK_END — Sets the pointer to the end of the file plus the specified offset (use with a negative offset) fseek() returns 0 if the pointer was successfully positioned, or - 1 if there was a problem. You can ’ t use this function with files on remote hosts opened via HTTP or FTP (for example, fopen( “ http://www.example.com/ ” )). If you want to move the pointer back to the start of the file (a common occurrence), a handy shortcut is the rewind() function. The following two lines of code both do the same thing: fseek( $handle, 0 ); rewind( $handle ); The ftell() function takes a file handle and returns the current offset (in characters) of the corresponding file pointer from the start of the file. For example: $offset = ftell( $handle ); As you saw earlier, the fpassthru() function outputs file data from the current file position onward. If you have already read data from an open file but want to output the file ’ s entire contents, call rewind() first. Working with File Permissions File system permissions determine what different users can do with each file and directory in the file system. For example, whereas one user might have permission to read and write to a file, another user may only be allowed to read the file. A third user might not even be allowed to do that. ❑ ❑ ❑ c11.indd 312c11.indd 312 9/21/09 9:10:16 AM9/21/09 9:10:16 AM [...]... Permissions generally won’t affect you much when writing PHP scripts, because PHP usually does the right thing behind the scenes For example, if you create a new file for writing, PHP automatically gives that file read and write permission for the user that’s running your PHP script (usually the Web server user) If you create a new directory, PHP gives the directory read, write, and execute permission... “.txt” ) { echo ‘’ $filename ‘’; echo ‘’ filesize( $filepath ) ‘’; 3 25 Part III: Using PHP in Practice echo ‘’ date( “M j, Y H:i:s”, filemtime( $filepath ) ) ‘’; } } $dir->close(); ?> or create a new file: ... $filepath ) ) die( “File not found” ); displayPageHeader(); ?> Editing < ?php echo $filename ?> ” /> < ?php echo htmlspecialchars( file_get_contents( $filepath ) ) ?>... many of the functions and concepts covered in the chapter Some functions rarely used in Web applications weren’t discussed For a full list of PHP s file and directory functions, refer to the online PHP function list at: http://www .php. net/manual/ref filesystem .php 334 Chapter 11: Working with Files and Directories In the next chapter you are introduced to another popular way of storing application data:... handling in PHP You can find the solution to this exercise in Appendix A Exercise Create a PHP application that can be used to find a particular directory by name when given a top-level directory to search Make the application look through the given directory, as well as all directories under the given directory 3 35 12 Introducing Databases and SQL In the last chapter you learned how your PHP scripts... 318 Chapter 11: Working with Files and Directories chdir() returns true if PHP managed to change to the specified directory, or false if there was an error (such as the directory not being found) The current directory is the directory where PHP first looks for files If you specify a path that isn’t an absolute or relative path, PHP looks for the file inside the current directory So the following code... rel=”stylesheet” type=”text/css” href=”common.css” /> Listing the contents of a directory < ?php $dirPath = “/home/matt/images”; $dir = dir( $dirPath ); ?> 320 Chapter 11: Working with Files and Directories < ?php echo $dirPath ?> contains the following files and folders: < ?php while ( $file = $dir->read() ) { if ( $file != “.” && $file != “ ” ) echo “$file”; } $dir->close();... create and delete files within that directory In this section you explore PHP s chmod() function, which lets you change the mode (permissions) of a file or directory You also take a look at three PHP functions that let you determine if a file or directory is readable, writable, or executable by the current user Changing Permissions PHP s chmod() function is used to change the mode, or permissions, of a... execute the file, but only the owner can write to it: chmod( “myfile.txt”, 0 755 ); // Only the owner can access the file, and they can only read and write to it: chmod( “myfile.txt”, 0600 ); Note that you can only change the permissions of a file or directory if you own it, or if you’re the super-user (which is highly unlikely for PHP scripts running on a Web server) So how do modes work with directories?... and outputting the result 331 Part III: Using PHP in Practice Notice that the filename and fileContents field values are passed through PHP s htmlspecialchars() function to encode characters such as &, in the markup This is a good security measure to take: < ?php echo htmlspecialchars( file_get_contents( . { fwrite( $handle, 0 ); fclose( $handle ); } } c11.indd 30 5c11.indd 3 05 9/21/09 9:10: 13 AM9/21/09 9:10: 13 AM 30 6 Part III: Using PHP in Practice Next the counter file is opened for reading: if. c11.indd 31 3c11.indd 31 3 9/21/09 9:10:16 AM9/21/09 9:10:16 AM 31 4 Part III: Using PHP in Practice Digit Value Permission 3 Can write to and execute the file 4 Can only read the file 5 Can. file_exists() ) to avoid such errors. c11.indd 31 5c11.indd 3 15 9/21/09 9:10:16 AM9/21/09 9:10:16 AM 31 6 Part III: Using PHP in Practice Working with Directories PHP lets you work with directories in

Ngày đăng: 09/08/2014, 14:21

Từ khóa liên quan

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

Tài liệu liên quan