Previous Section  < Day Day Up >  Next Section

10.3 Reading and Writing Parts of Files

The file_get_contents( ) and file_put_contents( ) functions are fine when you want to work with an entire file at once. But when it's time for precision work, use other functions to deal with a file a line at a time. Example 10-6 reads a file in which each line contains a name and an email address and then prints an HTML-formatted list of that information.

Example 10-6. Reading a file a line at a time
$fh = fopen('people.txt','rb');

for ($line = fgets($fh); ! feof($fh); $line = fgets($fh)) {

    $line = trim($line);

    $info = explode('|', $line);

    print '<li><a href="mailto:' . $info[0] . '">' . $info[1] ."</li>\n";

}

fclose($fh);

If people.txt contains what's listed in Example 10-7, then Example 10-6 prints:

<li><a href="mailto:alice@example.com">Alice Liddell</li>

<li><a href="mailto:bandersnatch@example.org">Bandersnatch Gardner</li>

<li><a href="mailto:charles@milk.example.com">Charlie Tenniel</li>

<li><a href="mailto:dodgson@turtle.example.com">Lewis Humbert</li>

Example 10-7. people.txt for Example 10-6
alice@example.com|Alice Liddell

bandersnatch@example.org|Bandersnatch Gardner

charles@milk.example.com|Charlie Tenniel

dodgson@turtle.example.com|Lewis Humbert

The four file access functions in Example 10-6 are fopen( ), fgets( ) , feof( ), and fclose( ). The fopen( ) function opens a connection to the file and returns a variable that's used for subsequent access to the file in the program. (This is very similar to the database connection variable returned by DB::connect( ) that you saw in Chapter 7.) The fgets( ) function reads a line from the file and returns it as a string. The PHP interpreter keeps a bookmark of where its current position in the file is. The bookmark starts at the beginning of the file, so the first time that fgets( ) is called, the first line of the file is read. After that line is read, the bookmark is updated to the beginning of the next line. The feof( ) function returns true if the bookmark is past the end of the file. ("eof" stands for "end of file.") Last, the fclose( ) function closes the connection to the file.

The for( ) loop in Example 10-6 may look a little funny, but its structure ensures that fgets( ) and feof( ) play nice together. When the for( ) loop starts, the initialization expression runs. This reads the first line from the file and stores it in $line. Then the test expression runs: ! feof($fh). This is true when feof($fh) returns false梚n other words, when the bookmark is not past the end of the file. Next the loop body runs, doing some things with $line. After the loop body is done, the iteration expression runs and stores the next line of the file in $line.

Everything moves along line by line in the for( ) loop until the last line of the file has been read by the iteration expression. The code block runs one more time, and the <li><a href="mailto:dodgson@turtle.example.com">Lewis Humbert</li> line of HTML is printed. Then, fgets( ) is called in the iteration expression. At this point, though, there's nothing left in the file, so fgets( ) returns false and puts the bookmark past the end of the file. Now, when feof( ) is called in the test expression, it sees where the bookmark is and returns true. This ends the for( ) loop.

Example 10-6 uses trim( ) on $line because the string that fgets( ) returns includes the trailing newline at the end of the line. The trim( ) function removes the newline, which makes the output look better.

The first argument to fopen( ) is the name of the file that you want to access. Use forward slashes (/) instead of backslashes (\) here, even on Windows. Example 10-8 opens a file in the Windows system directory.

Example 10-8. Opening a file on Windows
$fh = fopen('c:/windows/system32/settings.txt','rb');

Because backslashes have a special meaning (escaping, which you saw in Section 2.1.1) inside strings, it's easier to use forward slashes in filenames. The PHP interpreter does the right thing in Windows and loads the correct file.

The second argument to fopen( ) is the file mode. This controls what you're allowed to do with the file once it's opened: reading, writing, or both. The file mode also affects where the PHP interpreter's file position bookmark starts, whether the file's contents are cleared out when it's opened, and how the PHP interpreter should react if the file doesn't exist. Table 10-1 lists the different modes that fopen( ) understands.

Table 10-1. File modes for fopen( )

Mode

Allowable actions

Position bookmark starting point

Clear contents?

If the file doesn't exist?

rb

Reading

Beginning of file

No

Issue a warning, return false.

rb+

Reading, Writing

Beginning of file

No

Issue a warning, return false.

wb

Writing

Beginning of file

Yes

Try to create it.

wb+

Reading, Writing

Beginning of file

Yes

Try to create it.

ab

Writing

End of file

No

Try to create it.

ab+

Reading, Writing

End of file

No

Try to create it.

xb

Writing

Beginning of file

No

Try to create it; if the file does exist, issue a warning and return false.

xb+

Reading, Writing

Beginning of file

No

Try to create it; if the file does exist, issue a warning and return false.


Once you've opened a file in a mode that allows writing, use the fwrite( ) function to write something to the file. Example 10-9 uses the wb mode with fopen( ) and uses fwrite( ) to write information retrieved from a database table to the file dishes.txt.

Example 10-9. Writing data to a file
require 'DB.php';

$db = DB::connect('mysql://hunter:w)mp3s@db.example.com/restaurant');



// Open dishes.txt for writing

$fh = fopen('dishes.txt','wb');



$q = $db->query("SELECT dish_name, price FROM dishes");

while($row = $q->fetchRow( )) {

    // Write each line (with a newline on the end) to

    // dishes.txt

    fwrite($fh, "The price of $row[0] is $row[1] \n");

}

fclose($fh);

The fwrite( ) function doesn't automatically add a newline on to the end of the string you write. It just writes exactly what you pass to it. If you want to write a line at a time (such as in Example 10-9), be sure to add a newline (\n) to the end of the string that you pass to fwrite( ).

    Previous Section  < Day Day Up >  Next Section