Section 13.1. Reading Files


13.1. Reading Files

There are several ways to open and display files, and each has its uses. You don't need to know all the ways to read filesit is probably best to learn one and stick with it for your own code. However, you will almost certainly come across each of these methods in other people's code, because everyone has her own method of getting things done.

13.1.1. readfile( )

If you want to output a file to the screen without doing any form of text processing on it whatsoever, readfile( ) is the easiest function to use. When passed a filename as its only parameter, readfile( ) will attempt to open it, read it all into memory, then output it without further question. If successful, readfile( ) will return an integer equal to the number of bytes read from the file.

If unsuccessful, readfile( ) will return false, and there are quite a few reasons why it may fail. For example, the file might not exist, or it might exist with the wrong permissions.

Here is an example script:

     $testfile = @readfile("/home/paul/test.txt");     // OR "@readfile("c:\\boot.ini");" if you are using Windows     if (!$testfile) {             print "Could not open file.\n";     } 

If readfile( ) fails to open the file, it will print an error message to the screen. You can suppress this by placing an @ symbol before the function call.

The advantages to using readfile( ) are clear: there is no fuss, and there is little way for it to go wrong. However, the disadvantage is equally clear: you have no control over the text that comes out.

From here on, I will use the variable $filename to signify a filename you have chosen. This is to avoid having to keep printing separate examples for Windows and Unix.


13.1.2. file_get_contents( ) and file( )

The next evolutionary step up from readfile( ) is called file_get_contents( ), and it also takes one parameter for the filename to open. This time, however, it does not output any data. Instead, it will return the contents of the file as a string, complete with new line characters \n where appropriate. For example:

     $filestring = file_get_contents($filename);     if ($filestring) {             print $filestring;     } else {             print "Could not open $filename.\n";     } 

The file_get_contents( ) function opens $varname and places its contents into $filestring. Effectively, that piece of code is the same as our call to readfile( ), but only because we're not doing anything with $filestring once we have it.

If you want your file to be converted into an array, with each line an element inside that array, you should use the file( ) function:

     $filearray = file($filename);     if ($filearray) {             while (list($var, $val) = each($filearray)) {                     ++$var;                     $val = trim($val);                     print "Line $var: $val<br />";             }     } else {             print "Could not open $filename.\n";     } 

That script iterates over the file array, outputting one line at a time with line numbers. Array indexes start at 0, so we need ++$var to make sure that it starts at line 1 rather than line 0. We call trim( ) on $val because each element in the array still has its new line character \n at the end, and trim( ) will take that off.

13.1.3. fopen( ) and fread( )

For many people, fopen( ) is a fiendishly complex function. This is because it is another one of those functions lifted straight from C, and is not as user-friendly as most PHP functions. On the flip side, fopen( ) is an incredibly versatile function that you are likely to come to love for its ability to manipulate files just as you want it to.

It has two key parameters: the file to open, and how you would like it opened. The first parameter is $filename, as with the other examples. Parameter two is what makes fopen( ) so special: you specify letters in a string that define whether you want to read from (r), write to (w), or append to (a) the file specified in parameter one.

There is also a fourth option, b or t, which opens the file in binary mode or text modethe latter of which is designed to allow Windows to translate Unix-style line returns (\n) into Windows-style line returns (\r\n). PHP will enable binary mode by default on Windows in newer versions of PHP, but not on Unix, and not on older versions of PHP. This naturally causes great confusion, but the solution is simple: if you want binary mode, specify it. If you don't want binary mode, specify text mode with a t. Do not leave it to the default.

Take a look at the following usages:

     $fh_flowers = fopen("kinds_of_flowers.txt", "r")       OR die ("Can't open flowers file!\n");     $fh_logfile = fopen("$appname-log.log", "w")       OR die ("Log file not writeable!\n"); 

The fopen( ) function returns a file handle resource, which is a pointer to the location of the contents of the file. You cannot output it directly, e.g., print fopen($filename), but all fopen( )-related functions accept file handles as the file to work with. You should store the return value of fopen( ) in a variable for later use:

     $handle = fopen($filename, "a");     if (!$handle) {             print "Failed to open $filename for appending.\n";     } 

If the file cannot be opened, fopen( ) returns false. If the file is successfully opened, a file handle is returned and you can proceed. Once the file handle is ready, we can call other functions on the opened file, depending on how the file was opened (the second parameter to fopen( )). To read from a file, the function fread( ) is used; to write to a file, fwrite( ) is used. For now we're interested in reading, so you should use rb for the second parameter to fopen( ).

The fread( ) function takes two parameters: a file handle to read from (this is the return value from fopen( )) and the number of bytes to read. When combined with the feof( ), which takes a file handle as its only parameter and returns true if you are at the end of the file or false otherwise, it becomes easier to work with files of several megabytes or, indeed, hundreds of megabytes. For example:

     $huge_file = fopen("VERY_BIG_FILE.txt", "r");     while (!feof($huge_file)) {             print fread($huge_file, 1024);     }     fclose($huge_file); 

This use of fread( ) is also good for when you only care about a small part of the file. For example, Zip files all start with the letters "PK", so we can do a quick check to ensure a given file is a Zip file with this code:

     $zipfile = fopen("data.zip", "r");     if (fread($zipfile, 2) != "PK") {       print "Data.zip is not a valid Zip file!";     }     fclose($zipfile); 

To instruct PHP to use fread( ) to read in the entire contents of a file, you need to specify the exact file size in bytes as the second parameter to fread( ). PHP comes to the rescue again with the filesize( ) function, which takes the name of a file to check and returns its filesize in bytesprecisely what we're looking for.

Don't worry about specifying a number in the second parameter that is larger than the filePHP will stop reading when it hits the end of the file or the number of bytes in the second parameter, whichever comes first.


When reading a file, PHP uses a file pointer to determine which byte it is currently up tolike the array cursor. Each time you read in a byte, PHP advances the file pointer by one place. Reading in the entire file at once advances the pointer to the end of the file.

So, to use fread( ) to read in an entire file, we can use the following line:

     $contents = fread($handle, filesize($filename)); 

Notice that fread( )'s return value is the text it read in, and in the above situation, that is the entire file. To finish off using fread( ), it is necessary to close the file as soon as you are done with it.

Using fclose( ) immediately closes a file handle (although PHP will automatically close any file handles when your script finishes).


To close a file you have opened with fopen( ), use fclose( ). This takes the file handle we got from fopen( ) and returns TRue if it was able to close the file successfully. We have now got enough to use fopen( ) to fully open and read in a file, then close it:

     $handle = fopen($filename, "rb");     $contents = fread($handle, filesize($filename));     fclose($handle);     print $contents; 

You will need to set $filename to be the location of a file on your system that you have access to. In that example, fopen( ) is called with rb as the second parameter, for "read-only, binary-safe". Also, filesize( ) is being used to fread( ) in all of $filename's contents. The call to fclose( ) is made before $contents is printed, so that it is closed as soon as $handle is no longer needed.

13.1.4. Reading by line using fgets( )

In the same way that fread( ) is good for reading large files piece by piece, fgets( ) is good for reading large files line by line. Accessing by line means that you don't need to load the entire file into RAM at once, and it also lets you process each line as it arrives. To use fgets( ), pass it a file handle as its only parameter, and it will send back the next line as its return value.

For example, the next code block reads a large log line by line, only printing the lines that start with the word "Error":

     $access_log = fopen("access_log", "r");     while (!feof($access_log)) {             $line = fgets($access_log);             if (preg_match("/^Error:/", $line)) {                     print $line;             }     }     fclose($access_log);

You can find more information about the preg_match( ) in Chapter 15.




PHP in a Nutshell
Ubuntu Unleashed
ISBN: 596100671
EAN: 2147483647
Year: 2003
Pages: 249

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net