PHP使用FTP转移文件夹以及子文件夹
项目需要通过php调用ftp转移一个文件夹以及所有的内容到另一台服务器,刚听到这个需求,简直是一头雾水,可是php就是php,ftp被默认支持了。于是谷歌了一下ftp的知识,看了看php的api,有了个不怎么完美的解决方案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | <?php class FtpUpload { /** * 保存所有的目录 * @var array */ private $dirs ; /** * 保存所有的文件 * @var array */ private $files ; /** * FTP地址 * @var string */ private $host ; /** * FTP用户名 * @var string */ private $usr ; /** * FTP密码 * @var unknown_type */ private $pwd ; /** * FTP链接 * @var resource */ private $conn_id ; /** * FTP保存上传文件的目标目录 * @var string */ private $dst ; /** * 构造 * @param string $host * @param string $usr * @param string $pwd * @param string $prjname * @param string $dst */ public function __construct( $host , $usr , $pwd , $prjname , $dst ) { //初始化 $this ->dirs = array (); $this ->files = array (); $this ->listDir ( $prjname ); $this ->host = $host ; $this ->usr = $usr ; $this ->pwd = $pwd ; $this ->dst = $dst ; //ftp连接 $this ->conn_id = ftp_connect ( $this ->host, 21 ) or die ( "Cannot connect to host" ); //ftp 登陆 ftp_login ( $this ->conn_id, $this ->usr, $this ->pwd ) or die ( "Cannot login" ); //开启passive模式 ftp_pasv ( $this ->conn_id, true ); } /** * 析构,释放FTP链接 */ public function __destruct() { ftp_close ( $this ->conn_id ); } /** * 递归遍历要上传的文件夹,并分类文件夹与文件,分别存入对应的array * @param unknown_type $dirname */ private function listDir( $dirname ) { $dir = opendir ( $dirname ); while ( ( $file = readdir ( $dir )) != false ) { if ( $file == "." || $file == ".." ) { continue ; } if ( is_dir ( $dirname . "/" . $file )) { array_push ( $this ->dirs, $dirname . "/" . $file ); $this ->listDir ( $dirname . "/" . $file ); } else { array_push ( $this ->files, $dirname . "/" . $file ); } } } /** * 上传文件 */ public function upload() { $this ->mkdirs (); //上传文件 foreach ( $this ->files as $f ) { //区分BINARY和ASCII,可以根据自己的需要微调 if ( $this ->endsWith ( $f , ".jpg" ) || $this ->endsWith ( $f , ".png" ) || $this ->endsWith ( $f , ".gif" ) || $this ->endsWith ( $f , ".exe" ) || $this ->endsWith ( $f , ".zip" ) || $this ->endsWith ( $f , ".swf" ) || $this ->endsWith ( $f , ".db" ) || $this ->endsWith ( $f , ".dll" )) $upload = ftp_put ( $this ->conn_id, $f , $f , FTP_BINARY ); else $upload = ftp_put ( $this ->conn_id, $f , $f , FTP_ASCII ); } } /** * 创建所需的文件夹 */ private function mkdirs() { ftp_mkdir ( $this ->conn_id, $this ->dst ); ftp_chdir ( $this ->conn_id, $this ->dst ); foreach ( $this ->dirs as $d ) { ftp_mkdir ( $this ->conn_id, $d ); } } /** * 判断目标字符串$haystack是否以指定字符串$needle结尾 * @param string $haystack * @param string $needle * @return boolean */ private function endsWith( $haystack , $needle ) { $length = strlen ( $needle ); if ( $length == 0) { return true; } return ( substr ( $haystack , - $length ) === $needle ); } } |
不知道为啥,在自己的ftp服务器运行良好,换做公司的服务器就悲剧的挂掉了,真心不解,难道是不同的ftp服务器支持的不一样?
于是出现了下面的版本。只是把传输文件放在了遍历文件夹的方法里面了,结果还是比较欣慰的。只是如果文件大了,速度很慢不说,还会出点问题。真正到服务器的文件比原先的文件少了那么一点点。迷茫了。有高手可以指点一下吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | <?php class FtpUpload { private $host ; private $usr ; private $pwd ; private $conn_id ; private $dst ; public function __construct( $host , $usr , $pwd , $prjname , $dst ) { $this ->host = $host ; $this ->usr = $usr ; $this ->pwd = $pwd ; $this ->dst = $dst ; //ftp连接 $this ->conn_id = ftp_connect ( $this ->host, 21 ) or die ( "Cannot connect to host" ); //ftp 登陆 ftp_login ( $this ->conn_id, $this ->usr, $this ->pwd ) or die ( "Cannot login" ); //开启passive模式 ftp_pasv ( $this ->conn_id, true ); $this ->listDir ( $prjname ); } public function __destruct() { ftp_close ( $this ->conn_id ); } private function listDir( $dirname ) { set_time_limit(0); //ftp_mkdir($this->conn_id, $dirname); $dir = opendir ( $dirname ); while ( ( $file = readdir ( $dir )) != false ) { if ( $file == "." || $file == ".." ) { continue ; } if ( is_dir ( $dirname . "/" . $file )) { array_push ( $this ->dirs, $dirname . "/" . $file ); echo $dirname . "/" . $file . "<br/>" ; echo "pwd /$dirname <br/>" ; ftp_chdir ( $this ->conn_id, "/$dirname" ); echo "mkdir $file <br/>" ; ftp_mkdir ( $this ->conn_id, $file ); $this ->listDir ( $dirname . "/" . $file ); } else { array_push ( $this ->files, $dirname . "/" . $file ); echo "pwd /$dirname <br/>" ; ftp_chdir ( $this ->conn_id, "/$dirname" ); echo "put $file <br/>" ; if ( $this ->endsWith ( $file , ".jpg" ) || $this ->endsWith ( $file , ".png" ) || $this ->endsWith ( $file , ".gif" ) || $this ->endsWith ( $file , ".exe" ) || $this ->endsWith ( $file , ".zip" ) || $this ->endsWith ( $file , ".swf" ) || $this ->endsWith ( $file , ".db" ) || $this ->endsWith ( $file , ".dll" )) $upload = ftp_put ( $this ->conn_id, $file , $dirname . "/" . $file , FTP_BINARY ); else $upload = ftp_put ( $this ->conn_id, $file , $dirname . "/" . $file , FTP_ASCII ); echo $dirname . "/" . $file . "<br/>" ; } } } private function endsWith( $haystack , $needle ) { $length = strlen ( $needle ); if ( $length == 0) { return true; } return ( substr ( $haystack , - $length ) === $needle ); } } |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· 官方的 MCP C# SDK:csharp-sdk
· 一款 .NET 开源、功能强大的远程连接管理工具,支持 RDP、VNC、SSH 等多种主流协议!
· 提示词工程师自白:我如何用一个技巧解放自己的生产力
· 一文搞懂MCP协议与Function Call的区别
· 如何不购买域名在云服务器上搭建HTTPS服务