With PHP,
there’s always more than one way to accomplish a particular task. Take file
upload, for example. Sure, you can do it the traditional way, using HTTP file
upload and transferring the file directly to a location on your Web server’s
disk. Or you can do it the more exotic way, and use the FTP
protocol to upload in a two-step process: from your local disk to a Web
server, and then to an FTP server.
PHP supports both FTP and HTTP upload methods natively,
leaving it to you to make the best decision based on the design requirements of
your application. Transferring a file using PHP’s FTP
functions is almost the same as doing it using a traditional FTP client–as
you’ll see even the function names are similar to standard FTP commands.
Reams have already been written about HTTP file upload,
which is why this brief tutorial focuses on FTP-based file uploads instead (in
the example that follows, though, you’ll see both in action). Note that this
tutorial assumes that you have a working PHP/Apache installation, with both
HTTP file upload and FTP functions active.
The downloadable
version of this article includes all of the code listings in more
manageable separate text files.
Step 1: Make sure you have permission to connect to/upload to the FTP
server
PHP’s FTP functions
works over a client-server connection, and so you will need to log in to the
target FTP server before you can perform a file upload. Your first task is to
make sure that you have the credentials necessary for this action. This step
might seem somewhat obvious, but you’d be surprised how many developers forget
it and waste hours of debugging time later on.
You can check this by using a command-line FTP client to log
in to the target FTP server and attempt to upload a dummy file (Listing A):
Listing A
$ ftp
ftp> open some.host.com
Connected to some.host.com.
220 Welcome to leon FTP Server!
User: upload
331 User upload okay, need password.
Password: ***
230 Restricted user logged in.
ftp> bin
200 Type okay.
ftp> hash
Hash mark printing On ftp: (2048 bytes/hash mark) .
ftp> put file.bin
200 PORT command successful.
150 Opening BINARY mode data connection.
##
226 Transfer completed.
ftp: 4289 bytes sent in 0.00Seconds 4289000.00Kbytes/sec.
ftp> bye
221 Goodbye.
Once you’ve confirmed that you have the relevant access
privileges, log out.
Step 2: Construct an upload form
Next, create a simple HTML form that asks the user for
critical parameters–FTP server access information, the server directory to
upload to, and the full path and name of the file to be uploaded. Here’s a
sample (Listing B) of what this form
might look like:
Listing B
<html>
<head></head>
<body>
<h2>Please provide the following information:</h2>
<form enctype=”multipart/form-data” method=”post” action=”upload.php”>
<input type=”hidden” name=”MAX_FILE_SIZE” value=”5000000″ />
Host <br />
<input type=”text” name=”host” /><p />
Username <br />
<input type=”text” name=”user” /><p />
Password <br />
<input type=”password” name=”pass” /><p />
Destination directory <br />
<input type=”text” name=”dir” /><p />
File <br />
<input type=”file” name=”file” /><p />
<input type=”submit” name=”submit” value=”Upload File” />
</form>
</body>
</html>
Here, the <input type=file…> element
renders as a file selection dialog box, from which the user can select the file
to be uploaded. The <form enctype=…> element then forces the form data to
be encoded as a multi-part submission, which makes it easier for PHP to
identify the file component of the submission.
Step 3: Create the PHP upload processor
Once the form has been submitted to the Web server, the next
(and final) step is to use PHP’s FTP functions to
transfer it to the target FTP server, using the access credentials supplied by
the user. Here’s the script (upload.php) that does
all the work (Listing C):
Listing C
<?php
// get FTP access
parameters
$host = $_POST[‘host’];
$user = $_POST[‘user’];
$pass = $_POST[‘pass’];
$destDir
= $_POST[‘dir’];
$workDir
= “/usr/local/temp”; // define this as per
local system
// get temporary file name
for the uploaded file
$tmpName
= basename($_FILES[‘file’][‘tmp_name’]);
// copy uploaded file into
current directory
move_uploaded_file($_FILES[‘file’][‘tmp_name’], $workDir.”/”.$tmpName) or die(“Cannot move uploaded file to
working directory”);
// open connection
$conn
= ftp_connect($host) or die (“Cannot initiate connection to
host”);
// send access parameters
ftp_login($conn,
$user, $pass) or die(“Cannot login”);
// perform file upload
$upload = ftp_put($conn, $destDir.”/”.$_FILES[‘file’][‘name’], $workDir.”/”.$tmpName, FTP_BINARY);
// check upload status
// display message
if (!$upload) {
echo “Cannot
upload”;
} else {
echo “Upload
complete”;
}
// close the FTP stream
ftp_close($conn);
// delete local copy of
uploaded file
unlink($workDir.”/”.$tmpName) or die(“Cannot delete uploaded file
from working directory — manual deletion recommended”);
?>
This might appear complicated, but it’s actually fairly
straightforward. Here’s what’s happening:
- Once the form has been submitted,
the credentials supplied by the user in the various form input fields are
extracted into regular PHP variables. Information about the uploaded file
also now becomes available through PHP’s special
$_FILES array. - The $_FILESarray
is made up of multiple sub-arrays, one for each uploaded file. The keys of
each sub-array hold information about the size, MIME type, original name
and temporary name of the corresponding uploaded file. This information is
used by the move_uploaded_file() function to transfer the file
from the system’s temporary directory to the working directory. Remember
to alter the value of $workDir to reflect a valid file path on
your system.
Tip: It’s usually
a good idea to check the type and size of the uploaded file before calling move_uploaded_file(), to ensure
that it satisfies any upload constraints the application might have. For
example, if the application requires files to be in ZIP format for upload, this
can be checked at this stage (from the MIME type) to ensure that files in other
formats are filtered out.
- The ftp_connect() and ftp_login() functions are used to initiate a
connection to the named FTP host, and log in to it using the supplied
credentials. - Assuming a successful login, the ftp_put() function is used to upload the
file from the working directory to the remote directory specified by the
user and rename it to its original form. Note the addition of the special FTP_BINARY argument to ftp_put(), to specify that the file be
transferred in binary (not ASCII) mode. Depending on the result code
returned by the ftp_put() function, an error or success
message is displayed to the user. - The ftp_close() function is used to end the FTP
session, and the unlink() function
is used to clean up by deleting the local copy of the file that was
created in step (2).
Simple, isn’t it? Go on, try it out for yourself and see!