PHP Conference Japan 2024

ftp_nb_put

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

ftp_nb_put將檔案儲存到 FTP 伺服器(非阻塞)

描述

ftp_nb_put(
    FTP\Connection $ftp,
    string $remote_filename,
    string $local_filename,
    int $mode = FTP_BINARY,
    int $offset = 0
): int|false

ftp_nb_put() 將本地檔案儲存到 FTP 伺服器上。

此函式與 ftp_put() 的區別在於,此函式非同步上傳檔案,因此您的程式可以在檔案上傳期間執行其他操作。

引數

ftp

一個 FTP\Connection 例項。

remote_filename

遠端檔案路徑。

local_filename

本地檔案路徑。

mode

傳輸模式。必須是 FTP_ASCIIFTP_BINARY

offset

開始上傳到的遠端檔案中的位置。

返回值

返回 FTP_FAILEDFTP_FINISHEDFTP_MOREDATA,或者在無法開啟本地檔案時返回 false

變更日誌

版本 描述
8.1.0 ftp 引數現在期望一個 FTP\Connection 例項;以前,期望一個 資源
7.3.0 mode 引數現在是可選的。以前它是必須的。

示例

示例 #1 ftp_nb_put() 示例

<?php

// 開始上傳
$ret = ftp_nb_put($ftp, "test.remote", "test.local", FTP_BINARY);
while (
$ret == FTP_MOREDATA) {

// 做任何你想做的事情
echo ".";

// 繼續上傳...
$ret = ftp_nb_continue($ftp);
}
if (
$ret != FTP_FINISHED) {
echo
"上傳檔案時出現錯誤...";
exit(
1);
}
?>

示例 #2 使用 ftp_nb_put() 恢復上傳

<?php

// 初始化
$ret = ftp_nb_put($ftp, "test.remote", "test.local",
FTP_BINARY, ftp_size("test.remote"));
// 或者:$ret = ftp_nb_put($ftp, "test.remote", "test.local",
// FTP_BINARY, FTP_AUTORESUME);

while ($ret == FTP_MOREDATA) {

// 做任何你想做的事情
echo ".";

// 繼續上傳...
$ret = ftp_nb_continue($ftp);
}
if (
$ret != FTP_FINISHED) {
echo
"上傳檔案時出現錯誤...";
exit(
1);
}
?>

參見

添加註釋

使用者貢獻的筆記 6 個筆記

3
ted at hostleft dot com
19 年前
如果您收到類似以下的錯誤

警告:ftp_nb_put():無法在 /path/to/file.php 的第 27 行中為 PORT 命令提供服務

驗證您是否需要處於 PASV 模式。您可以透過宣告以下內容進入 PASV 模式

> ftp_pasv($cnx,TRUE);
3
manu at manux dot org
19 年前
在使用非阻塞函式時,如果您嘗試在非阻塞操作正在進行時斷開連線,則斷開連線命令將無法工作,直到操作完成。
3
Ariel asphp at dsgml dot com
18 年前
不要在迴圈內新增 sleep()。如果您這樣做,會嚴重降低上傳速度。

在我的測試中,每次迴圈傳送大約 2.5K,每秒迴圈大約 220 次。(這非常少。)

您不一定能獲得與我相同的每次迴圈數字,但顯然 PHP 對迴圈進行了自己的管理,以便您不會消耗伺服器上的所有 CPU。
1
WebSee.ru
15 年前
如何實現透過 FXP 將資料從一臺 FTP 伺服器傳輸到另一臺 FTP 伺服器的可能性



<?php
// ...

$ansver = ftp_raw($ftp_conn1, 'PASV');

if (
intval($ansver[0]) == 227) {
ftp_raw($ftp_conn2, 'PORT '.substr($ansver[0], $n = strpos($ansver[0], '(') + 1, strpos($m[0], ')', $n) - $n));
ftp_raw($ftp_conn1, 'STOR '.$filename); // 需要非同步(非阻塞)
ftp_raw($ftp_conn2, 'RETR '.$filename);
}
?>
-1
kaiohken1982 at hotmail dot com
18 年前
您好,
我嘗試使用 ftp_put() 和 ftp_nb_put(),並在指令碼開頭新增
變數 $start = date("Y:m:d h:i:s"); 並在檔案上傳函式之後,指令碼結尾新增變數 $end = date("Y:m:d h:i:s");。
我目前使用的是 GPRS 連線,嘗試上傳一個 67.5KB 的 .jpg 檔案,在這兩種情況下,$start 和 $end 之間的時間差都是 40 秒,所以我可以假設這兩個上傳函式之間沒有區別。
如果在 while ($ftp_upload == FTP_MOREDATA) 迴圈中新增任何內容,就會出現差異。
希望此說明能有所幫助。
此致
-1
brandon dot farber at gmail dot com
18 年前
我之前沒有注意到這一點……

ftp_nb_put 上傳檔案的時間明顯比 ftp_put 長得多(我沒有進行任何資料包嗅探或日誌測試來找出原因)。我使用了一個與上面示例幾乎相同的指令碼,一個 100KB 的檔案在大約 8 分鐘後只上傳了 3.99KB!PHP 指令碼自然超時,無法完成。

我將函式更改為使用 ftp_put,去掉了檢查 FTP_MOREDATA 的迴圈(如上例所示),並且相同的指令碼在沒有任何其他更改的情況下在 30 秒內上傳了 2.2MB。

如果您使用此函式而不是 ftp_put *僅僅是為了嘗試加快指令碼速度*,並且它花費了很長時間,您可能需要嘗試使用 ftp_put。
To Top