FTP上传类
1 <?php 2 3 namespace ftp; 4 5 /*$config = array( 6 'host' => '127.0.0.1', //服务器 7 'port' => 21, //端口 8 'timeout' => 90, //超时时间 9 'username' => 'test', //用户名 10 'password' => 'test', //密码 11 'is_pasv' => true, 12 'domain' => 'img.test.com' , 13 ); 14 15 try { 16 $ftp = new Ftp($config); 17 $ftp->checkRootPath("/demo"); 18 $ftp->checkSavePath("abc"); 19 $ftp->upload('formfilename'); 20 var_dump($ftp->get_upload_info()); 21 } catch (FtpException $e) { 22 echo $e->getMessage(); 23 echo $e->getCode(); 24 }*/ 25 26 /** 27 * 错误异常异常代码编号 28 * 21000,链接登录FTP失败 29 * 21001,上传根目录不存在 30 * 21002,目录创建失败 31 * 21003,文件后缀不可上传 32 * 21004,上传失败 33 */ 34 class FtpException 35 { 36 } 37 38 class Ftp 39 { 40 /** 41 * 上传文件根目录 42 * @var string 43 */ 44 private $rootPath; 45 46 private $savepath = ''; 47 private $filename = ''; 48 49 /** 50 * FTP连接 51 * @var resource 52 */ 53 private $link; 54 // 文件命名规则 (md5,timestamp,sha1,time); 55 private $config = array( 56 'host' => '', //服务器 57 'port' => 21, //端口 58 'timeout' => 60, //超时时间 59 'username' => '', //用户名 60 'password' => '', //密码 61 'is_pasv' => false,//开启被动模式 62 'filename' => 'md5', 63 'allow_file_extension' => array('gif', 'png', 'jpg', 'jpeg', 'doc', 'excel'), 64 'domain' => 'img.test.com', 65 ); 66 67 /** 68 * 构造函数,用于设置上传根路径 69 * @param array $config FTP配置 70 */ 71 public function __construct($config) 72 { 73 /* 默认FTP配置 */ 74 $this->config = array_merge($this->config, $config); 75 76 /* 登录FTP服务器 */ 77 if (!$this->login()) { 78 throw new FtpException($this->error, 21000); 79 } 80 } 81 82 /** 83 * 检测上传根目录 84 * @param string $rootpath 根目录 85 * @return boolean true-检测通过,false-检测失败,抛出异常 86 */ 87 public function checkRootPath($rootpath) 88 { 89 /* 设置根目录 */ 90 $this->rootPath = @ftp_pwd($this->link) . ltrim($rootpath, '/'); 91 92 if (!@ftp_chdir($this->link, $this->rootPath)) { 93 throw new FtpException('上传根目录不存在!(' . $this->rootPath . ')', 21001); 94 } 95 return true; 96 } 97 98 /** 99 * 设置上传目录 100 * @param string $savepath 上传目录 101 * @return boolean 检测结果,true-通过,false-失败 102 */ 103 public function checkSavePath($savepath) 104 { 105 $this->savepath = $savepath = "/" . ltrim($savepath, '/'); 106 /* 检测并创建目录 */ 107 if (!$this->mkdir($savepath)) { 108 return false; 109 } else { 110 //TODO:检测目录是否可写 111 return true; 112 } 113 } 114 115 /** 116 * 保存指定文件 117 * @param array $file 保存的文件信息 118 * @param String $user_defined_filename 自定义文件名 119 * @return boolean 保存状态,true-成功,false-失败 120 */ 121 public function upload($file, $user_defined_filename = '') 122 { 123 if (empty($user_defined_filename)) { 124 $filename = $this->filenamerule(); 125 } else { 126 $filename = $user_defined_filename; 127 } 128 $uploadfile = $_FILES[$file]; 129 $file_ext = $this->_get_file_extension($uploadfile['name']); 130 $this->filename = $filename . "." . $file_ext; 131 $fileurl = $this->rootPath . $this->savepath . "/" . $this->filename; 132 /* 移动文件 */ 133 if (!ftp_put($this->link, $fileurl, $uploadfile['tmp_name'], FTP_BINARY)) { 134 throw new FtpException("{$filename}.{$file_ext} 上传失败", 21004); 135 } 136 return true; 137 } 138 139 public function get_upload_info() 140 { 141 @extract($this->config); 142 $result['domain_all_path'] = "//" . $domain . $this->rootPath . $this->savepath . "/" . $this->filename; 143 $result['all_path'] = $this->rootPath . $this->savepath . "/" . $this->filename; 144 $result['save_path_file'] = $this->savepath . "/" . $this->filename; 145 return $result; 146 } 147 148 private function filenamerule() 149 { 150 @extract($this->config); 151 switch ($filename) { 152 case 'sha1': 153 $filename = sha1(microtime()); 154 break; 155 case 'md5': 156 $filename = md5(microtime()); 157 break; 158 case 'time': 159 $filename = date('YmdHis'); 160 break; 161 case 'timestamp': 162 $filename = time(); 163 break; 164 } 165 return $filename; 166 } 167 168 private function _get_file_extension($file) 169 { 170 @extract($this->config); 171 $file_ext = pathinfo($file, PATHINFO_EXTENSION); 172 if (in_array($file_ext, $allow_file_extension)) { 173 return $file_ext; 174 } else { 175 throw new FtpException(" {$file_ext} 不可上传", 21003); 176 } 177 178 } 179 180 /** 181 * 创建目录 182 * @param string $savepath 要创建的目录 183 * @return boolean 创建状态,true-成功,false-失败 184 */ 185 public function mkdir($savepath) 186 { 187 $dir = $this->rootPath . $savepath; 188 if (@ftp_chdir($this->link, $dir)) { 189 return true; 190 } 191 192 if (@ftp_mkdir($this->link, $dir)) { 193 return true; 194 } elseif ($this->mkdir(dirname($savepath)) && @ftp_mkdir($this->link, $dir)) { 195 return true; 196 } else { 197 throw new FtpException("目录 {$savepath} 创建失败,可能设置写入权限和权限组不对!", 21002); 198 } 199 } 200 201 /** 202 * 登录到FTP服务器 203 * @return boolean true-登录成功,false-登录失败 204 */ 205 private function login() 206 { 207 @extract($this->config); 208 $this->link = @ftp_connect($host, $port, $timeout); 209 if ($this->link) { 210 if (@ftp_login($this->link, $username, $password)) { 211 if ($is_pasv) { 212 @ftp_pasv($this->link, true); 213 } 214 return true; 215 } else { 216 $this->error = "无法登录到FTP服务器:username - {$username}"; 217 } 218 } else { 219 $this->error = "无法连接到FTP服务器:{$host}"; 220 } 221 return false; 222 } 223 224 /** 225 * 析构方法,用于断开当前FTP连接 226 */ 227 public function __destruct() 228 { 229 @ftp_close($this->link); 230 } 231 232 }