by vikram vaswani

melonfire

november 07, 2000

   我们是一群php的忠实fans,我们因各种不同的原因使用它-web站点的开发,画图,数据库的联接等 -我们发现,它非常的友好,强大而且易于使用……

你可能已经看到php是怎样被用于创建gif和jpeg图像,从数据库中动态的获取信息等等,但这只是冰山的一角—最新版本的php拥有着强大的文件传输功能。

在这篇教程里,我将向你展示ftp怎样通过http和ftp联接来传输文件,同时也会有一些简单的程序代码,跟我来吧!

首先,你应该知道php是通过http和ftp联接来传输文件的。通过http上传文件早在php3中就已经出现,现在,新的ftp函数已经在新的php版本中出现了!

开始之前,你需要确信你的php支持ftp,你可以通过以下代码查知:

——————————————————————————–

<?

phpinfo();

?>

——————————————————————————–

检查输出结果,有一“additional modules”区,这里列示了你的php支持的模块;如果你没发现ftp模块,你最好重新安装php,并添加ftp支持!

先让我们来看看一个典型的ftp任务是怎样完成的吧!

——————————————————————————–

$ ftp ftp.server.com

connected to ftp.server.com

220 server.com ftp server ready.

name (server:john): john

331 password required for john.

password:

230 user john logged in.

remote system type is unix.

using binary mode to transfer files.

ftp> ls

200 port command successful.

150 opening ascii mode data connection for /bin/ls.

drwxr-xr-x  5 john   users        3072 nov  2 11:03 .

drwxr-xr-x  88 root     root         2048 nov  1 23:26 ..

drwxr–r–   2 john   users        1024 oct  5 13:26 bin

drwx–x–x   8 john   users        1024 nov  2 10:59 public_html

drwxr–r–   4 john   users        1024 nov  2 11:26 tmp

-rw-r–r–   1 john   users     2941465 oct  9 17:21 data.zip

226 transfer complete.

ftp> bin

200 type set to i.

ftp> get data.zip

local: data.zip remote: data.zip

200 port command successful.

150 opening binary mode data connection for data.zip(2941465 bytes).

226 transfer complete.

ftp> bye

221 goodbye.

——————————————————————————–

你可以看到,进程明显被分为几段:联接(与ftp服务器建立联接)、验证(确定用户是否有权力进入系统)、传输(这里包括列目录,上传或下载文件)、取消联接。

使用php来ftp的步骤

建立一个php的ftp联接必须遵守以下基本步骤:打开一个联接 – 发出认证信息 – 使用php函数操纵目录和传输文件。

以下具体实现:

——————————————————————————–

<?

// 联接ftp服务器

$conn = ftp_connect(“ftp.server.com”);

// 使用username和password登录

ftp_login($conn, “john”, “doe”);

// 获取远端系统类型

ftp_systype($conn);

// 列示文件

$filelist = ftp_nlist($conn, “.”);

// 下载文件

ftp_get($conn, “data.zip”, “data.zip”, ftp_binary);

// 关闭联接

ftp_quit($conn);

?>

——————————————————————————–

让我们一步步的来:

为了初结化一个ftp联接,php提供了ftp_connect()这个函数,它使用主机名称和端口作为参数。在上面的例子里,主机名字为“ftp.server.com”;如果端口没指定,php将会使用“21”作为缺省端口来建立联接。

联接成功后ftp_connect()传回一个handle句柄;这个handle将被以后使用的ftp函数使用。

——————————————————————————–

<?

// connect to ftp server

$conn = ftp_connect(“ftp.server.com”);

?>

——————————————————————————–

一旦建立联接,使用ftp_login()发送一个用户名称和用户密码。你可以看到,这个函数ftp_login()使用了ftp_connect()函数传来的handle,以确定用户名和密码能被提交到正确的服务器。

——————————————————————————–

<?

// log in with username and password

ftp_login($conn, “john”, “doe”);

?>

——————————————————————————–

这时,你就能够做你想做的事情了,具体在下一部分讲:

做完你想做的事后,千万要记住使用ftp_quit()函数关闭你的ftp联接

——————————————————————————–

<?

// close connection

ftp_quit($conn);

?>

——————————————————————————–

登录了ftp服务器,php提供了一些函数,它们能获取一些关于系统和文件以及目录的信息。

ftp_pwd()

如果你想知道你当前所在的目录时,你就要用到这个函数了。

——————————————————————————–

<?

// get current location

$here = ftp_pwd($conn);

?>

——————————————————————————–

万一你需要知道服务器端运行的是什么系统呢?

ftp_systype()正好提供给你这方面的信息。

——————————————————————————–

<?

// get system type

$server_os = ftp_systype($conn);

?>

——————————————————————————–

关于被动模式(pasv)的开关,php也提供了这样一个函数,它能打开或关闭pasv(1表示开)

——————————————————————————–

<?

// turn pasv on

ftp_pasv($conn, 1);

?>

——————————————————————————–

现在,你已经知道你在“哪里”和“谁”跟你在一起了吧,现在我们开始在目录中逛逛–实现这一功能的是ftp_chdir()函数,它接受一个目录名作为参数。

——————————————————————————–

<?

// change directory to “public_html”

ftp_chdir($conn, “public_html”);

?>

——————————————————————————–

如果你想回到你刚才所在的目录(父目录),ftp_cdup()能帮你实现你的愿望,这个函数能回到上一级目录。

——————————————————————————–

<?

// go up one level in the directory tree

ftp_cdup($conn);

?>

——————————————————————————–

你也能够建立或移动一个目录,这要使用ftp_mkdir()和ftp_rmdir()函数;注意:ftp_mkdir()建立成功的话,就会返回新建立的目录名。

——————————————————————————–

<?

// make the directory “test”

ftp_mkdir($conn, “test”);

// remove the directory “test”

ftp_rmdir($conn, “test”);

?>

——————————————————————————–

建立一个ftp的目录通常是传输文件— 那么就让我们开始吧!

先是上传文件,ftp_put()函数能很好的胜任这一职责,它需要你指定一个本地文件名,上传后的文件名以及传输的类型。比方说:如果你想上传“abc.txt”这个文件,上传后命名为“xyz.txt”,命令应该是这样:

——————————————————————————–

<?

// upload

ftp_put($conn, “xyz.txt”, “abc.txt”, ftp_ascii);

?>

——————————————————————————–

下载文件:

php所提供的函数是ftp_get(),它也需要一个服务器上文件名,下载后的文件名,以及传输类型作为参数,例如:服务器端文件为his.zip,你想下载至本地机,并命名为hers.zip,命令如下:

——————————————————————————–

<?

// download

ftp_get($conn, “hers.zip”, “his.zip”, ftp_binary);

?>

——————————————————————————–

php定义了两种模式作为传输模式 ftp_binary 和 ftp_ascii ,这两种模式的使用请看上两例,至于其详细解释,本文也不多说了,具体请参看相关书籍。

我该怎样列示文件呢?(用dir? :) )

php提供两种方法:一种是简单列示文件名和目录,另一种就是详细的列示文件的大小,权限,创立时间等信息。

第一种使用ftp_nlist()函数,第二种用ftp_rawlist().两种函数都需要一个目录名做为参数,都返回目录列做为一个数组,数组的每一个元素相当于列表的一行。

——————————————————————————–

<?

// obtain file listing

$filelist = ftp_nlist($conn, “.”);

?>

——————————————————————————–

你一定想知道文件的大小吧!别急,这里有一个非常容易的函数ftp_size(),它返回你所指定的文件的大小,使用bites作为单位。要指出的是,如果它返回的是 “-1”的话,意味着这是一个目录,在随后的例子中,你将会看到这一功能的应用。

——————————————————————————–

<?

// obtain file size of file “data.zip”

$filelist = ftp_size($conn, “data.zip”);

?>

现在,我们已经接触了php关于ftp的大量函数,但这仅仅只是函数,离我们的目标还远远不够,要显示出这些函数的真正力量,我们应该建立一个程序,这个程序能以web方式上传,下载文件—这就是我们将要做的!

在我们进入代码前,我想要告诉大家的是,这个例子仅仅只是为了向大家解释php的各种ftp函数的使用,很多方面还不够完善,比如说,错误分析等,至于你想应用到你自己的程序中,你应该进行一些修改!

程序包括以下几个文件:

index.html – 登录文件

actions.php – 程序必需的ftp代码

include.php – 程序主界面,它显示文件列表和控制按钮。

让我们从 “index.html”开始吧:

——————————————————————————–

<table border=0 align=center>

<form action=”actions.php” method=post>

<input type=hidden name=action value=cwd>

<tr>

<td>

server

</td>

<td>

<input type=text name=server>

</td>

</tr>

<tr>

<td>

user

</td>

<td>

<input type=text name=username>

</td>

</tr>

<tr>

<td>

password

</td>

<td>

<input type=password name=password>

</td>

</tr>

<tr>

<td colspan=2 align=center>

<input type=”submit” value=”beam me up, scotty!”>

</td>

</tr>

</form>

</table>

——————————————————————————–

这是一个登录表单,有一个服务器名称、用户名、密码,输入框。输入的变量将会被存到$server, $username 和 $password 变量中,表单提交后,调用actions.php,它将初始化ftp联接。

注意那个“hidden” 它传给action.php一个变量$action ,值为cwd。

这是action.php文件的源码:

——————————————————————————–

<html>

<head>

<basefont face=arial>

</head>

<body>

<!– the include.php interface will be inserted into this page –>

<?

//检查表单传来的数据,不全则报错,要想程序完善的话,这里应该有更全的输入检测功能

if (!$server

!$username

!$password)

{

echo “提交数据不全!”;

}

else

{

// keep reading

}

?>

</body>

</html>

——————————————————————————–

接下来是变量 “actions”. 程序允许以下的action:

“action=cwd”

改变工作目录

“action=delete”

删除指定文件

“action=download”

下载指定文件

“action=upload”

上传指定文件

如果你仔细检查文件include.php,在里面包括一个html界面,你将会看到,它包括许多表单,每一个指向一个特定的功能,每一个表单包含一个field(通常隐藏) ,当表单提交,相应的功能将被执行。

例如:按下“删除”,”action=delete”就被传送给”actions.php”

为了操作这四个功能,actions.php中代码如下:

——————————————————————————–

<?

// action: 改变目录

if ($action == “cwd”)

{

// 具体代码

}

// action: 删除文件

else if ($action == “delete”)

{

// 具体代码

}

// action: 下载文件

else if ($action == “download”)

{

// 具体代码

}

// action: 上传文件

else if ($action == “upload”)

{

// 具体代码

}

?>

——————————————————————————–

以上的具体代码将会实现指定的功能,并退出循环,它们都包含以下步骤:

——————————————————————————–

通过定制的函数联接并登录ftp服务器

connect();

转向适当的目录

执行选择的功能

刷新列表,以察看改变的结果

通过include(“include.php”),显示文件列表和控制按钮

关闭联接

——————————————————————————–

注意:

以下功能支持多文件操作- 即 “action=delete” 和 “action=download” 它们使用for循环来实现。

变量$cdir 和 $here 将在每一阶段实时更新。