Pergunta

Estou escrevendo um cliente SFTP simples em PHP, porque temos a necessidade de programaticamente recuperar arquivos via n servidores remotos. Eu estou usando a extensão PECL SSH2.

Eu tenho que correr contra um bloqueio na estrada, no entanto. A documentação sobre php.net sugere que você pode fazer isso:

$stream = fopen("ssh2.sftp://$sftp/path/to/file", 'r');

No entanto, tenho um método ls que tenta algo semelhante

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);
}

Eu recebo o seguinte erro:

PHP Warning:  opendir(): Unable to open ssh2.sftp://Resource id #5/outgoing on remote host

Isso faz sentido porque é isso que acontece quando você lançar um recurso para string. É o errado documentação? Eu tentei substituir o recurso com o host, nome de usuário e de acolhimento e que não quer trabalhar. Eu sei que o caminho está correto, porque eu posso correr SFTP a partir da linha de comando e ele funciona muito bem.

Tem mais alguém tentou usar o extenstion SSH2 com SFTP? Estou faltando alguma coisa óbvia aqui?

UPDATE:

Eu sftp instalação em outra máquina em casa e ele funciona muito bem. Então, deve haver algo sobre o servidor Eu estou tentando se conectar a que não está funcionando.

Foi útil?

Solução

Ao se conectar a um servidor SFTP e você precisa conectar-se à pasta raiz (por exemplo, para ler o conteúdo da pasta) que você ainda obter o erro ao usar apenas "/" como o caminho.

A solução que encontrei foi usar o caminho "/./", que é um caminho válido que as referências para a pasta raiz. Isto é útil quando o usuário você está conectado com tem acesso apenas a sua própria pasta raiz e nenhum caminho completo está disponível.

Assim, o pedido para o servidor ao tentar ler o conteúdo da pasta raiz deve ser algo como isto:

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

Outras dicas

Para versões php> 5.6.27 uso 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

Eu estou tendo um problema semelhante. Eu suponho que você está fazendo algo semelhante a isto:

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

Quando $remote_dir é o caminho completo desde a raiz, em seguida, open_dir obras. Se $remote_dir é apenas '/' ou '', então eu obter o 'incapaz de abrir erro', como você fez.

No meu caso, parece Ligações ssh na pasta raiz em vez do diretório 'home' como ftp faz. Você mencionou que ele trabalhou em um servidor diferente, então eu pergunto se é apenas uma questão de configuração.

a maneira mais fácil de obter SFTP trabalhando dentro de PHP (mesmo no Windows) sem instalar qualquer extensão etc é PHPSECLIB: http: //phpseclib.sourceforge.net/ . O material SSH é totalmente implementado em uma classe PHP.

Você usa é assim:

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

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

echo $sftp->pwd();
?>

A documentação na página contém um erro. Dê uma olhada no exemplo aqui em vez disso: http://php.net/ssh2_sftp - o que você realmente precisa fazer é abrir um usando ssh2_sftp recurso especial SFTP () antes de utilizá-lo com fopen (). E sim, ele se parece com que, por exemplo, "Recurso # 24" quando convertido para string ... um pouco estranho, mas aparentemente ele funciona.

Outra ressalva é que SFTP começa no diretório raiz em vez do diretório home do usuário remoto, para que o seu caminho remoto no URI deve ser sempre absoluto.

Eu só tive o mesmo problema, mas eu poderia descobrir o problema.

No meu caso, quando se conectar ao servidor, eu estava indo para a raiz da conta, e devido a configurações de servidor que eu não era capaz de escrever lá.

Tenho ligado para a conta usando um fireFTP, e para que eu pudesse ver onde a raiz da conta era ... era a raiz do servidor.

Eu tive que incluir todo o caminho até a pasta onde eu estou autorizado a gravação, e assim eu poderia resolver a questão.

Então, meu conselho é para obter o caminho usando uma interface gráfica (eu usei fireFTP), e adicione todo o caminho para o código.


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

Espero que isso irá ajudá-lo e outras pessoas com o mesmo problema!

Felicidades!

Eu recentemente tentou obter SFTP em PHP trabalhar e descobriu que phpseclib era muito mais fácil de usar:

http://phpseclib.sourceforge.net/

Se você tem o luxo de não estar em um servidor compartilhado e pode instalar qualquer extensões você quer talvez a extensão PECL seria melhor, mas não todos nós têm tanta sorte. Além disso, a API do phpseclib parece um pouco mais intuitiva, sendo OOP e tudo.

Meu problema era que eu estava ligando em função e retornando URL string com interior de recursos. recurso Infelizmente é do que criado no contexto da função e coletor de lixo é desconectar recurso no final função. Solução:. Recurso retorno por referência e unset-lo manualmente no contexto mais complexo

resolvido meu problema, permitindo suporte sftp no servidor (PowerShell)

Este é um bug no pacote ssh2 que eu encontrei anos atrás e publicou um patch para php.net. Ele corrige esse problema, mas requer uma reconstrução do pacote pecl ssh2. Você pode ler mais aqui: https://bugs.php.net/bug.php? id = 69981 . Eu incluí um patch lá para o arquivo ssh2_fopen_wrappers.c no pacote para corrigir o problema. Aqui está um comentário que inclui:

Aqui está uma linha de código do ssh2_fopen_wrappers.c que faz com que este erro: (comentário incluído)

/*
       Find resource->path in the path string, then copy the entire string from the original path.
       This includes ?query#fragment in the path string
*/
    resource->path = estrdup(strstr(path, resource->path));

Esta linha de código - e, portanto, este bug - foi introduzido como uma correção para bug # 59794. Essa linha de código está a tentar obter uma string contendo a parte, consulta e fragmento da variável de caminho. Considere este valor para a variável caminho:

ssh2.sftp://Resource id #5/topdir?a=something#heading1

Quando utilização de recursos> caminho é "/ TOPDIR", o resultado é que "/ TOPDIR? A = algo # heading1" é atribuído à utilização de recursos> caminho exatamente como diz o comentário.

Agora, considere o caso quando utilização de recursos> caminho é "/". Após a linha de código é executado, utilização de recursos> caminho torna-se "// Resource id # 5 / TOPDIR # heading1". Este não é claramente o que você quer. Aqui está uma linha de código que faz:

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

Você também pode precisar de aplicar o patch para o bug # 73597 que remove "Resource id #" da cadeia de caminho antes de chamar php_url_parse ().

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top