Languages PHP Using PHP with Files

Using PHP with Files

The ability to work within the file system is the power to store and retrieve
information from the server. Combined with forms, it’s the basis for a range
of applications like guestbooks, blogs, images galleries and more.

In the next two articles, you will get an in depth look at how to work with
files and directories. You will learn how to use text files as databases, perform
basic tasks such as renaming and deleting files, and manipulate directories.
You will also see how to combine forms and files to accept user input and store
it on the server, including how to handle uploads.


Text Files as Databases

Text files are frequently used like databases to store information on the server.
In situations where there is no access to a real database like MySql, or when
the project is relatively simple and small, this is an idea solution. Text files
being utilized in this way are very similar in structure to regular databases,
spreadsheets and even arrays. These types of files are often known as comma
delimited databases, or flat file databases.

Take a look at the following sample file, file.txt:


John Doe|[email protected]
Jane Doe|[email protected]
Billy Bob Joe|[email protected]

Each entry in this file is on a separate row, seperated by an invisible new
line character ("n"). Every row is split into two different columns
by the "|" character. Any single or set of characters can be used
to delimitate the different columns within a row, as long as the single character
or combined set does not appear elsewhere in the text file. For example, John
Doe^^**^^^[email protected] would be perfectly valid, if a little verbose.

Unlike the columns within a spreadsheet or database, the columns within this
text file are not physically labeled. However, each column within each row has
an implied label. In the above example, the first column represents the name
of a person, and the second column represents their email. Every row must follow
the same format, creating a grid or array-like structure.

Now that you have a basic understanding of how these types of files look, let’s
explore how you can write your own data to them. We will be using the same sample
file, file.txt, so you can copy and save the file to your own hard drive.


Writing to Files

Adding new information to a file like this is fairly easy. There are three
basic steps:

  1. Open the file.
  2. Add the information to the file.
  3. Close the file.

Using file.txt, let’s take a look at the process. Assume that you had two
variables available representing a new and email:

<?php
$name = "The Name";
$email = "[email protected]";

Just like on your own computer, the first step in reading or writing to a file
is to open the file itself. To do this, the PHP function fopen() is used:


$fp = fopen("file.txt","a");

Let’s take a closer look at this line. The first argument of the fopen() function
determines what file will be opened, using a relative path (so if your file
was in a sub-directory called "files", then you would reference it
as "files/file.txt"). The second argument, also required, determines
what mode the file should be opened in.

There are half dozen different modes:


r


Opens the file for reading only, and begin reading at the start of
the file
r+ Opens
the file for reading and writing, beginning at the start of the file
w Opens
the file for writing only, and deletes everything in the file. If
the file doesn’t exist, PHP will also try to create it.
w+ Opens
the file for reading and writing and deletes everything within the
file. If the file doesn’t exist, PHP will so try to create it.
a
Open
the file for writing only, beginning at the end of the file
a+ Open
the file for reading and writing, beginning at the end of the file.

This function must always be assigned to a variable, as the variable will be
used to identify the file when you read or write to it. If the function can’t
open the file for any reason, it will return FALSE, so you can easily add error
checking:

$fp = fopen("file.txt","a");

if(!$fp) {
   print "error! The file could not be opened";
   
exit;

}

Now that the file it opened, we can write something to it. There are a couple
of ways to do this, but the easiest (and clearest) is to create a string with
the information you want to write to the file. Remember the format of the
previous entries in the sample text file as you look at this string. This is
essentially the same format, except that variables are used in place of the
actual name and email:

$stringtowrite=$name."|".$email;

Next, the string is written to the file using fwrite(). Defined earlier, $fp
is referenced to identify what file we want to write to:

fwrite($fp,
$stringtowrite);

If you wanted to add another line to the same file, you could use another fwrite()
statement. This is especially useful if you want to use a loop to add multiple
lines of information. You can also append multiple lines at a time by separating
them by the new line character, "n", which moves the "cusor"
to the next row in the file. For example: fwrite($fp, $stringtowrite."n".$stringtowrite2);

Once we’ve finished writing information to the file, the
final step is to close the file. Though not absolutely necessary, closing a
file after you have finished using it minimizes any possible chance of
corruption from being left open.

fclose($fp);
?>


Reading
from Files

Now that you have seen how to add information to a file, let’s take a look
at how you can view what you have written. PHP provides several different functions
for reading files; some are almost redundant, while others provide radically
different ways for extracting information. In this article, we’ll be taking
at two of the more common ones.

The fastest and easiest way to read a file is to use readfile(). This function
opens a file, reads it, and outputs the results all with a single call:

<?php
readfile("test.txt");
?>

Though quick and dirty, this method obviously does not allow for much control
over how the output is displayed. To get that control, the file() function is
used. Rather than fetching the entire file and outputting it at the same time,
file() grabs the contents of a file and assigns it to an array. Each line of
the file is represented by a separate row of the array.

$array
= file("test.txt");

Once the file is contained in an array, it is easy to print the contents of
the file with formatting. Remember that in our sample file each line of the
file contains multiple values separated by a "|". To print out the
file, we need to loop through the array using foreach, and during each itineration,
split the row apart to grab each value. To split the row apart, explode() is
used, which "explodes" a variable into separate parts on the occurrence
of another value. Each new part is assigned as an element in a new, scalar,
array:

foreach($array
as $row) {
   $line = explode($row, "|");
   print "Name: $line[0], Email: $line[1]<br>";
}

Since there’s nothing special about this loop, you can also use if statements
to include conditions for whether or not a row is printed.

With the file contained inside of an array, you can also
utilize other array functions to work with the data. For example, you can easily
find out how many entries you have in the file:

print
count($array);

or check to see if a certain string is inside of the file:

if (in_array("John
Doe",$array)) {
   print "The name John Doe is in this file<br>";
}

or choose and print a random line from the file after seeding the function with
the srand() function:

srand ((float) microtime()
* 10000000);
$random_key=array_rand($array);
$line = explode($array[$random_key], "|");

print "This is a random name and email: $line[0] : $line[1]<br>";
?>

Error handling with files

When reading and writing to files, there’s always potential for the operation
to fail because the file doesn’t exist, or because the server doesn’t have read/write
access to the file. This possiblity increases exponentially if you accept file
names based on user input. If such a situation occurs, the user will see an
unsightly PHP error, and the script will likely terminate.

You can handle any errors more gracefully though, by simply
including a few error handling lines before you attempt to read or write from a
file.

First, you should always check to make sure the file
actually exists. If it does, you can continue executing the script, but if it
doesn’t, you can exit and display a formatted error message, or even execute a
different block of code instead:

<?php
if (!file_exists("test.txt")) {
   print "oops, this file doesn’t exist.";
   exit;
}

//if we’ve gotten to this point, we know the file does exist

Next, depending on whether you plan to read or write to the file, you can also
check to make sure the file is readable and writeable. This is not so much an
issue on windows servers where permissions don’t come into play, but becomes
more practical on unix-based servers.

if (!is_readable("test.txt"))
{
   print "This file is not readable!";
   exit;
}

//if we’ve gotten to this point, we know the file is readable

if (!is_writeable("test.txt")) {
   print "This file is not writeable!";
   exit;
}


//if we’ve gotten to this point, we know the file is writeable.
?>

This kind of error handling could easily be combined into a single function
that could be called any time you need to open a file.


Remote Files

In addition to opening files stored on your own server, many of the file handling
functions also allow you to open remote URLs. For example, a script with the
following:

<?php
readfile("http://www.php.net");
?>

would output the PHP homepage at the URL of your script. Any images referenced
relatively on the page would not, however, be displayed.

Besides the "cool" factor, the ability to read remote files this has
some very practical applications. If there was a file on a remote server that
displayed stock listings, or sports scores and was dynamically updated, you
could include that content trasparently within your own page.

In addition to readfile(), you can also open remote files with fopen(), though
you cannot write to them using fwrite().


File Management

In addition to reading and writing to text files, PHP includes the ability
to perform common tasks relating to the management of files. Most of these tasks
can be performed in a line or two with PHP’s built in functions. Here are a
few of the more common ones:


Function

Usage Sample
.
rename() Renames
a given file
rename("oldname.txt","newname.txt");
unlink() Deletes
a file
unlink("file.txt");
filesize() Returns
the file size of a file
print
file("file.txt");
copy() Copys
a file from location to another
copy("olddir/oldname.txt","newdir/newname.txt");

You can find the complete list of file functions at the PHP
website
.


Working with Directories

There may be some instances when you need to perform tasks involving directories.
For example, if you were running an image gallery, you might want to have a
directory of thumbnails and be able to display them all for the user to browse.
Or, if your server has disabled the ability to list the contents of a directory,
you may want to create a script performs the same function.

To read a directory, you need to open it first, just as you would a file:

<?php
$dir=opendir("/directory/");

Once its open, you can use readdir to loop through all of the files and sub
directories listed within it:

while($file=readdir($dir)){
   print $file<br>";
}

When you try this snippet in an actual script, you’ll see that the "."
and ".." remain in the file listing. You can easily strip them out
like this:

while($file=readdir($dir)){
   if ($file!="." and $file!="..") {
      print "$file<br>";
   }
}

You could refine the script even more to denote which entries are directories:

while($file=readdir($dir)){
   if ($file!="." and $file!="..")
{
      if (is_dir($file)) {

         print "$file
(directory)<br>";
      } else {
         print "$file<br>";
      }
   }
}

When you are finished working with a directory, you should remember to close
it:

closedir($dir);
?>

Finally

In this article, you have seen how PHP can be used to work with files and directories.
Many of these tasks rely heavily on the use of arrays. Arrays can be used to
store the entire contents of a file, or an entire list of files and subdirectories
within a given directory. Exploring the wealth of built-in PHP array functions
will help you learn how to work with both files and directories better and allow
you to perform more complex tasks.

In the next article, we will return to the topic of forms to
see how to collect and store user submitted information on the server, rather
than emailing it. You’ll also learn how to accept uploads from the user, and
how to validate the files before storing them on the server.

Stay Tuned!


Liz Fulghum currently lives in Annapolis, MD where she works as a web designer for a custom shirt retailer. Liz was convinced to try PHP as an alternative to Perl; she has been a fan ever since and frequently works as a freelance developer.

# # #

Latest Posts

Related Stories