Reading and Writing to Files in PHP

Here, you will learn how to read and write data in a file. There are various functions described here.

Function Descriptions
fread() This function is used to Read a string of characters from a file.
fwrite() This function is used to Write a string of characters to a file.
fgetc() This function is used to Read a single character at a time.
feof() This function is used to Check whether the end of the file has been reached.
fgets() This function is used to Read a single line at a time.
fgetcsv() This function is used to Read a line of comma separated values.
file() This function is used to Read an entire file into an array.
file_get_contents() This function is used to Read an entire file into a string without to open it.
file_put_contents() This function is used to Write a whole string to a file without to open it.
fpassthru() This function is used to Display the contents of an open file.
readfile() This function is used to Display the contents of a file without to open it.
fseek() This function is used to Move the file pointer to a specific location within an open file.
ftell() This function is used to Return the position of the file pointer.
rewind() This function is used to Move the file pointer to the start of the file.

Reading and Writing Strings of Characters

The fread() function can be used to read a string of characters from a file. It takes two arguments: a file handle and the number of characters to read. The function reads the specified number of characters (or less if the end of the file is reached) and returns them as a string.

Example:

$handle = fopen( “string.txt”, “r” );
$data = fread( $handle, 10 );

This code reads the first ten characters from string.txt and assigns them to $data as a string.

When you work with binary files a character it is always one byte long, so ten characters equals ten bytes. However, it will not be applied when working with Unicode files, where each character may take up several bytes.

Here reading ten characters result in reading twenty bytes from the file.

Now, after fread() has finished, the file pointer, which holds the current position in the file, moves forward in the file by the number of characters read. So after the code runs, the file pointer moves forward to ten characters after the start of the file. If you repeat the same call to fread() , you will get the next ten characters in the file. If there are less than ten characters left to read in the file, fread() simply reads and returns as many as there are.

If you want to read only one character at a time you can use the fgetc() function. fgetc() takes a single argument, a file handle and returns just one character from the file it points to; it returns false when it reaches the end of the file:

$one_char = fgetc( $handle );

However, fgetc() is slow when working with large files. It ’ s faster to read a bunch of characters at once using fread() , or one of the other file.

You can also use the fwrite() function to write data to a file. It requires two arguments: a file handle and a string to write to the file. The function writes the contents of the string to the file, returning the number of characters written (or false if there is an error).

Example

$handle = fopen( “string.txt”, “w” );
fwrite( $handle, “ABCxyz” );

The first line opens the file string.txt for writing, which erases any existing data in the file. (If the file does not exist, PHP attempts to create it.) The second line writes the character string “ABCxyz” to the beginning of the file. As with fread() , the file pointer moves to the position after the written string; if you repeat the second line, fwrite() appends the same six characters again, so that the file contains the characters “ ABCxyzABCxyz ” .

You can limit the number of characters written by specifying an integer as a third argument. The function stops writing after that many characters (or when it reaches the end of the string, whichever occurs first).

Example

This code writes the first four characters of “ abcdefghij ” (that is, “ abcd “ ) to the file:

fwrite( $handle, “abcdefghij”, 4 );

Testing for the End of a File

The feof() function serves a single, simple purpose: it returns true when the file pointer has reached the end of the file (or if an error occurs) and returns false otherwise. It takes just one argument — the file handle to test. Notice that feof() only returns true once the script has tried to read one or more characters past the last character in the file:

// hello_eBIZ.txt contains the characters “Hello eBIZ”
$handle = fopen( “hello_eBIZ.txt”, “r” );
$hello = fread( $handle, 13 );
echo $hello . “ < br / > ”; // Displays “Hello eBIZ”
echo feof( $handle ) . “ < br / > ”; // Displays “” (false)
$five_more_chars = fread( $handle, 5 );
echo $five_more_chars . “ < br / > ”; // Displays “” (or possibly a newline)
echo feof( $handle ) . “ < br / > ”; // Displays “1” (true)
fclose( $handle );

feof() is useful with fread() or fgetc() in a while loop when you do not know how long the file is:

// hello_world.txt contains the characters “Hello eBIZ”
$handle = fopen( “hello_eBIZ.txt”, “r” );
$text = “”;
while ( !feof( $handle ) ) {
$text .= fread( $handle, 3 ); // Read 3 chars at a time
}
echo $text . “ < br / > ”; // Displays “Hello eBIZ”
fclose( $handle );

Reading One Line at a Time

It is useful to read text from a file one line at a time. A line is a nice manageable block of text to process or display. For example, data files and configuration files often contain one block of information per line, such as a data record or a configuration setting.

To read a line of text from an open file, call the fgets() function, passing in the file handle. The function reads from the current file pointer to the end of the current line, and returns the read characters as a string (or false if there was a problem, such as the end of the file being reached).

You can limit the number of characters read by passing in a second, integer argument, in which case fgets() stops when it reaches that number of characters minus one (unless the end of the line is reached first). It is a good idea to include this argument when reading large files that might not contain line breaks.

This example uses fgets() to read and display a three – line text file, one line at a time. The while loop exits when fgets() returns false (which means it is reached the end of the file):

/*
eBIZdata.txt contains:
Learn something and grow your Knowledge
A way to success
Learning is a best education
*/
$handle = fopen( “eBIZdata.txt”, “r” );
$lineNumber = 1;
while ( $line = fgets( $handle ) )
{
echo $lineNumber++ . “: $line < br / > ”;
}
fclose( $handle );

The code produces the following output:

1: Learn something and grow your Knowledge
2: A way to success
3: Learning is a best education

Reading and Writing Entire Files

Writing code to read a file line by line, or string by string, can be slow. Fortunately, PHP provides you with some functions that can access the complete contents of a file in one go.

    • file() — This function is used for reading a whole file into an array, without needing to open it.

 

    • file_get_contents() and file_put_contents() — This function is used for reading and writing the contents of a file without needing to open it.

 

    • fpassthru() — This function is used for displaying the contents of an open file.

 

  • readfile() — This function is used for displaying the contents of a file without needing to open it

As these functions read the entire file into memory in one go, they will be used for small files (a few MB at most). If you are working with a 100MB text file, then it is probably best to use fread() or fgets() to read and process the file in blocks.

file() reads the contents of a file into an array, with each element containing a line from the file. It takes just one argument, a string containing the name of the file to read and returns the array containing the lines of the file:

$lines = file( “/desktop/php/myfile.txt” );

The newline character remains attached at the end of each line stored in the array.

This function does not require you to specify a file handle. All you need to do is pass in the filename of the file to read. The function automatically opens, reads, and, once it is done, closes the file.

You can optionally specify some useful flags as the second parameter to file() :

Flag Description
FILE_USE_INCLUDE_PATH This flag is used to look for the file in the include path
FILE_IGNORE_NEW_LINES This flag is used to remove newline characters from the end of each line in the array
FILE_SKIP_EMPTY_LINES This flag is used to Ignore empty lines in the file

As with other flags in PHP you can combine any of these flags with the bitwise OR operator For example, the following code looks for a file in the include path and, when found, reads the file, ignoring any empty lines in the file:

$lines = file( “myfile.txt”, FILE_USE_INCLUDE_PATH | FILE_SKIP_EMPTY_LINES );

As with fopen() , you can also use file() to fetch files on a remote host:

$lines = file( “http://www.example.com/string.html” );
foreach ( $lines as $line ) echo $line . “ < br / > ”;

A related function is file_get_contents() . This does a similar job to file() , but it returns the file contents as a single string, rather than an array of lines. The end – of – line characters are included in the string:

$fileContents = file_get_contents( “phpdata\.txt” );

If there was a problem reading the file, file_get_contents() returns false.You can pass the FILE_USE_INCLUDE_PATH flag as the second argument to file_get_contents().You can also optionally pass in an offset and/or a length parameter to determine where you want the file reading to start, and how many characters you want to read.

Example

This code reads 23 characters from phpdata.txt , starting at character 17:

$fileContents = file_get_contents( “phpdata.txt”, null, null, 17, 23 );

The first null argument avoids setting the FILE_USE_INCLUDE_PATH flag, and the second null argument avoids setting a context. file_put_contents() is the complement to file_get_contents() . As you imagine, it takes a string and writes it to a file:

$numChars = file_put_contents( “phpdata.txt”, $myString );

The function returns the number of characters written, or false if there was a problem. You can affect the behavior of the function by passing various flags as the third argument. file_put_contents() supports the same flags as file_get_contents() , as well as two additional flags:

Flag Description
FILE_APPEND This flag is used if the file already exists, append the string to the end of the file, rather than overwriting the file.
LOCK_EX. This flag is used to Lock the file before writing to it. This ensures that other processes cannot write to the file at the same time.

You can also lock files that are opened using fopen(). To do this, use flock().

fpassthru() and readfile() both take a file and output its unmodified contents straight to the Web browser. fpassthru() requires the handle of an open file to work with:

$numChars = fpassthru( $handle );

readfile() instead works on an unopened file:

$numChars = readfile( “phpdata.txt” );

As you can see, both functions return the number of characters read (or false if there was a problem).

fpassthru() reads from the current file pointer position, so if you have already read some of the file only the remaining portion of the file will be sent.

You can make readfile() search the include path for the file by passing true as the second argument. Incidentally, readfile() is handy for sending binary files — such as images and PDF documents — to the Web browser for displaying or downloading.

Random Access to File Data

Using the functions you have met so far, you can only manipulate data sequentially, that is, in the same order that it is arranged in the file. However, sometimes you need to skip around the contents of an open file. For example, you might want to read a file once to search for a particular string, then return to the start of the file in order to search for another string. This is easy if you have read the entire file using, for example, file_get_contents() . However, this is not practical for large files.Fortunately, it is possible to move the file pointer around within an open file, so that you can start reading or writing at any point in the file. PHP gives you three functions that let you work with the file pointer:

    • fseek() This function repositions the file pointer to a specified point in the file.

 

    • rewind() — This function moves the file pointer to the start of the file.

 

  • ftell() — This function returns the current position of the file pointer.

To use fseek() , pass the handle of the open file, and an integer offset. The file pointer moves to the specified number of characters from the start of the file (use zero to move the pointer to the first character).

Example

This code moves the pointer to the eighth character in the file (that is,six characters after the first character) and displays the next four characters from that point:

// hello_eBIZ.txt contains the characters “Hello eBIZ!”
$handle = fopen( “hello_eBIZ.txt”, “r” );
fseek( $handle, 6 );
echo fread( $handle, 4 ); // Displays “”
fclose( $handle );

To specify how the offset is calculated, you can add a third optional argument containing one of the following constants:

    • SEEK_SET — This constant is used to Set the pointer to the beginning of the file plus the specified offset (the default setting).

 

    • SEEK_CUR — This constant is used to Set the pointer to the current position plus the specified offset.

 

  • SEEK_END — This constant is used to Set the pointer to the end of the file plus the specified offset (use with a negative offset).

fseek() returns 0 if the pointer was successfully positioned, or – 1 if there was a problem.

You cannot use this function with files on remote hosts opened via HTTP or FTP.

If you want to move the pointer back to the start of the file (a common occurrence), a shortcut is the rewind() function. The following two lines of code both do the same thing:

fseek( $handle, 0 );
rewind( $handle );

The ftell() function takes a file handle and returns the current offset (in characters) of the corresponding file pointer from the start of the file. For example:

$offset = ftell( $handle );

The fpassthru() function outputs file data from the current file position onward. If you have already read data from an open file but want to output the file’s entire contents, call rewind() first.