How to SFTP with PHP?
Asked Answered
H

6

96

I have came across many PHP scripts for web FTP clients. I need to implement a SFTP client as a web application in PHP. Does PHP support for SFTP? I couldn't find any samples. Can anyone help me with this?

Hygienics answered 14/1, 2011 at 9:16 Comment(0)
D
81

PHP has ssh2 stream wrappers (disabled by default), so you can use sftp connections with any function that supports stream wrappers by using ssh2.sftp:// for protocol, e.g.

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

or - when also using the ssh2 extension

$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');

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

On a side note, there is also quite a bunch of questions about this topic already:

Drill answered 14/1, 2011 at 9:26 Comment(6)
file_get_contents and file_put_contents both work awesome. never knew they worked with sftp and it's so much easier than using the built in sftp stuff. Thanks!Laurustinus
Even when using file_get_contents() you still need the ssh2 extension (afaik).Agadir
debian/ubuntu packages : apt install libssh2-1-dev php-ssh2Pegmatite
This answer doesn't seem correct. SFTP uses an encrypted private key to provide its security, so it requires the pathname of a private key and its passphrase in any PHP solution. The answer does not provide this functionality. I don't know why it got so many upvotes.Arcadia
@DavidSpector that depends only on settings of server. You can have regular USER/PASS combination even with SFTP/SSH.Roselba
I think you mean that you can have a password in addition to using SFTP. True.Arcadia
I
45

The ssh2 functions aren't very good. Hard to use and harder yet to install, using them will guarantee that your code has zero portability. My recommendation would be to use phpseclib, a pure PHP SFTP implementation.

Idiot answered 14/1, 2011 at 14:30 Comment(2)
@Hygienics would you mark this as the correct answer so that future users don't have to read comments to find which worked best for you?Batish
phpseclib isn't any easier to install, just my experienceSteed
E
33

I found that "phpseclib" should help you with this (SFTP and many more features). http://phpseclib.sourceforge.net/

To Put the file to the server, simply call (Code example from 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);
Earflap answered 1/5, 2014 at 14:36 Comment(2)
The git repo is here: github.com/phpseclib/phpseclib/tree/master/phpseclibLucilelucilia
Can you update your answer to phpseclib 2.0? Your current example is obsolete.Valentia
V
6

Install Flysystem v1:

composer require league/flysystem-sftp

Then:

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
....

Read:

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

Upgrade to v2:

https://flysystem.thephpleague.com/v2/docs/advanced/upgrade-to-2.0.0/

Install

 composer require league/flysystem-sftp:^2.0

Then:

//$filesystem->listFiles($path); // get file lists
$allFiles = $filesystem->listContents($path)
->filter(fn (StorageAttributes $attributes) => $attributes->isFile());

$filesystem->read($path_to_file); // grab file
//$filesystem->put($path); // upload file
$filesystem->write($path);
Velez answered 7/2, 2020 at 12:21 Comment(3)
Answer is no longer valid since the methods changed. No put or read available anymore!Rachelrachele
@Mr.Jo they are if you look at the v1 docsPhrase
@Phrase At StackOverflow we drive with the time I think. So it would be good to keep the answer updated.Rachelrachele
V
2

After messing around with PECL ssh2 I decided to take a look at phpseclib 3 and it worked out of the box. No installation on the server. I used composer to install it and put the code in. It has a ton of useful things and it's free. These are the steps:

  1. Run this composer install on your PHP app folder. I used VS Code and I opened a terminal window (need Composer to be installed on your machine first):

    composer require phpseclib/phpseclib:~3.0

  2. Use the basic example from here: https://phpseclib.com/docs/sftp

    use phpseclib3\Net\SFTP;

    $sftp = new SFTP('localhost');

    $sftp->login('username', 'password');

    $sftp->put('filename.remote', 'filename.local', SFTP::SOURCE_LOCAL_FILE);

Other useful links: GitHub: https://github.com/phpseclib/phpseclib and website: https://phpseclib.com/

Valuation answered 15/1, 2023 at 0:43 Comment(0)
H
-1

I performed a full-on cop-out and wrote a class which creates a batch file and then calls sftp via a system call. Not the nicest (or fastest) way of doing it but it works for what I need and it didn't require any installation of extra libraries or extensions in PHP.

Could be the way to go if you don't want to use the ssh2 extensions

Heterothallic answered 29/5, 2013 at 15:13 Comment(1)
related thread that helped me: groups.google.com/forum/#!topic/comp.security.ssh/_55TdDdUTCwMauritamauritania

© 2022 - 2024 — McMap. All rights reserved.