Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Can';不要让SFTP在PHP中工作_Php_Ssh_Wrapper_Sftp - Fatal编程技术网

Can';不要让SFTP在PHP中工作

Can';不要让SFTP在PHP中工作,php,ssh,wrapper,sftp,Php,Ssh,Wrapper,Sftp,我正在用PHP编写一个简单的SFTP客户端,因为我们需要通过n个远程服务器以编程方式检索文件。我正在使用PECL SSH2扩展 不过,我遇到了一个路障。php.net上的文档建议您可以这样做: $stream = fopen("ssh2.sftp://$sftp/path/to/file", 'r'); 但是,我有一个ls方法,它试图实现类似的功能 public function ls($dir) { $rd = "ssh2.sftp://{$this->sftp}/$dir";

我正在用PHP编写一个简单的SFTP客户端,因为我们需要通过n个远程服务器以编程方式检索文件。我正在使用PECL SSH2扩展

不过,我遇到了一个路障。php.net上的文档建议您可以这样做:

$stream = fopen("ssh2.sftp://$sftp/path/to/file", 'r');
但是,我有一个ls方法,它试图实现类似的功能

public function ls($dir)
{
    $rd = "ssh2.sftp://{$this->sftp}/$dir";
    $handle = opendir($rd);
    if (!is_resource($handle)) {
        throw new SFTPException("Could not open directory.");
    }

    while (false !== ($file = readdir($handle))) {
        if (substr($file, 0, 1) != '.'){
            print $file . "\n";
        }
    }
    closedir($handle);
}
我得到以下错误:

PHP Warning:  opendir(): Unable to open ssh2.sftp://Resource id #5/outgoing on remote host
这非常有意义,因为当您将资源强制转换为字符串时会发生这种情况。文档是否有误?我尝试用主机、用户名和主机替换资源,但也没有成功。我知道路径是正确的,因为我可以从命令行运行SFTP,它工作得很好

是否有其他人尝试将SSH2扩展与SFTP一起使用?我是不是漏掉了什么明显的东西

更新:


我在内部的另一台机器上设置了sftp,它工作得很好。因此,我试图连接的服务器一定有什么地方不工作。

我也遇到了类似的问题。我假设您正在做类似的事情:

    $dir = "ssh2.sftp://{$sftp}{$remote_dir}"; 
    $handle = opendir($dir);
$remote\u dir
是根目录的完整路径时,
open\u dir
起作用。如果
$remote\u dir
只是“/”或“”,那么我会像您一样出现“无法打开”错误


在我的例子中,ssh似乎是在根文件夹而不是像ftp那样在“home”目录下连接的。您提到它在不同的服务器上工作,所以我想知道这是否只是一个配置问题。

我最近尝试让PHP上的SFTP工作,发现phpseclib更易于使用:


如果您有幸不在共享主机上,并且可以安装任何您想要的扩展,那么PECL扩展可能会更好,但并非所有人都这么幸运。另外,phpseclib的API看起来更直观,是面向对象的。我也遇到了同样的问题,但我可以解决这个问题

在我的情况下,当连接到服务器时,我将转到帐户的根目录,由于服务器配置,我无法在那里写入

我已经使用fireFTP连接到该帐户,因此我可以看到该帐户的根在哪里…它是服务器的根

我必须包括整个路径,直到允许我写入的文件夹,这样我才能解决这个问题

因此,我的建议是使用图形界面获取路径(我使用了fireFTP),并将整个路径添加到代码中


$pathFromAccountRootFolderToMyDestinationFolder = '/Account/Root/Folder/To/My/Folder';
$stream = fopen("ssh2.sftp://".$sftp."/".$pathFromAccountRootFolderToMyDestinationFolder."/myFile.ext", 'r');
希望这将有助于你和其他人与同样的问题


干杯

让SFTP在PHP内(甚至在windows上)工作而不安装任何扩展等最简单的方法是PHPSECLIB:。SSH内容完全在PHP类中实现

您使用的是这样的:

<?php
include('Net/SFTP.php');

$sftp = new Net_SFTP('www.domain.tld');
if (!$sftp->login('username', 'password')) {
    exit('Login Failed');
}

echo $sftp->pwd();
?>
$rd = "ssh2.sftp://{$this->sftp}/./";

该页上的文档包含错误。请看下面的示例:-您实际需要做的是在将其与fopen()一起使用之前,使用ssh2_SFTP()打开一个特殊的SFTP资源。是的,它看起来就像那样,例如,当转换为字符串时,“Resource#24”。。。有点奇怪,但很明显它是有效的


另一个警告是,SFTP在根目录而不是远程用户的主目录中启动,因此URI中的远程路径应该始终是绝对路径。

当连接到SFTP服务器时,您需要连接到根文件夹(例如,读取文件夹的内容)仅使用“/”作为路径时,仍然会出现错误

我找到的解决方案是使用路径“/。/”,这是引用根文件夹的有效路径。当您登录的用户只能访问其自己的根文件夹,并且没有可用的完整路径时,这非常有用

因此,当尝试读取根文件夹的内容时,对服务器的请求应该如下所示:

<?php
include('Net/SFTP.php');

$sftp = new Net_SFTP('www.domain.tld');
if (!$sftp->login('username', 'password')) {
    exit('Login Failed');
}

echo $sftp->pwd();
?>
$rd = "ssh2.sftp://{$this->sftp}/./";

我的问题是,我在函数中连接并返回包含资源的字符串URL。不幸的是,资源不是在函数上下文中创建的,垃圾收集器正在断开函数端的资源连接。解决方案:通过引用返回资源,并在更复杂的上下文中手动取消设置它。

对于php版本>5.6.27,请使用intval()


通过在(Powershell)服务器上启用sftp支持解决了我的问题

这是多年前我在ssh2包中发现的一个错误,并在php.net上发布了一个补丁。它修复了此问题,但需要重建ssh2 pecl包。您可以在此处阅读更多:。我在包中的ssh2_fopen_wrappers.c文件中添加了一个补丁来修复这个问题。以下是我的评论:

下面是ssh2_fopen_wrappers.c中导致此错误的一行代码:(包括注释)

这一行代码——也就是这个bug——是作为bug#59794的修复而引入的。这行代码试图从path变量中获取包含部件、查询和片段的字符串。 考虑路径变量的这个值:

ssh2.sftp://Resource id #5/topdir?a=something#heading1
当resource->path为“/topdir”时,结果是“/topdir?a=something#heading1”被分配给resource->path,就像注释所说的那样

现在考虑资源->路径为“/”时的情况。执行代码行后,resource->path变为“//resource id#5/topdir#heading1”。这显然不是你想要的。下面是一行代码,用于:

 resource->path = estrdup( strstr( strstr( path, "//" ) + 2, "/" ) );

在调用php_url_parse()之前,您可能还需要应用bug#73597的修补程序,该修补程序会从路径字符串中删除“Resource id”。

您能确认ssh2连接正在工作吗?使用任何其他ssh2函数如何?ssh2\u connect()ssh2\u auth\u password()ssh2\u sftp()都工作正常。据我所知,我有一个有效的连接资源。从我所看到的,你是对的。它连接到根目录而不是“home”。使用命令行sftp客户端确实连接到“home”。我可能只需要从尝试连接到的客户端获取绝对路径。
$dir='ssh2.sftp://'.$sftp.//'.$absolute\u path使用绝对值