PHP ftp类实现远程附件上传例子

多服务器数据同步并且实时数据处理功能想了很多没找到合适的工具了,今天想了可以使用ftp+rsync工具来实现,下文重点介绍的是php ftp上传类的实现了.

现在很多地方需要用ftp类操作另外的网站服务器,上传图片之类的,现在贴一个php ftp类给大家.

  1. class Ftp {
  2. //FTP 连接资源
  3. private $link;
  4. //FTP连接时间
  5. public $link_time;
  6. //错误代码
  7. private $err_code = 0;
  8. //传送模式{文本模式:FTP_ASCII, 二进制模式:FTP_BINARY}
  9. public $mode = FTP_BINARY;
  10. /**
  11. * 连接FTP服务器
  12. * @param string $host    服务器地址
  13. * @param string $username   用户名
  14. * @param string $password   密码
  15. * @param integer $port     服务器端口,默认值为21
  16. * @param boolean $pasv 是否开启被动模式
  17. * @param boolean $ssl      是否使用SSL连接
  18. * @param integer $timeout 超时时间 
  19. */
  20. public function connect($host, $username = '', $password = '', $port = '21', $pasv = false, $ssl = false, $timeout = 30) {
  21. $start = time();
  22. if ($ssl) {
  23. if (!$this->link = @ftp_ssl_connect($host, $port, $timeout)) {
  24. $this->err_code = 1;
  25. return false;
  26. }
  27. } else {
  28. if (!$this->link = @ftp_connect($host, $port, $timeout)) {
  29. $this->err_code = 1;
  30. return false;
  31. }
  32. }
  33. if (@ftp_login($this->link, $username, $password)) {
  34. if ($pasv)
  35. ftp_pasv($this->link, true);
  36. $this->link_time = time() - $start;
  37. return true;
  38. } else {
  39. $this->err_code = 1;
  40. return false;
  41. }
  42. register_shutdown_function(array(&$this, 'close'));
  43. }
  44. /**
  45. * 创建文件夹
  46. * @param string $dirname 目录名,
  47. */
  48. public function mkdir($dirname) {
  49. if (!$this->link) {
  50. $this->err_code = 2;
  51. return false;
  52. }
  53. $dirname = $this->ck_dirname($dirname);
  54. $nowdir = '/';
  55. foreach ($dirname as $v) {
  56. if ($v && !$this->chdir($nowdir . $v)) {
  57. if ($nowdir)
  58. $this->chdir($nowdir);
  59. @ftp_mkdir($this->link, $v);
  60. }
  61. if ($v)
  62. $nowdir .= $v . '/';
  63. }
  64. return true;
  65. }
  66. /**
  67. * 上传文件
  68. * @param string $remote 远程存放地址
  69. * @param string $local 本地存放地址
  70. */
  71. public function put($remote, $local) {
  72. if (!$this->link) {
  73. $this->err_code = 2;
  74. return false;
  75. }
  76. $dirname = pathinfo($remote, PATHINFO_DIRNAME);
  77. if (!$this->chdir($dirname)) {
  78. $this->mkdir($dirname);
  79. }
  80. if (@ftp_put($this->link, $remote, $local, $this->mode)) {
  81. return true;
  82. } else {
  83. $this->err_code = 7;
  84. return false;
  85. }
  86. }
  87. /**
  88. * 删除文件夹
  89. * @param string $dirname 目录地址
  90. * @param boolean $enforce 强制删除
  91. */
  92. public function rmdir($dirname, $enforce = false) {
  93. if (!$this->link) {
  94. $this->err_code = 2;
  95. return false;
  96. }
  97. $list = $this->nlist($dirname);
  98. if ($list && $enforce) {
  99. $this->chdir($dirname);
  100. foreach ($list as $v) {
  101. $this->f_delete($v);
  102. }
  103. } elseif ($list && !$enforce) {
  104. $this->err_code = 3;
  105. return false;
  106. }
  107. @ftp_rmdir($this->link, $dirname);
  108. return true;
  109. }
  110. /**
  111. * 删除指定文件
  112. * @param string $filename 文件名
  113. */
  114. public function f_delete($filename) {
  115. if (!$this->link) {
  116. $this->err_code = 2;
  117. return false;
  118. }
  119. if (@ftp_delete($this->link, $filename)) {
  120. return true;
  121. } else {
  122. $this->err_code = 4;
  123. return false;
  124. }
  125. }
  126. /**
  127. * 返回给定目录的文件列表
  128. * @param string $dirname 目录地址
  129. * @return array 文件列表数据
  130. */
  131. public function nlist($dirname) {
  132. if (!$this->link) {
  133. $this->err_code = 2;
  134. return false;
  135. } //开源软件:phpfensi.com
  136. if ($list = @ftp_nlist($this->link, $dirname)) {
  137. return $list;
  138. } else {
  139. $this->err_code = 5;
  140. return false;
  141. }
  142. }
  143. /**
  144. * 在 FTP 服务器上改变当前目录
  145. * @param string $dirname 修改服务器上当前目录
  146. */
  147. public function chdir($dirname) {
  148. if (!$this->link) {
  149. $this->err_code = 2;
  150. return false;
  151. }
  152. if (@ftp_chdir($this->link, $dirname)) {
  153. return true;
  154. } else {
  155. $this->err_code = 6;
  156. return false;
  157. }
  158. }
  159. /**
  160. * 获取错误信息
  161. */
  162. public function get_error() {
  163. if (!$this->err_code)
  164. return false;
  165. $err_msg = array(
  166. '1' => 'Server can not connect',
  167. '2' => 'Not connect to server',
  168. '3' => 'Can not delete non-empty folder',
  169. '4' => 'Can not delete file',
  170. '5' => 'Can not get file list',
  171. '6' => 'Can not change the current directory on the server',
  172. '7' => 'Can not upload files'
  173. );
  174. return $err_msg[$this->err_code];
  175. }
  176. /**
  177. * 检测目录名
  178. * @param string $url 目录
  179. * @return 由 / 分开的返回数组
  180. */
  181. private function ck_dirname($url) {
  182. $url = str_replace('', '/', $url);
  183. $urls = explode('/', $url);
  184. return $urls;
  185. }
  186. /**
  187. * 关闭FTP连接
  188. */
  189. public function close() {
  190. return @ftp_close($this->link);
  191. }
  192. }

先来说说远程附件上传的大致流程:

用户选择文件上传提交到服务器->服务器接收到文件->服务器一些安全检测完成通过FTP功能上传到相应FTP服务器.

我说的只是一个大概过程,不是很标准,明白个意思即可啦!~

这个类大致使用方法:首先通过$ftps->connect($host,$username,$password,$post,$pasv,$ssl,$timeout);进行FTP服务器连接.

通过具体的函数进行FTP的操作,$ftps->mkdir() 创建目录,可以创建多级目录以“/abc/def/higk”的形式进行多级目录的创建.

$ftps->put()上传文件

$ftps->rmdir()删除目录

$ftps->f_delete()删除文件

$ftps->nlist()列出指定目录的文件

$ftps->chdir()变更当前文件夹

$ftps->get_error()获取错误信息

rsync工具同步

这里只介绍原理了rsync同步在windows中只能使用windows计划任务来实现了,我们可以定义为1小时同步一次,这样可以保证同步失败文件再次同步一下,当然在ftp上传类时可以做一个错误日志记录,上传失败之后记录在一个日志文件,然后我们可以手工点击再实现一次上传了,这样台保证万无一失了.