用PHP控制FTP文件上传
利用PHP,你总是可以有多种方式来完成某个特定的任务。我们就拿文件上传举个例子。当然了,你可以按照传统的方式来使用HTTP文件上传,把文件直接传输到Web服务器磁盘上。你还可以用更加奇异的方式上传,用FTP协议两步就完成上传:从你的本地硬盘到Web服务器,然后再到FTP服务器。
PHP在本机同时支持FTP和HTTP上传,所以你可以根据自己应用程序的设计需要进行最佳的选择。使用PHP的FTP函数进行文件传输几乎与使用传统的FTP客户端相同——你会看到连函数的名字都和标准的FTP命令类似。
关于HTTP文件上传的文章已经多得满天飞了,这就是为什么本文有必要把注意力放在基于FTP的文件上传上了(但是在后面给出的例子中,两种方式你都会看到)。要注意的是,本教程假设你已经安装好了PHP/Apache,而且HTTP文件上传和FTP的函数都已经激活了。
本文可以从这里下载,所有的源代码都以单独的文本方式列出来了。
第一步:确信你拥有连接/上传到FTP服务器的权限
PHP的FTP函数需要客户端-服务器连接,所以你需要在进行文件上传之前登录到目标服务器上。你的第一项任务是确信你已经拥有了完成这项任务的信任书。这一步可能看起来是理所当然的,但是你会惊奇地发现有多少开发人员忘了这么做,结果后来浪费大量的时间来解决因此而出现的问题。
你可以通过使用命令行的FTP客户端登录到目标服务器上,以检查连接状况并尝试上传一个假文件(列表A):
列表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.
一旦确认有相关的访问权限,你就可以登录出来。
第二步:创建上传表单
然后,创建一个简单的HTML表单,向用户询问重要的参数——FTP服务器的访问信息、服务器上传的目录,以及完整的目录和上传文件的名字。下面这个例子就是这个表单的样式(列表B):
列表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>
在这里,<input type=file...>元素用来生成文件选择对话框,用户通过它来选择要被上传的文件。<form enctype=...>元素然后就把表单数据编码成为多个部分提交,这可以让PHP更容易地识别提交的文件组件。
第三步:创建PHP上传处理程序
一旦表单被提交给了Web服务器,下一步(也是最后一步)是使用PHP的FTP函数按照用户提供的访问信任书把它传输到目标服务器上。下面就是完成上述所有工作的脚本(upload.php),见列表C:
列表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");
?>
这看起来很复杂,但是事实上相当简单。下面就是实际发生的事情:
- 一旦表单被提交,在各种不同形式的输入字段里由用户提供的信任书被提取出来变成正常的PHP变量。关于上传文件的信息现在就可以通过PHP的专用数组$_FILES获得。
- $_FILESarray由多个子数组组成,每一个都用于一个上传文件。每个子数组的键都保存有关于相关文件的大小、MIME类型、原始名字和临时名字的信息。这些信息被move_uploaded_file()函数用来把文件从系统的临时目录传输到工作目录。你要记住更改$workDir的值,以反映你系统上的合法文件路径。
提示:在调用move_uploaded_file()函数之前检查上传文件的类型和大小以确保它满足应用程序的上传要求是一个好习惯。例如,如果应用程序要求文件必须以ZIP格式上传,那么在这一阶段就可以(从MIME类型)检查文件是否符合要求,以保证其他格式的文件被过滤掉。
- ftp_connect()和ftp_login()函数用来初始化到指定的FTP主机的连接,并使用提供的信任书登录进去。
- 如果登录成功,就使用ftp_put()函数把文件从工作目录上传到用户指定的远程目录里,并把它的名字改回原来的名字。要注意的是,向ftp_put()函数加入专用的FTP_BINARY参数是要指定文件以二进制(而非ASCII)模式传输。根据ftp_put()函数返回的结果代码,用户会看到错误或者成功的消息。
- ftp_close()函数被用来结束FTP会话,而unlink()函数用来完成收尾工作,删除第二步里创建的上传文件的本地副本。
很简单吧,不是吗?你自己试试看!
- 最新评论