Jak SFTP z PHP?

83

Natknąłem się na wiele skryptów PHP dla internetowych klientów FTP. Muszę zaimplementować klienta SFTP jako aplikację internetową w PHP. Czy PHP obsługuje SFTP? Nie mogłem znaleźć żadnych próbek. Czy ktoś może mi w tym pomóc?

indranama
źródło

Odpowiedzi:

72

PHP ma opakowania strumieniowe ssh2 (domyślnie wyłączone), więc możesz używać połączeń sftp z dowolną funkcją obsługującą opakowania strumieniowe za pomocą ssh2.sftp://protokołu, np.

file_get_contents('ssh2.sftp://user:[email protected]:22/path/to/filename');

lub - gdy używasz również rozszerzenia ssh2

$connection = ssh2_connect('shell.example.com', 22);
ssh2_auth_password($connection, 'username', 'password');
$sftp = ssh2_sftp($connection);
$stream = fopen("ssh2.sftp://$sftp/path/to/file", 'r');

Zobacz http://php.net/manual/en/wrappers.ssh2.php

Na marginesie, jest już sporo pytań na ten temat:

Gordon
źródło
file_get_contents i file_put_contents działają świetnie. nigdy nie wiedziałem, że pracują z sftp i jest to o wiele łatwiejsze niż używanie wbudowanych elementów sftp. Dzięki!
jbrahy
3
Nawet jeśli używasz file_get_contents (), nadal potrzebujesz rozszerzenia ssh2 (afaik).
StanE
Pakiety debian / ubuntu: apt install libssh2-1-dev php-ssh2
Ajay Singh
40

Funkcje ssh2 nie są zbyt dobre. Trudne w użyciu i jeszcze trudniejsze do zainstalowania, korzystanie z nich gwarantuje, że Twój kod nie jest przenoszony. Moim zaleceniem byłoby użycie phpseclib, czystej implementacji PHP SFTP .

calgaryhit
źródło
3
@indranama, czy oznaczyłbyś to jako poprawną odpowiedź, aby przyszli użytkownicy nie musieli czytać komentarzy, aby znaleźć najlepszą dla Ciebie odpowiedź?
Fi Horan
30

Odkryłem, że "phpseclib" powinno ci w tym pomóc (SFTP i wiele innych funkcji). http://phpseclib.sourceforge.net/

Aby umieścić plik na serwerze, po prostu zadzwoń (przykład kodu z http://phpseclib.sourceforge.net/sftp/examples.html#put )

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

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

// puts a three-byte file named filename.remote on the SFTP server
$sftp->put('filename.remote', 'xxx');
// puts an x-byte file named filename.remote on the SFTP server,
// where x is the size of filename.local
$sftp->put('filename.remote', 'filename.local', NET_SFTP_LOCAL_FILE);
Prut Udomwattawee
źródło
2
Repozytorium
relipse
1
Czy możesz zaktualizować swoją odpowiedź do phpseclib 2.0? Twój obecny przykład jest przestarzały.
Martin Prikryl,
2

Zainstaluj Flysystem:

composer require league/flysystem-sftp

Następnie:

use League\Flysystem\Filesystem;
use League\Flysystem\Sftp\SftpAdapter;

$filesystem = new Filesystem(new SftpAdapter([
    'host' => 'example.com',
    'port' => 22,
    'username' => 'username',
    'password' => 'password',
    'privateKey' => 'path/to/or/contents/of/privatekey',
    'root' => '/path/to/root',
    'timeout' => 10,
]));
$filesystem->listFiles($path); // get file lists
$filesystem->read($path_to_file); // grab file
$filesystem->put($path); // upload file
....

Czytać:

https://flysystem.thephpleague.com/v1/docs/

Sole
źródło
-1

Wykonałem pełną wymówkę i napisałem klasę, która tworzy plik wsadowy, a następnie dzwoni sftpprzez systempołączenie. Nie jest to najprzyjemniejszy (lub najszybszy) sposób na zrobienie tego, ale działa na to, czego potrzebuję i nie wymagał żadnej instalacji dodatkowych bibliotek lub rozszerzeń w PHP.

Może być dobrym rozwiązaniem, jeśli nie chcesz korzystać z ssh2rozszerzeń

DaveyBoy
źródło
powiązany wątek, który mi pomógł: groups.google.com/forum/#!topic/comp.security.ssh/_55TdDdUTCw
Quamis