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 年前
当尝试从用户的 home 目录获取远程文件时,如果使用类似 '~/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] = "域名或IP地址/";
$remotedirs[1] = "域名或IP地址/";
$remotedirs[2] = "域名或IP地址/";
$remotedirs[3] = "域名或IP地址/";

$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(主机IP 域名, 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_name." 已复制到 $local_dir<br />";
}
}
}

fclose($stream);
?>
0
gordon_e_rouse at yahoo dot com dot au
16 年前
因为还在测试阶段(Beta版),我想它会有一些特性问题。我发现一个问题是,如果远程文件名包含括号,它就无法工作。

我应该把它作为一个bug报告提交,但是整个流程让我觉得很吓人——我一直都觉得自己是个啥也不懂的笨用户!

但无论如何——在下载前重命名文件这种变通方法很有效。

使用
$_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年前
如果你使用从ssh2_sftp()获得的路径,通过opendir和readdir扫描远程目录以获取文件列表,你最终会得到一个包含ssh2.sftp://$sftp前缀的完整文件路径列表,其中$sftp是由ssh2_sftp返回的sftp资源字符串。

如果你稍后尝试使用ssh2_scp_recv()(即使在相同的连接上!)从远程路径本地复制文件,复制操作将会失败,因为ssh2_scp_recv()不喜欢包装路径前缀。它期望远程文件引用位于远程文件系统的根目录(例如,“/”)。

结论:ssh2_scp_recv()喜欢位于远程机器文件系统根目录的路径,而不是完整的网络路径。这个例程会以一条关于无法复制文件的模糊消息失败——然而当你查看时,它却工作正常。更糟糕的是,当你连接并从scp shell会话中复制它们时,它也工作正常。
-2
Maddie
11 年前
如果你收到错误 - ssh2_scp_recv(): Unable to receive remote file

尝试使用file_get_contents("ssh2.sftp://$sftp$fileLocation") 和 file_put_contents() 作为变通方法——在我尝试了各种不同的远程文件路径格式都无效之后。
-3
chad dot [the letter d] johnson AT gmail
16 年前
如果你在尝试使用此函数时收到“Warning: ssh2_scp_send(): Failure creating remote file,”错误,请尝试使用

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