類設計目標
- 封裝 FTP 核心操作:連接、登錄、被動模式、目錄切換、創建、上傳、下載、重命名、刪除、權限修改、列表獲取
- 自動判斷傳輸模式(ASCII/BINARY)
- 支持遞歸刪除目錄
- 完善的錯誤日誌記錄
- 兼容 CodeIgniter 風格配置
核心類 Ftp 結構
class Ftp {
private $hostname = '';
private $username = '';
private $password = '';
private $port = 21;
private $passive = true;
private $debug = true;
private $conn_id = false;
// 魔術方法、公共 API、私有輔助方法...
}
關鍵公共方法
連接與登錄
public function connect($config = []) {
if ($config) $this->_init($config);
$this->conn_id = @ftp_connect($this->hostname, $this->port);
if (!$this->conn_id) return $this->_error('ftp_unable_to_connect');
if (!$this->_login()) return $this->_error('ftp_unable_to_login');
if ($this->passive) ftp_pasv($this->conn_id, true);
return true;
}
private function _login() {
return @ftp_login($this->conn_id, $this->username, $this->password);
}
上傳文件(自動模式判斷)
public function upload($localpath, $remotepath, $mode = 'auto', $permissions = null) {
if (!$this->_isconn() || !file_exists($localpath)) return false;
if ($mode === 'auto') {
$ext = $this->_getext($localpath);
$mode = $this->_settype($ext); // ascii 或 binary
}
$mode = ($mode === 'ascii') ? FTP_ASCII : FTP_BINARY;
$result = @ftp_put($this->conn_id, $remotepath, $localpath, $mode);
if (!$result) return $this->_error('ftp_unable_to_upload');
if ($permissions !== null) $this->chmod($remotepath, $permissions);
return true;
}
private function _settype($ext) {
$textTypes = ['txt','text','php','js','css','html','xml','log','csv'];
return in_array($ext, $textTypes) ? 'ascii' : 'binary';
}
遞歸刪除目錄
public function delete_dir($path) {
if (!$this->_isconn()) return false;
$path = preg_replace('/(.+?)\/*$/', '\\1/', $path); // 確保以 / 結尾
$filelist = $this->filelist($path);
if ($filelist) {
foreach ($filelist as $item) {
if (!$this->delete_file($item)) {
$this->delete_dir($item); // 遞歸刪除子目錄
}
}
}
return @ftp_rmdir($this->conn_id, $path);
}
錯誤日誌記錄
private function _error($msg) {
$log = "date[".date('Y-m-d H:i:s')."] hostname[{$this->hostname}] username[{$this->username}] msg[$msg]\n";
@file_put_contents('ftp_err.log', $log, FILE_APPEND);
return false;
}
使用示例
require_once 'ftp.php';
$config = [
'hostname' => '101.64.183.92',
'username' => 'ftpadminuser',
'password' => 'admin_user',
'port' => 2112,
];
$ftp = new Ftp();
if ($ftp->connect($config)) {
// 上傳視頻文件
if ($ftp->upload('local/video.mp4', 'remote/video.mp4')) {
echo "上傳成功";
}
// 下載日誌
$ftp->download('remote/error.log', 'local/error.log');
// 創建目錄並設置權限
$ftp->mkdir('remote/new_dir', 0755);
$ftp->close();
}
擴展建議
- 添加 SSL/TLS 支持(
ftp_ssl_connect)
- 實現斷點續傳(
ftp_fput + ftp_fget + 文件指針定位)
- 增加連接池管理,避免頻繁建連
- 集成 PSR-3 日誌接口替代文件日誌
- 添加單元測試覆蓋核心邏輯
注意事項
- 確保服務器開放 21 端口及被動模式端口範圍
- PHP 需啟用
ftp 擴展
- 大文件上傳需調整
max_execution_time 和 memory_limit
- 生產環境建議關閉
$debug 或導向專業日誌系統