You are on page 1of 10

File System Management

In this lesson of the PHP tutorial, you will learn... 
1. To read from files on the server. 
2. To write to files on the server. 
3. To upload files to the server. 
4. To get information about files on the server. 
5. To access and work with directories on the server. 
Most Web applications use databases to store large amounts of data. However, in some cases, it will be 
necessary to store data in or access data from files.

Opening a File
fopen()
Syntax
fopen (path_to_file, file_mode)

path_to_file can either be a relative or an absolute path.
File Modes
File Mode Description
r  open for reading
w  open for writing (erases existing content); creates new file if one doesn't exist
a  open for appending to end of content; creates new file if one doesn't exist
x  create and open for writing (new in PHP 4.3.2); fails and returns false if file already exists
r+  open for reading and writing (erases existing content when file is written to)
open for writing and reading (erases existing content on opening or creates new file if one 
w+ 
doesn't exist
a+  open for appending and writing; creates new file if one doesn't exist
create and open for writing and reading (new in PHP 4.3.2); fails and returns false if file 
x+ 
already exists

File Permissions
Files that do no have the appropriate permissions settings will fail to open. In this case, the fopen() 
function will return false and a warning will be given. Use conditional processing as shown below to 
handle this situation.
$MyFile = @fopen('MyFile.txt','a');
if (!$MyFile)
{
echo '<b>Sorry, but the file cannot be opened.</b>';
}
else
{
// code for processing file
}

The @ symbol in front of first line of code is used to suppress errors. Any errors can then be handled 
more gracefully.

Reading from a File
Opening a file for reading involves three steps:
1. Open the file. 
2. Read the file. 
3. Close the file. 

fgets()
fgets() is used to read a file one line at a time. It requires one argument: the resource or "handle" for the 
file and accepts a second argument: the length of the line. It will continue reading the line until the 
length ­ 1 have been read or it reaches the end of the line or the end of the file. If the second argument 
is not included, it will continue reading until it reaches the end of the line.
Examine the file shown below.

Code Sample: Files/Demos/Employees.txt
Nancy Davolio Sales Representative ndavolio@northwind.com
Andrew Fuller Vice President, Sales afuller@northwind.com
Janet Leverling Sales Representative jleverling@northwind.com
Margaret Peacock Sales Representative mpeacock@northwind.com
Steven Buchanan Sales Manager sbuchanan@northwind.com
Michael Suyama Sales Representative msuyama@northwind.com
Robert King Sales Representative rking@northwind.com
Laura Callahan Inside Sales Coordinator lcallahan@northwind.com
Anne Dodsworth Sales Representative adodsworth@northwind.com

Code Explanation
Employees.txt is a tab­delimited text file. Each line is formatted as follows: 

FirstName\tLastName\tTitle\tEmail\n

The file is divided into "columns" using tabs (\t) and each "row" is separated by a newline 
character (\n). The code below opens Employees.txt, reads and displays each line, and 
closes the file.
Code Sample: Files/Demos/Employees.php
<html>
<head>
<title>Employees</title>
</head>
<body>
<h1>Employees</h1>
<?php
$MyFile = @fopen("Employees.txt", 'r');

if (!$MyFile)
{
echo '<p>Cannot open file.';
}
else
{
while (!feof($MyFile))
{
$Employee = fgets($MyFile, 999);
echo $Employee.'<br />';
}
fclose($MyFile);
}
?>
</body>
</html>

Other options for reading from files
Function Description
fgetss()  Like fgets() but it strips out HTML and PHP tags.
fgetcsv()  Like fgets() but it splits the file on a specified delimiter rather than a newline character.
readfile()  Opens a file, sends its contents to the browser, and closes the file.
file()  Opens a file, splits it into an array on newline characters, and closes the file.

Writing to a File
Opening a file for writing involves three steps:
1. Open the file. 
2. Write to the file. 
3. Close the file. 

fwrite()
Syntax
fwrite(file_pointer,output_string)

The output_string is the text to write to the file. See the following example of writing to a file.
$OutputString='text to write';
$MyFile = @fopen('Employees.txt', 'a');
fwrite($MyFile, $OutputString);
fclose($MyFile);

Exercise: Writing to a File

Duration: 10 to 15 minutes.
In this exercise you will write code to append entries to the Employees.txt.
1. Open Files/Exercises/AddEmployee.php in your editor. 
2. Create short versions of the form variables. 
3. Write code to save the entry in Employees.txt, which is in the same directory. The steps involved 
are:
1. Open Employees.txt for appending. Be sure to suppress errors. 
2. Write a condition that checks to see if the file failed to open. 
3. If it did open, write the output string to the file and close the file. 
Where is the solution? 

File Locking
flock() (see footnote) 
flock() is used to lock a file so that two or more people do not get access to it at the same time. This 
helps protect the file from being corrupted. flock() takes two arguments: a file handler and a lock type.
Lock Type Explanation
LOCK_SH  Reading lock. Others can read file.
LOCK_EX  Exclusive lock. The file cannot be opened by others.
LOCK_UN  Unlocks file.
If a file is already locked by another user, flock() waits to get a lock. LOCK_NB tells it 
LOCK_NB 
not to wait.
The code below shows how we should change Files/Solutions/AddEntry.php to protect Employees.txt 
from being corrupted.

Code Sample: Files/Demos/Locking.php
---- Code Omitted ----

flock($MyFile, LOCK_EX);
fwrite($MyFile,$OutputString);
flock($MyFile, LOCK_UN);
fclose($MyFile);
---- Code Omitted ----
Uploading Files via an HTML Form (see 
footnote) 
In order to upload files via an HTML form, the form tag's method must be set to "post" and the enctype 
must be set to "multipart/form­data" as shown below.
Syntax
<form method="post" enctype="multipart/form-data">

The following example demonstrates how to safely allow the user to upload a file to the server.

Code Sample: Files/Demos/FileUpload.php
<html>
<head>
<title>Resume Upload</title>
</head>
<body style="text-align:center">
<?php
if (!array_key_exists('Submitted',$_POST)) {
?>
<h2>Resume Upload Form</h2>
<form method="post" enctype="multipart/form-data">
<input type="hidden" name="Submitted" value="true">
<table border="1">
<tr>
<td>First Name</td>
<td><input type="text" name="FirstName" size="20"></td>
</tr>
<tr>
<td>Last Name</td>
<td><input type="text" name="LastName" size="20"></td>
</tr>
<tr>
<td>Resume</td>
<td><input type="file" name="Resume"></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="Upload"></td>
</tr>
</table>
</form>
<?php
} else {
//process the form
$ResumeFile = $_FILES['Resume']['tmp_name'];
$FileSize = $_FILES['Resume']['size'];
$FileType = $_FILES['Resume']['type'];
$FileError = $_FILES['Resume']['error'];

$ResumeName=$_POST['FirstName'] . '_' .
$_POST['LastName'] . '_Resume.txt';
if ($FileError)
{
echo "We could not upload the file:<br/>$FileError";
EndPage();
}
elseif ($FileType != 'text/plain')
{
echo "You have attempted to upload a file of type: $FileType.
<br/>Only text files allowed.";
EndPage();
}

$FileSavePath = 'Resumes/' . $ResumeName;


if (is_uploaded_file($ResumeFile))
{
if (!move_uploaded_file($ResumeFile,$FileSavePath))
{
echo 'Could not save file.';
EndPage();
}
}
else
{
//This case happens if somehow the file
//we are working with was already on the server.
//It's to stop hackers.
echo 'Hey, what is going on here?
Are you being bad?';
EndPage();
}
$Resume=makeFileSafe($FileSavePath);
?>
<h2>Thanks!</h2>
<b>We got your resume.</b><hr>
<form>
<textarea cols="60" rows="20"><?echo $Resume?></textarea>
</form>
</p>
<?php
}

function EndPage()
{
echo '</body></html>';
exit;
}

function makeFileSafe($FilePath)
{
$FP = @fopen($FilePath,'r+');
if (!$FP)
{
return "Could not read file";
}
$Contents = fread($FP,filesize($FilePath));
$Contents = strip_tags($Contents);
rewind($FP);
fwrite($FP,$Contents);
fclose($FP);
return $Contents;
}
?>
</body>
</html>

Code Explanation
The first thing to notice about this page is that it submits to itself. The first time it is loaded, 
it will show the form. When the form is submitted, it will attempt to upload and save the 
user's resume.

1. The form also has an input field of type file that is used to browse for the file to 
upload. 
2. When the form is submitted, the script assigns values to short named variables. 
3. The next block of code is the if­elseif­elseif statement, which checks for errors. If it 
finds any, it displays an appropriate message and calls the EndPage() user function, 
which just closes the HTML page. 
4. The next piece of code attempts to upload the file:

if (is_uploaded_file($ResumeFile))
{
if (!move_uploaded_file($ResumeFile,$FileSavePath))
{
echo 'Could not save file.';
EndPage();
}
}
else
{
//This case happens if somehow the file
//we are working with was already on the server.
//It's to stop hackers.
echo 'Hey, what is going on here?
Are you being bad?';
EndPage();
}

5. The last bit of PHP code on the page calls the makeFileSafe() user function which 
opens the resume file, strips out all the tags from its contents and closes it. 

Getting File Information
The following code sample illustrates how to get information about a file using PHP.

Code Sample: Files/Demos/FileInfo.php
<html>
<head>
<title>File Details</title>
</head>
<body>
<?php
$CurrentDir = 'Resumes/';
$File = basename('J_C_Resume.txt');
echo '<h1>Details of file: ' . $File.'</h1>';
$File = $CurrentDir.$File;

echo '<h2>File data</h2>';


echo 'File last accessed: ' .
date('j F Y H:i', fileatime($File)) . '<br/>';
echo 'File last modified: ' .
date('j F Y H:i', filemtime($File)).'<br/>';
echo 'File type: ' . filetype($File).'<br/>';
echo 'File size: '.filesize($File).' bytes<br/>';

echo '<h2>File tests</h2>';


echo 'is_dir: ' .
(is_dir($File)? 'true' : 'false') . '<br/>';
echo 'is_file: ' .
(is_file($File)? 'true' : 'false').'<br/>';
echo 'is_readable: ' .
(is_readable($File)? 'true' : 'false').'<br/>';
echo 'is_writable: ' .
(is_writable($File)? 'true' : 'false').'<br/>';
?>
</body>
</html>

Code Explanation
The functions used in this script are described in the following table.

Function Description
basename()  Strips off the path and returns the file name.
fileatime()  Returns the last accessed time of the file.
filemtime()  Returns the last modified time of the file.
filetype()  Returns the type of file (e.g, file or dir).
filesize()  Returns the size of the file in bytes.
is_dir()  Returns true if the passed value is a directory, false if it isn't.
is_file()  Returns true if the passed value is a file, false if it isn't.
is_readable()  Returns true if the file is readable, false if it isn't.
is_writable()  Returns true if the file is writable, false if it isn't.

More File Functions
A few more file functions are shown below:
Function Description
file_exists(path Checks to see if a file exists.
Function Description
_to_file) 
filesize(path_to
Returns the size of file in bytes.
_file) 
unlink(path_to
Deletes the file.
_file) 
Copies a file. Takes two arguments: the path to the source file and the destination to 
copy() 
copy the source file to.
Moves a file. Takes two arguments: the path to the source file and the destination to 
rename()  move the source file to. If the path and destination are the same with the exception of 
the filename, rename() simply renames the file.

Directory Functions
The following table shows some of the more common directory functions.
Function Description
mkdir()  Creates a directory.
rmdir()  Deletes a directory.
opendir()  Opens a directory for reading.
readdir()  Reads the contents of an open directory.

Getting a Directory Listing
To get a directory listing, use the opendir() function to open the directory and the readdir() function to 
read its contents. Then loop through its contents with a while loop outputting the name of each file and 
folder.

Exercise: Creating a Resume Management Page

Duration: 20 to 30 minutes.
In this exercise, you will create a simple resume management page that will list all the resumes 
currently in the resumes folder and allow you to remove resumes from the folder.
1. Open Files/Exercises/FileListing.php in your editor. Much of the file is done already. 
2. Complete the fileDetails() function so that it will properly display the details of the passed file. 
3. At the end of the if block of the fileDetails() function there is a "Delete File" link. Modify this 
link so that it passes the file path in the "Delete" variable via the query string. 
4. Write the browseDir() function. 
5. Write the deleteFile() function. 
Write a renameFile() function and add a form to the fileDetails() function that allows the user to 
provide a new name for the file.
Where is the solution? 

File System Management Conclusion
Although writing to and reading from files can be useful in certain situations, when it is important to be 
able to access and change data quickly and to maintain the integrity of that data, it is often better to use 
a database.
Many websites allow visitors to upload files via a form. In this lesson, we have stored those files in a 
directory under the web root. For security reasons, this is generally not a good idea. In practice, you 
should store any uploaded files above or outside of the web root.

Footnotes
1. flock() does not work with NFS or other networked file systems or with older systems such as 
FAT that do not support file locking.
2. For file uploads to work, the file_uploads flag in php.ini must be turned on

You might also like