Reading and Writing Parts of Files in PHP

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 the file() function to access each line of a file. Example 9-4 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 9-4. Accessing each line of a file

foreach (file(‘people.txt’) as $line) {

$line = trim($line);

$info = explode(‘|’, $line);

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

}

Suppose people.txt contains what’s listed in Example 9-5.

Example 9-5. people.txt for Example 9-4

alice@example.com|Alice Liddell

bandersnatch@example.org|Bandersnatch Gardner

charles@milk.example.com|Charlie Tenniel

dodgson@turtle.example.com|Lewis Humbert

Then, Example 9-4 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>

The file() function returns an array. Each element of that array is a string contain­ing one line of the file, newline included. So, the foreach() loop in Example 9-4 visits each element of the array, putting the string in $line. The trim() function removes the trailing newline, explode() breaks apart the line into what’s before the | and what’s after it, and then print outputs the HTML list elements.

Although file() is very convenient, it can be problematic with very large files. It reads the whole file to build the array of lines—and with a file that contains lots of lines, that may use up too much memory. In that case, you need to read the file line- by-line, as shown in Example 9-6.

Example 9-6. Reading a file one line at a time

$fh = fopen(‘people.txt’,’rb’);

while ((! feof($fh)) && ($line = fgets($fh))) {

$line = trim($line);

$info = explode(‘|’, $line);

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

}

fclose($fh);

The four file access functions in Example 9-6 are fopen(),fgets(), feof(), and fclose(). They work together as follows:

  • 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 conceptually simi­lar to the database connection variable returned by new PDO() that you saw in Chapter 8.)
  • The fgets() function reads a line from the file and returns it as a string.
  • The PHP engine 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”).
  • The fclose() function closes the connection to the file.

The while() loop in Example 9-6 keeps executing as long as two things are true:

  • feof($fh) returns false.
  • The $line value that fgets($fh) returns evaluates to true.

Each time fgets($fh) runs, the PHP engine grabs a line from the file, advances its bookmark, and returns the line. When the bookmark is pointing at the very last spot in the file, feof($fh) still returns false. At that point, however, fgets($fh) returns false because it tries to read a line and can’t. So, both of those checks are necessary to make the loop end properly.

Example 9-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. As with other PHP file access functions, use forward slashes (/) instead of backslashes (\) here, even on Windows. Example 9-7 opens a file in the Windows system directory.

Example 9-7. Opening a file on Windows

$fh = fopen(‘c:/windows/system32/settings.txt’,’rb’);

Because backslashes have a special meaning (escaping, which you saw in “Defining Text Strings” on page 20) inside strings, it’s easier to use forward slashes in filenames. The PHP engine 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 engine’s file position bookmark starts, whether the file’s con­tents are cleared out when it’s opened, and how the PHP engine should react if the file doesn’t exist. Table 9-1 lists the different modes that fopen() understands.

 

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

Example 9-8. Writing data to a file

try {

$db = new PDO(‘sqlite:/tmp/restaurant.db’);

} catch (Exception $e) {

print “Couldn’t connect to database: ” . $e->getMessage();

exit();

}

// Open dishes.txt for writing

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

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

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

// 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 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 9-8), be sure to add a newline (\n) to the end of the string that you pass to fwrite().

Source: Sklar David (2016), Learning PHP: A Gentle Introduction to the Web’s Most Popular Language, O’Reilly Media; 1st edition.

Leave a Reply

Your email address will not be published. Required fields are marked *