PHP 內建 FTP 擴充功能提供完整的 FTP 客戶端操作能力,適用於自動化部署、檔案同步、備份系統等場景。本文系統整理核心函式並提供完整可執行範例。
| 函式 | 用途 | 關鍵參數 |
|---|---|---|
ftp_connect() | 建立 FTP 連線 | $host, $port=21, $timeout=90 |
ftp_login() | 使用者認證登入 | $conn, $username, $password |
ftp_pasv() | 設定被動模式 | $conn, true/false(防火牆/NAT 環境建議開啟) |
ftp_put() | 上傳檔案 | $conn, $remote_file, $local_file, $mode |
ftp_get() | 下載檔案 | $conn, $local_file, $remote_file, $mode |
ftp_close() | 關閉連線 | $conn |
ftp_chdir() | 切換遠端目錄 | $conn, $directory |
ftp_mkdir() | 建立遠端目錄 | $conn, $directory |
ftp_delete() | 刪除遠端檔案 | $conn, $path |
ftp_nlist() | 列出目錄檔案 | $conn, $directory='.' |
FTP_ASCII:文字檔(自動轉換換行符)FTP_BINARY:二進位檔(圖片、壓縮檔、執行檔等,預設建議)<?php
/**
* FTP 檔案上傳封裝函式
*
* @param array $config 連線設定
* @param string $localPath 本地檔案路徑
* @param string $remotePath 遠端儲存路徑(含檔名)
* @param int $mode 傳輸模式 FTP_BINARY|FTP_ASCII
* @return bool|string 成功回傳 true,失敗回傳錯誤訊息
*/
function ftpUpload(array $config, $localPath, $remotePath, $mode = FTP_BINARY) {
// 1. 檢查本地檔案
if (!file_exists($localPath) || !is_file($localPath)) {
return "本地檔案不存在: {$localPath}";
}
if (!is_readable($localPath)) {
return "本地檔案不可讀: {$localPath}";
}
// 2. 建立連線
$conn = @ftp_connect($config['host'], $config['port'] ?? 21, $config['timeout'] ?? 30);
if (!$conn) {
return "無法連線至 FTP 伺服器: {$config['host']}";
}
// 3. 登入驗證
$login = @ftp_login($conn, $config['username'], $config['password']);
if (!$login) {
ftp_close($conn);
return "FTP 登入失敗,請檢查帳號密碼";
}
// 4. 設定被動模式(推薦)
if (isset($config['pasv']) && $config['pasv']) {
ftp_pasv($conn, true);
}
// 5. 確保遠端目錄存在
$remoteDir = dirname($remotePath);
if ($remoteDir !== '.' && $remoteDir !== '/') {
// 遞迴建立目錄(簡易版)
$dirs = explode('/', trim($remoteDir, '/'));
$currentPath = '';
foreach ($dirs as $dir) {
$currentPath .= '/' . $dir;
@ftp_chdir($conn, $currentPath) || @ftp_mkdir($conn, $currentPath);
}
}
// 6. 執行上傳
$result = ftp_put($conn, $remotePath, $localPath, $mode);
// 7. 關閉連線
ftp_close($conn);
return $result ? true : "檔案上傳失敗(權限不足或磁碟空間不足)";
}
// 使用範例
$ftpConfig = [
'host' => 'ftp.example.com',
'port' => 21,
'username' => 'user123',
'password' => 'secret456',
'timeout' => 30,
'pasv' => true // 建議開啟被動模式
];
$uploadResult = ftpUpload($ftpConfig, '/var/www/uploads/report.pdf', '/backups/report_2024.pdf');
if ($uploadResult === true) {
echo "✅ 上傳成功!\n";
} else {
echo "❌ 上傳失敗: {$uploadResult}\n";
}
?>
| 問題現象 | 可能原因 | 解決方案 |
|---|---|---|
| 連線逾時 | 防火牆阻擋、Port 錯誤、主機名解析失敗 | 檢查防火牆規則、嘗試 IP 直連、增加 timeout |
| 登入成功但上傳失敗 | 主動模式下資料連線被阻擋 | 啟用 ftp_pasv(true) |
| 中文檔名亂碼 | 伺服器編碼不支援 UTF-8 | 上傳前轉碼:iconv('UTF-8', 'GBK', $filename) 或改用英文檔名 |
| 大檔案上傳中斷 | PHP max_execution_time、FTP 伺服器逾時設定 | 調整 set_time_limit(0)、分塊上傳、檢查伺服器設定 |
| 權限被拒 | 帳號無寫入權限、目錄不存在 | 確認 FTP 帳號權限、程式自動建立目錄 |
ftp_fput() 搭配檔案指標 fseek() 實現ftp_ssl_connect()(需 PHP 編譯支援 OpenSSL)ftp_nlist() 遞迴比對本地/遠端檔案清單PHP FTP 函式雖然基礎,但配合妥善的錯誤處理、被動模式與目錄管理,足以應付大多數自動化檔案傳輸需求。