fopen() and fread()

resource fopen ( string filename, string mode [, bool use_include_path [, resource context]])

string fread ( resource handle, int length)

Fopen() is, for many, a fiendishly complex function to use. The reason for this is because it is another one of those functions lifted straight from C, and so is not as user-friendly as most PHP functions. On the flip-side, as per usual, is the fact that fopen() is an incredibly versatile function that some people come to love for its ability to manipulate files just as you want it to.

Fopen() has two key parameters: the file to open, and how you would like it opened. Parameter one is easy - it is just $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", which opens the file in binary mode. This is not necessary on Unix-based systems, but it is on Windows, so it is best to use it everywhere - it is not detrimental on Unix-based systems at all.

Take a look at the following usages:

<?php
    fopen($filename, "r");
    fopen($filename, "w");
?>

Fopen() returns a file handle resource, which is basically the contents of the file. You cannot output it directly, e.g. "print fopen(....)", but fopen() -related functions all accept file handles as the file to work with, so you should store the return value of fopen() in a variable for later use. Therefore, here's a full usage of fopen() :

<?php
    $handle = fopen($filename, "a");
?>

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, and 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().

Fread() takes two parameters: a file handle to read from (this is the return value from fopen(), remember) and the number of bytes to read. The second parameter might not make sense at first, after all you generally want to read in all of a file, right?

Author's Note: Do not worry about specifying a number in parameter two that is larger than the file - PHP will stop reading when it hits the end of the file or the number of bytes in parameter two, whichever comes first.

Well, while the chances are that you will indeed want to read in all of a file, doing so requires you have enough memory to be able to read in the entire file at once - if you are working with files of several megabytes or indeed hundreds of megabytes, PHP's resource consumption would balloon. In circumstances such as these you have but two choices: buy more RAM, or parse your data sequentially!

Luckily, most people will not have to make that choice - most people work with text files under a megabyte in size, and PHP can load a megabyte file all at once in a tiny fraction of a second. To instruct PHP to use fread() to read in the entire contents of a file, you simply need to specify the exact file size in bytes of that file as parameter two to fread(). Sound difficult? PHP comes to the rescue again with the filesize() function, which takes the name of a file to check, and returns its filesize in bytes - precisely what we're looking for.

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

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

<?php
    $contents = fread($handle, filesize($filename));
?>

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

Author's Note: Although PHP automatically closes all files you left open in your script, it is not smart to rely on it to do so - it is a poor use of resources, and it might affect other processes trying to read the file. Always, always, always close your files the minute you are finished with them.

To close a file you have opened with fopen(), use fclose() - it 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. Here is the script:

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

Firstly, remember that you will need to set $filename to be the location of a file on your system that you have access to. Secondly, notice that fopen() is called with "fb" as the second parameter - read-only, binary-safe. Always use "b" to ensure compatibility with Windows servers. Thirdly, notice that filesize() is being used to fread() in all of $filename's contents. Finally, notice that fclose() is called before $contents is printed - it is closed as soon as $handle is no longer needed. Get into - and stay in - this habit.

 

Want to learn PHP 7?

Hacking with PHP has been fully updated for PHP 7, and is now available as a downloadable PDF. Get over 1200 pages of hands-on PHP learning today!

If this was helpful, please take a moment to tell others about Hacking with PHP by tweeting about it!

Next chapter: Creating and changing files >>

Previous chapter: file_get_contents() and file()

Jump to:

 

Home: Table of Contents

Copyright ©2015 Paul Hudson. Follow me: @twostraws.