首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP FTP 連線與檔案上傳完整實作指南

     編輯:PHP 相關知識

FTP 基本流程

  1. ftp_connect():建立連線
  2. ftp_login():使用者認證
  3. ftp_pasv():啟用被動模式(穿透防火牆/NAT 必須)
  4. ftp_put():上傳檔案
  5. 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 函式速查

函式用途
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)關閉連線

被動模式 vs 主動模式

  • 主動模式:客戶端告知 IP/Port,伺服器主動連回客戶端傳輸資料。客戶端需有公網 IP 且防火牆允許入站連線,內網環境幾乎不可用。
  • 被動模式:客戶端請求伺服器開啟 Port,客戶端主動連線過去。**穿透 NAT/防火牆**,現代 FTP 客戶端預設皆用被動模式。

永遠啟用 ftp_pasv($conn, true),除非你確定在特殊環境需主動模式。

安全性建議

  1. 優先使用 FTPS (ftp_ssl_connect) 或 **SFTP (SSH2 擴展/ssh2_sftp)**,避免明文傳輸帳密與資料。
  2. 限制 FTP 帳號權限:僅允許特定目錄讀寫,禁用 Shell 登入。
  3. 定期輪換密碼,啟用 IP 白名單(伺服器端設定)。
  4. 上傳後驗證檔案大小與 checksum(md5/sha256),確保傳輸完整。

替代方案:phpseclib / league/flysystem

原生 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/本地
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved