支持多文件、多格式远程上传的FTP实战案例

来源:互联网 发布:navicat for mysql破解 编辑:程序博客网 时间:2024/06/04 08:04

我们平时在开发项目时,经常会做的上传文件的功能,比如上传音视频、图片、word、pdf文件等等,但是我们一般是上传到跟我们程序一起的服务上,但是如果我们有额外单独的文件服务器,想把我们上传上来的文件放到远程的文件服务器上,这时可能我们平时的上传文件功能已经不能满足我们现在的要求了,需要用到FTP的功能了。

说到FTP,我们就需要先搭建FTP服务器,这里推荐一款很好用的FTP服务器软件Serv-U(Serv-U是Windows平台和Linux平台的安全FTP服务器(FTPS, SFTP, HTTPS),是一个优秀的、安全的文件管理、文件传输和文件共享的解决方案。),先去它的官网现在相对应的版本,并进行安装。网址为:http://www.serv-u.com.cn。PS:这软件是收费的,但是有15天的试用期哦。

安装完后,双击图标后,显示控制台,如图所示


第1步,点击左上角“导航”旁边的“+”,就会弹出域向导的界面,如图所示


第2步,直接默认,点击下一步,如下图所示:


第3步,填写网址和建立文件分享仓库,截图如下:


第4步,选择协议,一般直接默认,然后下一步,如图所示:


第5步,IP监听,一般写下IPv4,如图所示:


6、第6步,加密,根据需要选择,否则直接用默认值,然后点击“完成”,如图所示:


然后看到控制台的左侧边栏的“域”里面多了个域名(IP),如图所示:

,现在说明已经设置FTP服务器的相关设置了。

接下来,废话少说,直接上代码:

情景一,在自己本机做测试

index.html

<!DOCTYPE html><html lang="en">    <head>        <meta charset="utf-8">        <title>支持多文件、多格式上传的FTP案例</title>    </head>    <body>        <form action="uploadfile.php" method="post" enctype="multipart/form-data">             <input type="file" name="ftpfile[]"/><br />            <input type="file" name="ftpfile[]"/><br />              <input type="file" name="ftpfile[]"/><br />              <input type="file" name="ftpfile[]"/><br />              <input type="file" name="ftpfile[]"/><br />              <input type="file" name="ftpfile[]"/><br />              <input type="file" name="ftpfile[]"/><br />              <input type="file" name="ftpfile[]"/><br />              <input type="file" name="ftpfile[]"/><br />              <input type="submit" name="submit" value="提交" />         </form>     </body></html>

uploadfile.php

<?php    header('Content-type:text/html;charset=utf-8');//设置编码    $ftp_server = "127.0.0.1";//FTP服务器    $ftp_user_name = "zps";//登录名    $ftp_user_pass = "php100";//登录密码    //建立一个新的 FTP 连接    $conn_id = ftp_connect($ftp_server) or die("不能连接到FTP服务器:$ftp_server。");    //bool ftp_login ( resource $ftp_stream , string $username , string $password )    //使用用户名和密码登录入给定的FTP连接。    $login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);    $ftp_files = $_FILES['ftpfile'];//上传的文件    if (is_array($ftp_files['tmp_name'])) {        foreach ($ftp_files['tmp_name'] as $key => $value) {            if($ftp_files['error'][$key] == UPLOAD_ERR_OK){                if (is_uploaded_file($value)){                    list($name,$ext) = explode('.',$ftp_files['name'][$key]);                    $local_file = $value;                    $remote_file = '/uploads/'.date('YmdHis').rand(00,99).'.'.$ext; // 注意:这里的"/test"指的是ftp根目录下的test文件夹,而非系统跟目录下的test                    //bool ftp_put (resource $ftp_stream,string $remote_file,string $local_file,int $mode[, int $startpos ])                    //ftp_put() 函数用来上传由local_file参数指定的文件到FTP 服务器,上传后的位置由remote_file指定。传输模式参数                    //此处需要用FTP_BINARY(二进制模式),用FTP_ASCII(文本模式)时,图片能上传但无法显示                    if (!ftp_put($conn_id, $remote_file, $local_file, FTP_BINARY)) {                        echo "文件移动失败";                        exit;                    }                }else{                    echo '文件不是上传的文件!';                }            }        }        echo "文件移动成功!";    }else{        echo '上传出错!';    }    // 关闭一个 FTP 连接,关闭给出的连接标识符并释放资源。    ftp_close($conn_id);
待上传的文件截图:


表单页面截图:


上传成功后,提示:


查看FTP根目录,发现文件已经传上来了:


到此,说明我们在本机测试成功。接下来我们测试下远程服务器:

情景二,本机上传到远程服务器

index.html的代码还是不变,

后台的remote_uploadfile.php代码:

<?php    header('Content-type:text/html;charset=utf-8');//设置编码    $ftp_server = "1*********6";//远程FTP服务器    $ftp_port = "5056";//远程FTP服务器端口号    $ftp_user_name = "s******c";//远程FTP登录名    $ftp_user_pass = "sh*****456";//远程FTP登录密码    //建立一个新的 FTP 连接    $conn_id = ftp_connect($ftp_server,$ftp_port) or die("不能连接到FTP服务器:$ftp_server");    //bool ftp_login ( resource $ftp_stream , string $username , string $password )    //使用用户名和密码登录入给定的FTP连接。    $login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);    ftp_pasv($conn_id, true);//开启被动模式,如果第二个参数为true,打开的是被动传输模式,否则关闭被动传输模式。否则会报:“Warning: ftp_put(): Opening data channel for file transfer.”的错误    $ftp_files = $_FILES['ftpfile'];//上传的文件    if (is_array($ftp_files['tmp_name'])) {        // var_dump($ftp_files);exit();        foreach ($ftp_files['tmp_name'] as $key => $value) {            if($ftp_files['error'][$key] == UPLOAD_ERR_OK){                if (is_uploaded_file($value)){                    list($name,$ext) = explode('.',$ftp_files['name'][$key]);                    $local_file = $value;                    $remote_file = '/ftpfile/'.date('YmdHis').rand(10,99).'.'.$ext; // 注意:这里的"/ftpfile"指的是ftp根目录下的test文件夹,而非系统跟目录下的test                    //bool ftp_put (resource $ftp_stream,string $remote_file,string $local_file,int $mode[, int $startpos ])                    //ftp_put() 函数用来上传由local_file参数指定的文件到FTP 服务器,上传后的位置由remote_file指定。传输模式参数                    //此处需要用FTP_BINARY(二进制模式),用FTP_ASCII(文本模式)时,图片能上传但无法显示                    if (!ftp_put($conn_id, $remote_file, $local_file, FTP_BINARY)) {                        echo "文件移动失败";                        exit;                    }                }else{                    echo '文件不是上传的文件!';                }            }        }        echo "文件移动成功!";    }else{        echo '上传出错!';    }    // 关闭一个 FTP 连接,关闭给出的连接标识符并释放资源。    ftp_close($conn_id);
这里我们说下连接FTP服务器的两种工作模式:

主动模式的ftp是这样的;客户端从一个任意的非特权端口连接到ftp服务器的命令端口(21),然后客户端开始监听端口,并发送ftp命令到ftp服务器。服务器从它自己的数据端口20连接到客户端指定的数据端口。
被动模式ftp中,命令连接和数据连接都由客户端,这样就可以解决从服务器到客户端的数据端口的入方向连接被防火墙过滤掉的问题。当开启一个 FTP连接时,客户端打开两个任意的非特权本地端口。第一个端口连接服务器的21端口,但与主动方式的FTP不同,客户端不会提交PORT命令并允许服务器来回连它的数据端口,而是提交 PASV命令。这样做的结果是服务器会开启一个任意的非特权端口,并发送PORT P命令给客户端。然后客户端发起从本地端口到服务器的端口的连接用来传送数据。

然后用第三方工具LeapFTP查看,发现已成功上传文件了,如图所示:


最后说下,在用ftp_put方法时,第四个参数传送模式,需要用FTP_BINARY(二进制模式),如果用FTP_ASCII(文本模式)时,图片能上传但无法显示,如图所示: