Professional Documents
Culture Documents
File Manipulation: Techniques You'll Need To Master
File Manipulation: Techniques You'll Need To Master
File Manipulation
Techniques You’ll Need to Master
n How to open a file
n How to read from a file
n How to write to a file
n How to close a file
n How to interact with the filesystem
n How to lock files
n Miscellaneous functions for handling files
Terms You’ll Need to Understand
nFile resources
nFile properties
nAdvisory locking
nEnd of File
Interacting with files is a constant aspect of programming.Whether they are cache files,
data files, or configuration files, the ability to manipulate files and their contents is a core
skill for PHP programmers. In this chapter, you will learn how to open file stream
resources for reading from and writing to files, as well as filesystem-level functions for
manipulating file attributes.
106 Chapter 6 File Manipulation
Opening Files
When interacting with files in PHP, the first step is to open them. Opening files creates a
resource that you must pass to the functions for reading, writing, and locking files.To
open a file, use the fopen() function.
fopen() takes as its first parameter the filename to open, and as its second the mode
with which to open the file.The filename can be either a local file or any network protocol
that PHP understands. In this chapter, we will only discuss local files: Network
streams will be covered in Chapter 10, “Stream and Network Programming.”The mode
determines what you can do with the file (read/write, write-only, read-only), where
your file resource will start from (the beginning of the file or the end of the file), and
what to do if the file does not exist (create it or fail).The complete list of modes is presented
in Table 6.1. fopen() also takes an optional argument: a Boolean flag indicating
whether the include_path should be searched (defaults to false).
Table 6.1 fopen() Modes
Mode Description
r Opens file for reading only; position is beginning of the file.
r+ Opens for reading and writing; position is beginning of the file.
w Opens for writing only; position is beginning of the file; if the file does not exist,
creates it.
w+ Opens file for reading and writing; position is beginning of the file; if the file does
not exist, creates it.
a Opens file for writing only; position is end of the file; if the file does not exist, creates
it.
a+ Opens file for reading and writing; position is end of the file; if the file does not
exist, creates it.
x Creates and opens a file for writing; position is at the beginning of the file; if the
file already exists, fails.
x+ Creates and opens a file for reading and writing; position is at the beginning of the
file; if the file already exists, fails.
On Windows systems, you can also specify explicitly whether your file consists of binary
or text data. (The default is text.) To do this, you can append a b or t to the mode,
respectively. Failure to do this can result in writing corrupted binary files. Although this
flag is only necessary on Windows platforms, it is recommended that you always use it
for portability reasons.
If the fopen() call fails for any reason, it will return false and emit an E_WARNING
level error; otherwise, it will return a stream resource for the file. For example, to open a
file for appending information, you would use code such as this:
Reading from a File 107
if(($fp = fopen($filename, “a”)) === false) {
// call failed, do something appropriate
}
// call succeeded, proceed normally
A call to fopen() can fail for a number of reasons—for example, if a file to be opened
for reading does not exist or the executing user does not have sufficient permissions to
open it with the specified mode.
Closing Files
After you are done accessing a file resource, you should close it. Unclosed files will be
automatically closed by PHP at the end of a request. But if two processes write to the
same file at the same time, they risk corruption, so you need to either close your files as
expediently as possible or implement a locking scheme.To close an open file resource,
you can use the fclose() function.
Reading from a File
When you have a valid file resource opened for reading, you can read from it in a number
of ways. Before you go about performing reads, however, you should ensure that
your stream resource still has data available.You can check this using the function
feof(). feof() returns true if the file resource has hit EOF (End Of File).
The most basic of the read functions is fread(). fread() takes as its two parameters
the file resource handle to read from and the length to be read. It returns a string with
the data that was read or false if an error occurred.
Here is an example of reading a file 1024 bytes at a time until it is complete:
if(($fp = fopen($filename, “r”)) === false) {
return;
}
while(!feof($fp)) {
$buffer = fread($fp, 1024);
// process $buffer
}
If you want to read your file resource a single line at a time, you can use the fgets()
function. fgets() takes a file resource as its first argument and reads up to 1024 bytes
from the file, returning when it reaches a newline.To change the maximum readable
string length, you can pass a length as an optional second parameter. On success, the line
just read (including its newline) is returned. If an error occurs, false is returned.
As an example, here is a code block that reads in a file of lines such as
foo=bar
108 Chapter 6 File Manipulation
and constructs an array using them as key value pairs:
$arr = array();
if(($fp = fopen($filename, “r”)) === false) {
return;
}
while(!feof($fp)) {
$line = fgets($fp);
list($k, $v) = explode(‘=’, rtrim($line));
$arr[$k] = $v;
}
The fpassthru() function allows you to directly output all the remaining data on a file
resource.The following code checks the first four bytes of a file to see if it is a JPEG; if
so, it sets the file resource position back to the start of the file using fseek() and outputs
the entire file:
function output_jpeg($filename)
{
if(($fp = fopen($filename, “rb”)) === false) {
return;
}
$line = fread($fp, 4);
// check the ‘magic number’ of the file
if($line === “\377\330\377\340”) {
fseek($fp, 0);
fpassthru($fp);
}
fclose($fp);
}
Writing to a File
If you have a file resource opened for writing, you can write to it using fwrite(),
which is the inverse of fread().
fwrite() takes as its first argument a file resource and as its second the string to
write to that file. Optionally, you can pass a third argument—the maximum length that
you want to write with the call. fwrite() returns the number of bytes written to the
file resource. fputs() is an alias of fwrite()—they perform the exact same functions.
You can force a flush of all output to a file using the fflush() function. Flushing
data is implicitly done when a file resource is closed, but is useful if other processes
might be accessing the file while you have it open.
Here is an example of a function that appends time stamped data to a logfile:
Determining Information About Files 109
function append_to_log($logline)
{
if(($fh = fopen(‘debug.log’, ‘a’)) === false) {
die(“Can not open debug.log”);
}
fwrite($fh, time().” “.$logline.”\n”);
fclose($fh);
}
Miscellaneous Shortcuts
In addition to the basic file functions, PHP offers a collection of ‘shortcut’ functions that
allow you to handle common tasks with a single function call. In this final section, you
will learn some of the more common shortcut functions available in PHP.
file()
Often you will want to convert a file into an array of its lines.The file() function performs
this task. It takes the filename to read as its first argument and an optional flag as
its second argument, specifying whether the include_path should be searched to find
the file.
Because the entire file must be read in and parsed when file() is called, this function
can be expensive if used on large files. For larger files, you will often want to open
the file with fopen() and iterate over it line by line with fgets() to achieve a similar
effect.
readfile()
Similar to fpassthru(), readfile() directly outputs an entire file. readfile
($filename) is equivalent to the following PHP code:
if($fp = fopen($filename, ‘r’)) {
fpassthru($fp);
fclose($fp);
}
Exam Prep Questions 113
file_get_contents()
Although it is possible to read an entire file into a string with the following code,
if(($fp = fopen($filename, “r”)) === false) {
$file = false;
} else {
$file = fread($fp, filesize($filename));
}
fclose($fp);
it is much more efficient to use the built-in function file_get_contents().That function
will replace the entire previous loop with
$file = file_get_contents($filename);