PHP Conference Japan 2024

ssh2_scp_recv

(PECL ssh2 >= 0.9.0)

ssh2_scp_recv透過 SCP 請求檔案

說明

ssh2_scp_recv(資源 $session, 字串 $remote_file, 字串 $local_file): 布林值

使用 SCP 協定將檔案從遠端伺服器複製到本機檔案系統。

參數

session

一個 SSH 連線識別碼,透過呼叫 ssh2_connect() 取得。

remote_file

遠端檔案的路徑。

local_file

本機檔案的路徑。

傳回值

成功時傳回 true,失敗時傳回 false

範例

範例 #1 使用 SCP 下載檔案

<?php
$connection
= ssh2_connect('shell.example.com', 22);
ssh2_auth_password($connection, 'username', 'password');

ssh2_scp_recv($connection, '/remote/filename', '/local/filename');
?>

參見

新增筆記

使用者貢獻的筆記 10 則筆記

2
匿名
11 年前
當您嘗試使用類似 '~/filename.txt' 的路徑從使用者家目錄取得遠端檔案時,可能會失敗。它似乎不喜歡波浪號,因此請使用完整的檔案路徑。
4
liubomyr dot pelo at gmail dot com
8 年前
如果您收到

警告:ssh2_scp_recv():無法接收 /some-php-file.php 第 2 行的遠端檔案

請使用 `stream_get_contents` 函式。

範例
<?php
$stream
= @fopen("ssh2.sftp://$sftp$remoteFile", 'r');
if (!
$stream) {
throw new
\Exception("無法開啟檔案: $remoteFile");
}

$contents = stream_get_contents($stream);
file_put_contents ($localFile, $contents);
@
fclose($stream);
?>
2
ojovirtual
13 年前
嘗試取得名稱中包含空格的遠端檔案?

切記在遠端檔名中使用引號,但在本機檔名中則不要使用。

範例

<?php
$remote_file_name
="my name with spaces.ext"

ssh2_scp_recv($cn,$remote_file_name,$local_path."/".$remote_file_name); // 錯誤

ssh2_scp_recv($cn,"\"".$remote_file_name."\"",$local_path."/".$remote_file_name); //正確

ssh2_scp_recv($cn,"\"".$remote_file_name."\"","\"".$local_path."/".$remote_file_name."\""); //錯誤
?>

所以,檔名中的引號僅在遠端需要,本地端不需要。
2
miller4980 at msn dot com
16 年前
問題
無法將陣列傳遞給 sftp_scp_rec()
此外:對於 Windows:連線到 Windows 資料夾時,sftp 會出現問題。
例如:sftp_scp_rec($connection, "remote/directory","local/$directory[$i]");
解決方案
陣列會在變數末尾放置空白字元。
trim(" ","",$directory[$i]);

連線到 Windows 資料夾
sftp_scp_rec($connection, "linux/directory","\\windows\share[$i]");

此腳本會根據檔案的修改日期將遠端 Linux 資料夾備份到本機 Windows 資料夾。

其概念是透過 ftp 用戶端等取得完整目錄備份。
然後,當腳本執行時,它只會備份新修改的檔案。

<?php
//error_reporting(0);

$file ='';
$arr2 ='';
$arr1 ='';
$ldir = '';

$remotedirs[0] = "Domain name or IP address/";
$remotedirs[1] = "Domain name or IP address/";
$remotedirs[2] = "Domain name or IP address/";
$remotedirs[3] = "Domain name or IP address/";

$fh = fopen("c:\dirlist.txt","w");
fwrite($fh, " ");
fclose($fh);
foreach (
$remotedirs as $val){
echo
$remotedir = "/data/www/$val/";
$localdir = "\\\\192.168.0.234\\C$\\xampp\\htdocs\\$val\\";
backupwebsites($remotedir,$localdir);
}
function
backupwebsites($remotedir,$localdir){
$connection = ssh2_connect(Host IP or Domain, 22);
$com ="ls -R -lt $remotedir";
ssh2_auth_password($connection, 'user', 'password');
$stream = ssh2_exec($connection, $com );
stream_set_blocking($stream, true);
$output = stream_get_contents($stream);

$fh = fopen("c:\dirlist.txt","a+");
fwrite($fh, $output);
fclose($fh);
$handle = @fopen('c:\dirlist.txt', "r");
if (
$handle) {
while (!
feof($handle)) {
$lines[] = fgets($handle, 4096);
}
fclose($handle);
}
foreach (
$lines as $val)
{
$yr = date('Y-m-d');
$i++;
$arr1=split("200",$val);
$arr2=explode(" ",$arr1[1]);
if(
"200".$arr2[0]==$yr)
{
//if("200".$arr2[0]=='2008-04-21'){ //for testing
$remotedir = $remotedir.$arr2[2];
$cpy=$arr2[2];
$file = $localdir;
glue($connection,$remotedir,$localdir,$cpy);
}
}
}
//echo $i;
function glue($connection,$remotedir,$localdir,$cpy){
$ldir[0] = "$localdir";
$ldir[1]="$cpy";
$file = $ldir[0].$ldir[1];
$file = trim($file);
$file;
gop($connection,$remotedir,$file);
}
function
gop($connection,$remotedir,$file){
echo
$file;

ssh2_scp_recv(
$connection,
$remotedir,
$file);
}

?>
1
mark at mohc dot net
12 年前
如果您未呼叫 ssh2_exec($connection,'exit'),則傳輸的檔案可能會被截斷。即使檔案未完全傳輸,ssh2_scp_send 也會傳回 true。

例如:

ssh2_scp_send($connection, $infile, $remotefile, 0644);
ssh2_exec($connection, 'exit'); // 結束 ssh2 連線
0
luis dot sv at gmail dot com
14 年前
此函數可用於使用 SSH 和 SCP 將所有檔案複製到遠端伺服器上的目錄中。

<?php
$connection
= ssh2_connect('host', 22);
ssh2_auth_password($connection, 'user', 'password');

$remote_dir="/remote_dir/";
$local_dir="/local_dir/";

$com ="ls $remote_dir";
$stream = ssh2_exec($connection, $com);
stream_set_blocking($stream,true);
$cmd=fread($stream,4096);

$arr=explode("\n",$cmd);

$total_files=sizeof($arr);

for(
$i=0;$i<$total_files;$i++){
$file_name=trim($arr[$i]);
if(
$file_name!=''){
$remote_file=$remote_dir.$file_name;
$local_file=$local_dir.$file_name;

if(
ssh2_scp_recv($connection, $remote_file,$local_file)){
echo
"File ".$file_name." was copied to $local_dir<br />";
}
}
}

fclose($stream);
?>
0
gordon_e_rouse at yahoo dot com dot au
16 年前
我猜測因為它還處於 Beta 階段,所以會有一些古怪的地方。我發現其中一個問題是,如果遠端檔案名稱中包含括號,它就無法正常運作。

我應該將它作為錯誤報告提交,但整個過程真的令人生畏 - 我始終只是一個愚蠢的用戶,不知道自己在說什麼!

但無論如何 - 在下載檔案之前重新命名檔案的解決方法有效。

使用
$_new_path = str_replace("(", "", $_path );
$_new_path = str_replace(")", "", $_new_path );

ssh2_sftp_rename( $sftp, $_path, $_new_path );

老實說,我還沒有確定是左括號、右括號還是兩者都有問題。其他人可以研究一下。

同時,最好能知道所有會造成此函式問題的無效檔名,無疑還有更多。
-1
jcalcote at novell dot com
18 年前
如果您使用 opendir 和 readdir 掃描透過 ssh2_sftp() 取得路徑的遠端目錄以取得檔案列表,您最終會得到一個包含 ssh2.sftp://$sftp 前綴的完整檔案路徑列表,其中 $sftp 是 ssh2_sftp() 返回的 sftp 資源字串。

如果您之後嘗試使用 ssh2_scp_recv()(即使在同一個連線上!)從遠端路徑複製檔案到本機,複製操作將會失敗,因為 ssh2_scp_recv() 不接受此包裝路徑前綴。它預期遠端檔案參考的根目錄是遠端檔案系統的根目錄(例如「/」)。

重點:ssh2_scp_recv() 接受以遠端機器檔案系統根目錄為根的路徑,而不是完整的網路路徑。這個例程會失敗,並顯示一則關於無法複製檔案的模糊訊息 — 但當您實際查看時,檔案卻可以正常運作。更糟的是,當您連線並從 scp shell session 複製它們時,它也能正常運作。
-2
Maddie
11 年前
如果您收到錯誤訊息 - ssh2_scp_recv(): 無法接收遠端檔案

請嘗試使用 file_get_contents("ssh2.sftp://$sftp$fileLocation") 和 file_put_contents() 作為解決方法 — 這是在我嘗試了各種不同的遠端檔案路徑格式都無效之後的作法。
-3
chad dot [字母 d] johnson AT gmail
16 年前
如果在嘗試使用此函式時出現「警告:ssh2_scp_send(): 建立遠端檔案失敗」,請嘗試使用

$data = file_get_contents("ssh2.sftp://$sftp/path/to/file");
To Top