Working with Formatted Text

Working with Formatted Text

Text files are easy to work with, but they are extremely unstructured. Sometimes you might want to impose a little bit of formatting on a text file in order to work with data in the file. You'll learn some more formal data management skills in the next couple of chapters, but with a few simple tricks you can do quite a lot with plain text files.

Introducing the mailMerge.php Program

To illustrate how text files can be used for basic data storage, I created a simple mail merge program. The results of this program are shown in Figure 6.9.

Click To expand
Figure 6.9: The program created several form letters from a list of names and e-mail addresses.

You can see that the same letter was used repeatedly, but each time it used a different name and e-mail address. The name and e-mail information was pulled from a file.

Determining a Data Format

The data file (shown in Figure 6.10) for this program is simply a file created in Notepad. Each line consists of a name and an e-mail address, separated by a tab character.

Click To expand
Figure 6.10: The data file for this program was created in Notepad.
TRICK?

This particular format (one line per record, each field separated by tabs) is called a tab-delimited file, and it is extremely popular, because you can easily create it in a text editor, spreadsheet, or any other kind of program you wish. It's also quite easy to use another character as a separator. Spreadsheet programs often save in a comma-delimited format (CSV for comma-separated values) but string data does not work well in this format because it might already have commas embedded in it.

Examining the mailMerge.php Code

The basic strategy for the mailMerge program is very simple. Take a look at the code for the program, and you might be surprised at how easy it is.

<html>
<head>
<title>Mailing List</title>
</head>
<body>
<form>

<?
//Simple Mail merge
//presumes tab-delimited file called maillist.dat

$theData = file("maillist.dat");

foreach($theData as $line){
  $line = rtrim($line);
  print "<h3>$line</h3>";
  list($name, $email) = split("\t", $line);
  print "Name: $name";

  $message = <<<HERE
TO: $email:
Dear $name:

Thanks for being a part of the spam afficionado forum. You asked to
be notified whenever a new recipe was posted. Be sure to check our web
site for the delicious 'spam flambe with white sauce and cherries' recipe.

Sincerely,

Sam Spam,
Host of Spam Afficionados.

HERE;

  print "<pre>$message</pre>";

} // end foreach

?>
</body>
</html>

Loading the Data with the file() Command

The first step is to load the data into the form. Instead of using the file pointer technique from earlier in the chapter, I used a special shortcut that can be extremely handy. The file() command takes a filename and automatically loads that file into an array. Each line of the file becomes an element of the array. This is especially useful when your text file contains data, because each line in my data file represents one individual's data.

TRAP?

The file() command is so easy you might be tempted to use it all the time, but it loads the entire file into memory, so you should only use it for relatively small files. When you use the fgets() technique, you only need to have one line from the file in memory at a time, so the fgets() method can be effectively used on any size file without affecting performance. Using file() on a very large file can be extremely slow.

Splitting a Line into an Array to Scalar Values

You might recall the split() function from Chapter 5, "Better Arrays and String Handling." This function is used to separate elements of a string based on some delimiter. I used the split() function inside a foreach loop to break each line into its constituent values. However, I really didn't want an array in this situation. Instead, I wanted the first value on the line to be read into the $name variable, and the second value should be stored in $email. The list() function allows you to take an array and distribute its contents into scalar (non-array) variables. In this particular situation, I never stored the results of the split() function in an array at all, but immediately listed the contents into the appropriate scalar variables. Once the data is in the variables, it can be easily interpolated into a mail-merge message.

IN THE REAL WORLD
Start example

The next obvious step for this program would be to automatically send each message as an e-mail. PHP provides a function called mail() which makes it quite easy to add this functionality. However, the way the function works is very dependent on how the server is set up, and it won't work with equal reliability on every server.

Also, there are good reasons to send e-mail through a program, and reasons that aren't so good. It's completely legitimate to send e-mails to people when they request it, or to have a program send you e-mails when certain things happen. For example, my own more secure version of the tester program sends me an e-mail to alert when certain conditions that might indicate cheating occur. A program that sends unsolicited e-mail to people is rude, and will cause bad feelings about your site.

End example