This brief tutorial focuses on FTP-based file uploads using the PHP-FTP protocol to upload in a two-step process: from your local disk to a Web server and then to an FTP server.
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.
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):
$ 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.
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:
<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.
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):
<?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:
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.
Simple, isn’t it? Go on, try it out for yourself and see!