Подтвердить что ты не робот

Не удается заставить SFTP работать в PHP

Я пишу простой SFTP-клиент в PHP, потому что нам нужно программно извлекать файлы через 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 extenstion с SFTP? Я пропустил что-то очевидное здесь?

UPDATE:

Я устанавливаю sftp на другой машине внутри, и он работает нормально. Итак, должно быть что-то о том, что сервер, с которым я пытаюсь подключиться, не работает.

4b9b3361

Ответ 1

При подключении к SFTP-серверу вам необходимо подключиться к корневой папке (например, для чтения содержимого папки), вы все равно получите ошибку при использовании только "/" в качестве пути.

Решение, которое я нашел, это использовать путь "/./", который является допустимым путем, который ссылается на корневую папку. Это полезно, когда пользователь, с которым вы регистрируетесь, имеет доступ только к своей корневой папке и полный путь не доступен.

Таким образом, запрос на сервер при попытке прочитать содержимое корневой папки должен выглядеть примерно так:

$rd = "ssh2.sftp://{$this->sftp}/./";

Ответ 2

Для версий php > 5.6.27 используйте intval()

$sftpConnection = ssh2_connect($host);
$sftp = ssh2_sftp($sftpConnection);
$fp = fopen("ssh2.sftp://" . intval($sftp) . $remoteFile, "r");

https://bugs.php.net/bug.php?id=73597

Ответ 3

У меня такая же проблема. Я предполагаю, что вы делаете что-то похожее на это:

    $dir = "ssh2.sftp://{$sftp}{$remote_dir}"; 
    $handle = opendir($dir);

Когда $remote_dir - полный путь от корня, тогда работает open_dir. Если $remote_dir - это просто '/' или '', тогда я получаю ошибку "неспособность открыть", как вы это делали.

В моем случае кажется, что ssh подключается в корневой папке вместо каталога "home", как это делает ftp. Вы упомянули, что он работал на другом сервере, поэтому я задаюсь вопросом, просто ли это проблема с конфигурацией.

Ответ 4

Самый простой способ заставить SFTP работать в PHP (даже в Windows) без установки какого-либо расширения и т.д. - это PHPSECLIB: http://phpseclib.sourceforge.net/. Материал 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();
?>

Ответ 5

Документация на этой странице содержит ошибку. Взгляните сюда на пример: http://php.net/ssh2_sftp - вам действительно нужно открыть специальный SFTP-ресурс, используя ssh2_sftp() ранее использовать его с fopen(). И да, это выглядит так, например, "Ресурс № 24" при преобразовании в строку... немного странно, но, по-видимому, он работает.

Другой оговоркой является то, что SFTP запускается в корневом каталоге, а не в домашнем каталоге удаленного пользователя, поэтому ваш удаленный путь в URI всегда должен быть абсолютным.

Ответ 6

У меня была одна и та же проблема, но я мог понять проблему.

В моем случае, когда я подключался к серверу, я направлялся в корневую учетную запись, и из-за конфигураций сервера я не мог там писать.

Я подключился к учетной записи с помощью fireFTP, и поэтому я мог видеть, где был корень учетной записи... это был корень сервера.

Мне пришлось включить весь путь до папки, где мне разрешено писать, и поэтому я мог бы решить проблему.

Итак, мой совет - получить путь с использованием графического интерфейса (я использовал fireFTP) и добавить весь путь к вашему коду.


$pathFromAccountRootFolderToMyDestinationFolder = '/Account/Root/Folder/To/My/Folder';
$stream = fopen("ssh2.sftp://".$sftp."/".$pathFromAccountRootFolderToMyDestinationFolder."/myFile.ext", 'r');

Надеюсь, это поможет вам и другим людям с той же проблемой!

Ура!

Ответ 7

Недавно я попытался заставить SFTP работать с PHP и обнаружил, что phpseclib намного проще в использовании:

http://phpseclib.sourceforge.net/

Если у вас есть роскошь не быть на общем хосте и вы можете устанавливать любые расширения, которые вы хотите, возможно, расширение PECL было бы лучше, но не всем нам повезло. Кроме того, API phpseclib выглядит немного интуитивно понятным, будучи ООП и все.

Ответ 8

Моя проблема заключалась в том, что я подключался к функции и возвращал строковый URL-адрес с ресурсом внутри. Unfortunatelly ресурс, чем создан в контексте функции, и сборщик мусора отключает ресурс на конце функции. Решение: вернуть ресурс по ссылке и вручную удалить его в более сложном контексте.

Ответ 9

Решил мою проблему, включив поддержку sftp на сервере (Powershell)