1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
21: class FTPClient
22: {
23:
24:
25: const ASCII = FTP_ASCII;
26: const BINARY = FTP_BINARY;
27:
28: const TIMEOUT_SEC = FTP_TIMEOUT_SEC;
29: const AUTOSEEK = FTP_AUTOSEEK;
30:
31: 32: 33: 34:
35: private $connection = null;
36:
37: 38: 39: 40: 41:
42: public function FTPClient()
43: {
44: if ( !extension_loaded('ftp') ) {
45: throw new Exception('FTP extension is not loaded!');
46: }
47: }
48:
49: 50: 51: 52: 53: 54: 55: 56: 57: 58:
59: public function connect($host, $ssl = false, $port = 21, $timeout = 90)
60: {
61: if ($ssl) {
62: $this->connection = @ftp_ssl_connect($host, $port, $timeout);
63: } else {
64: $this->connection = @ftp_connect($host, $port, $timeout);
65: }
66:
67: if ($this->connection == null) {
68: throw new Exception('Unable to connect');
69: } else {
70: return $this;
71: }
72: }
73:
74: 75: 76: 77: 78: 79: 80: 81:
82: public function login($username = 'anonymous', $password = '')
83: {
84: $result = @ftp_login($this->connection, $username, $password);
85:
86: if ($result === false) {
87: throw new Exception('Login incorrect');
88: } else {
89: return $this;
90: }
91: }
92:
93: 94: 95: 96: 97:
98: public function close()
99: {
100: $result = @ftp_close($this->connection);
101:
102: if ($result === false) {
103: throw new Exception('Unable to close connection');
104: }
105: }
106:
107: 108: 109: 110: 111: 112: 113:
114: public function passive($passive = true)
115: {
116: $result = @ftp_pasv($this->connection, $passive);
117:
118: if ($result === false) {
119: throw new Exception('Unable to change passive mode');
120: }
121:
122: return $this;
123: }
124:
125: 126: 127: 128: 129:
130: public function changeDirectory($directory)
131: {
132: $result = @ftp_chdir($this->connection, $directory);
133:
134: if ($result === false) {
135: throw new Exception('Unable to change directory');
136: }
137:
138: return $this;
139: }
140:
141: 142: 143: 144: 145:
146: public function parentDirectory()
147: {
148: $result = @ftp_cdup($this->connection);
149:
150: if ($result === false) {
151: throw new Exception('Unable to get parent folder');
152: }
153:
154: return $this;
155: }
156:
157: 158: 159: 160: 161:
162: public function getDirectory()
163: {
164: $result = @ftp_pwd($this->connection);
165:
166: if ($result === false) {
167: throw new Exception('Unable to get directory name');
168: }
169:
170: return $result;
171: }
172:
173: 174: 175: 176: 177: 178: 179:
180: public function createDirectory($directory)
181: {
182: $result = @ftp_mkdir($this->connection, $directory);
183:
184: if ($result === false) {
185: throw new Exception('Unable to create directory');
186: }
187:
188: return $this;
189: }
190:
191: 192: 193: 194: 195: 196: 197:
198: public function removeDirectory($directory)
199: {
200: $result = @ftp_rmdir($this->connection, $directory);
201:
202: if ($result === false) {
203: throw new Exception('Unable to remove directory');
204: }
205:
206: return $this;
207: }
208:
209: 210: 211: 212: 213: 214: 215:
216: public function listDirectory($directory)
217: {
218: $result = @ftp_nlist($this->connection, $directory);
219: asort($result);
220:
221: if ($result === false) {
222: throw new Exception('Unable to list directory');
223: }
224:
225: return $result;
226: }
227:
228: 229: 230: 231: 232: 233: 234:
235: public function delete($path)
236: {
237: $result = @ftp_delete($this->connection, $path);
238:
239: if ($result === false) {
240: throw new Exception('Unable to get parent folder');
241: }
242:
243: return $this;
244: }
245:
246: 247: 248: 249: 250: 251: 252: 253: 254:
255: public function size($remoteFile)
256: {
257: $size = @ftp_size($this->connection, $remoteFile);
258:
259: if ($size === -1) {
260: throw new Exception('Unable to get file size');
261: }
262:
263: return $size;
264: }
265:
266: 267: 268: 269: 270: 271: 272: 273: 274:
275: public function modifiedTime($remoteFile, $format = null)
276: {
277: $time = ftp_mdtm($this->connection, $remoteFile);
278:
279: if ( $time !== -1 && $format !== null ) {
280: return date($format, $time);
281: } else {
282: return $time;
283: }
284: }
285:
286: 287: 288: 289: 290: 291: 292: 293:
294: public function rename($currentName, $newName)
295: {
296: $result = @ftp_rename($this->connection, $currentName, $newName);
297:
298: return $result;
299: }
300:
301: 302: 303: 304: 305: 306: 307: 308: 309: 310:
311: public function get($localFile, $remoteFile, $mode = FTPClient::ASCII, $resumePosision = 0)
312: {
313: $result = @ftp_get($this->connection, $localFile, $remoteFile, $mode, $resumePosision);
314:
315: if ($result === false) {
316: throw new Exception('Unable to get file');
317: }
318:
319: return $this;
320: }
321:
322: 323: 324: 325: 326: 327: 328: 329: 330: 331:
332: public function put($remoteFile, $localFile, $mode = FTPClient::ASCII, $startPosision = 0)
333: {
334: $result = @ftp_put($this->connection, $remoteFile, $localFile, $mode, $startPosision);
335:
336: if ($result === false) {
337: throw new Exception('Unable to put file');
338: }
339:
340: return $this;
341: }
342:
343: 344: 345: 346: 347: 348: 349: 350: 351: 352:
353: public function fget(resource $handle, $remoteFile, $mode = FTPClient::ASCII, $resumePosision = 0)
354: {
355: $result = @ftp_fget($this->connection, $handle, $remoteFile, $mode, $resumePosision);
356:
357: if ($result === false) {
358: throw new Exception('Unable to get file');
359: }
360:
361: return $this;
362: }
363:
364: 365: 366: 367: 368: 369: 370: 371: 372: 373:
374: public function fput($remoteFile, resource $handle, $mode = FTPClient::ASCII, $startPosision = 0)
375: {
376: $result = @ftp_fput($this->connection, $remoteFile, $handle, $mode, $startPosision);
377:
378: if ($result === false) {
379: throw new Exception('Unable to put file');
380: }
381:
382: return $this;
383: }
384:
385: 386: 387: 388: 389: 390: 391: 392:
393: public function getOption($option)
394: {
395: switch ($option) {
396: case FTPClient::TIMEOUT_SEC:
397: case FTPClient::AUTOSEEK:
398: $result = @ftp_get_option($this->connection, $option);
399:
400: return $result;
401: break;
402:
403: default:
404: throw new Exception('Unsupported option');
405: break;
406: }
407: }
408:
409: 410: 411: 412: 413: 414: 415: 416: 417:
418: public function setOption($option, $value)
419: {
420: switch ($option) {
421: case FTPClient::TIMEOUT_SEC:
422: if ($value <= 0) {
423: throw new Exception('Timeout value must be greater than zero');
424: }
425: break;
426:
427: case FTPClient::AUTOSEEK:
428: if (!is_bool($value)) {
429: throw new Exception('Autoseek value must be boolean');
430: }
431: break;
432:
433: default:
434: throw new Exception('Unsupported option');
435: break;
436: }
437:
438: return @ftp_set_option($this->connection, $option, $val);
439: }
440:
441: 442: 443: 444: 445: 446: 447:
448: public function allocate($filesize)
449: {
450: $result = @ftp_alloc($this->connection, $size);
451:
452: if ($result === false) {
453: throw new Exception('Unable to allocate');
454: }
455:
456: return $this;
457: }
458:
459: 460: 461: 462: 463: 464: 465: 466:
467: public function chmod($mode, $filename)
468: {
469: $result = @ftp_chmod($this->connection, $mode, $filename);
470:
471: if ($result === false) {
472: throw new Exception('Unable to change permissions');
473: }
474:
475: return $this;
476: }
477:
478: 479: 480: 481: 482: 483: 484:
485: public function exec($command)
486: {
487: $result = @ftp_exec($this->connection, $command);
488:
489: if ($result === false) {
490: throw new Exception('Unable to exec command');
491: }
492:
493: return $this;
494: }
495:
496: 497: 498:
499: public function __destruct()
500: {
501: $this->close();
502: }
503: }