PHP provides a number of functions for reading data from files. These functions enable you to read by the byte, by the whole line, and even by the single character.
Reading Lines from a File with fgets() and feof()
When you open a file for reading, you may want to access it line by line. To read a line from an open file, you can use the fgets() function, which requires the file resource returned from fopen() as its argument. You must also pass fgets() an integer as a second argument, which specifies the number of bytes that the function should read if it doesn't first encounter a line end or the end of the file. The fgets() function reads the file until it reaches a newline character ("\n"), the number of bytes specified in the length argument, or the end of the filewhichever comes first.
$line = fgets($fp, 1024); // where $fp is the file resource returned by fopen()
Although you can read lines with fgets(), you need some way to tell when you reach the end of the file. The feof() function does this by returning true when the end of the file has been reached and false otherwise. The feof() function requires a file resource as its argument:
feof($fp); // where $fp is the file resource returned by fopen()
You now have enough information to read a file line by line, as shown in Listing 13.8.
Listing 13.8. Opening and Reading a File Line by Line
If this code were saved to the document root of your web server as readlines.php and run through your web browser, the output would look something like Figure 13.3 (the contents of your sample text file might be different).
Figure 13.3. Output of readlines.php.
We call fopen() on line 3, using the name of the file that we want to read as its argument. We use the or die() construct to ensure that script execution ends if the file cannot be read. This usually occurs if the file does not exist or if the file's permissions don't allow read access to the file.
The actual reading of the file contents takes place in the while statement on line 4. The while statement's test expression calls feof() for each iteration, ending the loop when it returns TRue. In other words, the loop continues until the end of the file is reached. Within the code block, we use fgets() on line 5 to extract a line (or 1,024 bytes, whichever comes first) from the file. We assign the result to $line and print it to the browser on line 6, appending a <br/> tag for the sake of readability.
Reading Arbitrary Amounts of Data from a File with fread()
Rather than reading text by the line, you can choose to read a file in arbitrarily defined chunks. The fread() function accepts a file resource as an argument, as well as the number of bytes you want to read. The fread() function returns the amount of data you requested, unless the end of the file is reached first.
$chunk = fread($fp, 16);
Listing 13.9 amends our previous example so that it reads data in chunks of eight bytes rather than by the line.
Listing 13.9. Reading a File with fread()
If this code were saved to the document root of your web server as readlines2,php and run through your web browser, the output could look something like Figure 13.4.
Figure 13.4. Output of readlines2.php.
Although the fread() function enables you to define the amount of data acquired from a file, it doesn't let you decide the position from which the acquisition begins. You can set this manually with the fseek() function.
The fseek() function enables you to change your current position within a file. It requires a file resource and an integer that represents the offset from the start of the file (in bytes) to which you want to jump:
Listing 13.10 uses fseek() and fread() to output the second half of a file to the browser.
Listing 13.10. Moving Around a File with fseek()
If this code were saved to the document root of your web server as readseek.php and run through your web browser, the output could look something like Figure 13.5.
Figure 13.5. Output of readseek.php.
We calculate the halfway point of our file on line 5, by dividing the return value of filesize() by 2. We use this as the second argument to fseek() on line 7, jumping to the halfway point of the text file. Finally, we call fread() on line 8, to extract the second half of the file and then print the result to the browser.
Reading Characters from a File with fgetc()
The fgetc() function is similar to fgets() except that it returns only a single character from a file every time it is called. Because a character is always one byte in size, fgetc() doesn't require a length argument. You must simply pass it a file resource:
$char = fgetc($fp);
Listing 13.11 creates a loop that reads the file test.txt one character at a time, outputting each character to the browser on its own line.
Listing 13.11. Moving Around a File with fgetc()
If this code were saved to the document root of your web server as readchars.php and run through your web browser, the output could look something like Figure 13.6.
Figure 13.6. Output of readchars.php.