ftp_connect():建立連線ftp_login():使用者認證ftp_pasv():啟用被動模式(穿透防火牆/NAT 必須)ftp_put():上傳檔案ftp_close():關閉連線<?php
$host = 'ftp.example.com';
$user = 'username';
$pass = 'password';
$localFile = 'local/data.csv';
$remoteFile = 'backup/data_' . date('Ymd') . '.csv';
$conn = ftp_connect($host, 21, 30); // 連接埠 21,逾時 30 秒
if (!$conn) die('無法連線至 FTP 伺服器');
$login = ftp_login($conn, $user, $pass);
if (!$login) die('FTP 登入失敗:帳號密碼錯誤');
// 【關鍵】啟用被動模式,解決防火牆/NAT 導致資料連線失敗
ftp_pasv($conn, true);
// 上傳:FTP_BINARY 適用所有檔案(含圖片、壓縮檔),FTP_ASCII 僅純文字
$upload = ftp_put($conn, $remoteFile, $localFile, FTP_BINARY);
if ($upload) {
echo "上傳成功:$remoteFile";
} else {
echo '上傳失敗:' . ftp_last_error($conn);
}
ftp_close($conn);
function ftpUploadWithRetry($host, $user, $pass, $local, $remote, $maxRetry = 3) {
for ($attempt = 1; $attempt <= $maxRetry; $attempt++) {
$conn = @ftp_connect($host, 21, 10);
if (!$conn) {
sleep(2);
continue;
}
if (!@ftp_login($conn, $user, $pass)) {
ftp_close($conn);
sleep(2);
continue;
}
ftp_pasv($conn, true);
$ok = @ftp_put($conn, $remote, $local, FTP_BINARY);
$err = ftp_last_error($conn);
ftp_close($conn);
if ($ok) return true;
error_log("FTP 上傳失敗 (嘗試 $attempt/$maxRetry): $err");
sleep(3);
}
return false;
}
| 函式 | 用途 |
|---|---|
| ftp_connect(host, port, timeout) | 建立連線 |
| ftp_ssl_connect() | 建立 FTPS (SSL/TLS) 連線 |
| ftp_login(conn, user, pass) | 登入驗證 |
| ftp_pasv(conn, true) | 啟用被動模式(客戶端發起資料連線) |
| ftp_put(conn, remote, local, mode) | 上傳檔案 |
| ftp_fput(conn, remote, handle, mode) | 上傳已開啟的檔案指標 |
| ftp_get(conn, local, remote, mode) | 下載檔案 |
| ftp_fget(conn, handle, remote, mode) | 下載到檔案指標 |
| ftp_nlist(conn, dir) | 列出目錄檔案(陣列) |
| ftp_rawlist(conn, dir) | 列出目錄詳細資訊 |
| ftp_mkdir(conn, dir) | 建立目錄 |
| ftp_rmdir(conn, dir) | 刪除目錄 |
| ftp_delete(conn, file) | 刪除檔案 |
| ftp_rename(conn, old, new) | 重新命名/移動 |
| ftp_chmod(conn, mode, file) | 變更權限(如 0644) |
| ftp_size(conn, file) | 取得檔案大小 |
| ftp_mdtm(conn, file) | 取得最後修改時間 |
| ftp_close(conn) | 關閉連線 |
永遠啟用 ftp_pasv($conn, true),除非你確定在特殊環境需主動模式。
原生 FTP 函式錯誤處理弱、不支援 SFTP。建議使用成熟套件:
// composer require league/flysystem
use League\Flysystem\Filesystem;
use League\Flysystem\Ftp\FtpAdapter;
$adapter = new FtpAdapter([
'host' => 'ftp.example.com',
'username' => 'user',
'password' => 'pass',
'passive' => true,
'ssl' => true, // FTPS
'port' => 21,
'timeout' => 30,
]);
$fs = new Filesystem($adapter);
$fs->write('remote/path/file.txt', '內容'); // 統一介面支援 FTP/SFTP/S3/本地