FtpHelper.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: 中闽 < 1464674022@qq.com >
  5. * Date: 2020/7/23
  6. * Time: 17:56
  7. */
  8. namespace network;
  9. use file\PathHelper;
  10. use think\Exception;
  11. class FtpHelper
  12. {
  13. private $f_conn;
  14. /**
  15. * @param $host
  16. * @param $user
  17. * @param $pwd
  18. * @param int $port
  19. * @return resource
  20. * @throws Exception
  21. */
  22. public function connect($host, $user, $pwd, $port = 21)
  23. {
  24. if (!empty($this->f_conn)) {
  25. return $this->f_conn;
  26. }
  27. // 连接ftp
  28. $f_conn = ftp_connect($host, $port);
  29. if (!$f_conn) {
  30. throw new Exception("ftp connect fail");
  31. }
  32. // 登录ftp
  33. $f_login = ftp_login($f_conn, $user, $pwd);
  34. if (!$f_login) {
  35. throw new Exception("ftp login fail");
  36. }
  37. ftp_set_option($f_conn, FTP_USEPASVADDRESS, false); //考虑到不同ftp环境,需要加此参数,否则可能会出现连接超时错误
  38. ftp_pasv($f_conn, TRUE);//被动模式打开
  39. $this->f_conn = $f_conn;
  40. return $f_conn;
  41. }
  42. /**
  43. * 获取当前所在的ftp目录
  44. * @return string
  45. * @throws Exception
  46. */
  47. public function pwd()
  48. {
  49. $in_dir = ftp_pwd($this->f_conn);
  50. if (!$in_dir) {
  51. throw new Exception("ftp pwd fail");
  52. }
  53. return $in_dir;
  54. }
  55. /**
  56. * 获取当前所在ftp目录下包含的目录与文件的路径列表
  57. * @param null $path
  58. * @return array
  59. */
  60. public function ls($path = null)
  61. {
  62. if (empty($path)) {
  63. $path = ftp_pwd($this->f_conn);
  64. }
  65. //有时候末尾没有/会直接返回false,但是加上会读取不出文件夹
  66. return ftp_nlist($this->f_conn, $path);
  67. }
  68. /**
  69. * 详细列表
  70. * drw-rw-rw- 1 ftp ftp 0 Feb 07 16:01 course
  71. * @param null $path
  72. * @return array
  73. */
  74. public function ll($path = null)
  75. {
  76. if (empty($path)) {
  77. $path = ftp_pwd($this->f_conn);
  78. }
  79. //有时候末尾没有/会读取不出文件夹
  80. return ftp_rawlist($this->f_conn, appendEndDS($path, '/'));
  81. }
  82. /**
  83. * 如不存在则进行创建,多级目录需要一层一层创建
  84. * @param $dir_name string 相对根目录的路径
  85. * @return bool
  86. */
  87. public function mkdir($dir_name)
  88. {
  89. if (empty($dir_name)) {
  90. return false;
  91. }
  92. $dir_name = replaceUrlDS($dir_name);
  93. $dir_name = deleteStartDS($dir_name, '/');
  94. $root_dir = $this->pwd();
  95. //要新建的远程目录
  96. $new_dir = ($root_dir == '/') ? ("/" . $dir_name) : ("$root_dir/$dir_name");
  97. //远程父目录下列表
  98. $new_dir_parent = PathHelper::getParentDir($new_dir, '/');
  99. $exist_dirs = $this->ls($new_dir_parent);
  100. //检查目录下是否已存在同名文件夹
  101. if (!$exist_dirs || !in_array($new_dir, $exist_dirs)) {
  102. return @ftp_mkdir($this->f_conn, $dir_name);
  103. }
  104. return false;
  105. }
  106. /**
  107. * 切换目录
  108. * @param $dir_name
  109. * @return bool
  110. */
  111. public function cd($dir_name)
  112. {
  113. return ftp_chdir($this->f_conn, $dir_name);
  114. }
  115. /**
  116. * 进行文件上传,会覆盖同名文件
  117. * @param $remote_file [上传后的文件名.带扩展名]
  118. * @param $local_file [文件物理路径]
  119. * @return bool
  120. */
  121. public function upload($remote_file, $local_file)
  122. {
  123. $remote_file = replaceUrlDS($remote_file);
  124. $remote_file = deleteStartDS($remote_file, '/');
  125. return ftp_put($this->f_conn, $remote_file, $local_file, FTP_BINARY);
  126. }
  127. /**
  128. * 进行ftp下载
  129. * @param $local_file [本地保存路径]
  130. * @param $remote_file [ftp的相对路径,相对于$ftp->pwd()的路径]
  131. * @return bool
  132. */
  133. public function download($local_file, $remote_file)
  134. {
  135. return ftp_get($this->f_conn, $local_file, $remote_file, FTP_BINARY);
  136. }
  137. /**
  138. * @param $remote_file
  139. * @return bool
  140. */
  141. public function delete($remote_file)
  142. {
  143. return ftp_delete($this->f_conn, $remote_file);
  144. }
  145. //测试
  146. public function test()
  147. {
  148. // $root_path = \app\common\model\FileManageModel::getRootDir();
  149. // $ftp = new FtpHelper();
  150. // $ftp->connect('ftp.test.com', 'test', '123123');
  151. // var_dump($ftp->pwd());//显示当前路径
  152. // $ftp->upload('test.html', $root_path . DS . 'test.html');//上传
  153. // var_export($ftp->ls());//显示文件列表
  154. // $ftp->download('./test.html', '/test_dir/test2.html');//下载
  155. //
  156. // $ftp->mkdir('test_dir/test_dir2');//新建多级目录,上级目录必须存在,文件分隔符linux上不可使用\,windows没测试过
  157. // $ftp->cd('test_dir');//切换目录
  158. // $ftp->mkdir('test_dir3');//新建目录/test/test_dir3
  159. // $ftp->mkdir('/test_dir4');//新建目录/test_dir4
  160. // var_dump($ftp->pwd());//显示当前路径
  161. // $ftp->upload('test2.html', $root_path . DS . 'test2.html');//上传
  162. // var_export($ftp->ls());//显示文件列表
  163. // $ftp->download($root_path . DS . 'down_test2.html', $ftp->pwd() . '/test2.html');//这里$remote_file等同于'./test2.html'
  164. //测试指定路径上传
  165. // $ftp->upload('/mkdir.html', $root_path . DS . 'test.html');
  166. // $ftp->upload('/test_dir/mkdir.html', $root_path . DS . 'test.html');
  167. // $ftp->upload('/test_dir2/mkdir.html', $root_path . DS . 'test.html');//如果test_dir2不存在,会报错
  168. }
  169. }