Uploading a file to an SFTP server with PHP and curl

I was looking for a nice way of uploading a local file to a remote SFTP server with PHP today. I came across the ssh2 set of functions (e.g. http://php.net/ssh2_connect) which seem to fit the bill, but unfortunately the PECL package wasn’t PHP7-compatible.

An alternative was to use Curl. After a bit of messing around, I managed to get a working solution together which is summarised here:

        $dataFile      = '/path/to/file';
        $sftpServer    = 'sftp.foo.com';
        $sftpUsername  = 'user';
        $sftpPassword  = 'pass';
        $sftpPort      = 22;
        $sftpRemoteDir = '/files';

        $ch = curl_init('sftp://' . $sftpServer . ':' . $sftpPort . $sftpRemoteDir . '/' . basename($dataFile));

        $fh = fopen($dataFile, 'r');

        if ($fh) {
            curl_setopt($ch, CURLOPT_USERPWD, $sftpUsername . ':' . $sftpPassword);
            curl_setopt($ch, CURLOPT_UPLOAD, true);
            curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_SFTP);
            curl_setopt($ch, CURLOPT_INFILE, $fh);
            curl_setopt($ch, CURLOPT_INFILESIZE, filesize($dataFile));
            curl_setopt($ch, CURLOPT_VERBOSE, true);

            $verbose = fopen('php://temp', 'w+');
            curl_setopt($ch, CURLOPT_STDERR, $verbose);

            $response = curl_exec($ch);
            $error = curl_error($ch);
            curl_close($ch);

            if ($response) {
                echo "Success";
            } else {
                echo "Failure";
                rewind($verbose);
                $verboseLog = stream_get_contents($verbose);
                echo "Verbose information:\n" . $verboseLog . "\n";
            }
        }

Note the use of the CURLOPT_VERBOSE option which can be handy for debugging failed connections.

Looking for reliable PHP hosting?. I can thoroughly recommend Linode.

Glen Scott

I’m a freelance software developer with 18 years’ professional experience in web development. I specialise in creating tailor-made, web-based systems that can help your business run like clockwork. I am the Managing Director of Yellow Square Development.

More Posts

Follow Me:
TwitterFacebookLinkedIn

14 thoughts on “Uploading a file to an SFTP server with PHP and curl

  1. alinton

    Thanks you for help, good worked….. i am used match method for connect Sftp, but i have a problem: can you help me?
    FailureVerbose information: * Initialized password authentication * Authentication complete * Upload failed: No such file or directory (2/-31) * Connection #4 to host sftp.xxxxxxx.com left intact

    Reply
    1. LesD

      I have had such errors in the past. Caused by either permission issues or not understanding where SFTP is actually uploading to. Try uploading to just the ‘root’ path ‘/’ and see where the file ends up.

      Reply
  2. LesD

    Perfect!

    I hunted high and low for SFTP uploads from PHP and all were problematic – requiring external packages.

    This worked first time!

    Many thanks

    Reply
  3. Aaron Cook

    This worked Great! I searched for 2 days for a solution for SFTP file transfer and tried atleast 10 different options. This worked right out of the box. You sir are a genius!

    Reply
  4. Fred

    I get
    SSH public key authentication failed: Unable to extract public key from private key file: Unable to open private key file

    Reply
  5. ivan

    hi, the script works for a short period of time. Its supposed to download a 1.9MB file and its only 16kb when put to the server.
    Hosting support says this is the error:

    RELINQUISH PRIVS: unable to seteuid(PR_ROOT_UID): Operation not permitted
    say the script is trying to change folder / file permissions which is not allowed.

    any clue? thanks.

    Reply
  6. Gary Webb

    Hi Glenn
    Great script.
    Is there a way to take a look and see if the uploaded file exists on the remote server?
    I have read that there is no function to do that in curl

    Reply
  7. Bruno B

    Hello ,I used this script under windows 2016 / Apache 2.4.38 (Win64) OpenSSL/1.1.1a
    php 7.3.6 with curl 7.64.0 and libssh2/1.8.2 I have the following error. I’m trying for a couple of hours and getting crasy …. Thanks for any help * Connected to cloudftp.xxxxxx.com (yy.yy.yy.yyy) port 22 (#0)
    * SSH MD5 fingerprint: xx1x1x11x1x11xx11x1x1x1x1x1
    * SSH authentication methods available: password,publickey
    * Using SSH private key file ”
    * SSH public key authentication failed: Unable to extract public key from private key file: Unable to open private key file
    * Initialized password authentication
    * Authentication complete
    * Upload failed: Operation failed (4/-31)
    * Connection #0 to host cloudftp.xxxxxx.com left intact

    Reply
  8. Roma

    Good morning,
    Thank you, the solution worked like a charm!
    How does one confirm the file integrity i.e. the file got uploaded to remote server?
    How do you check the file size on remote server after its uploaded using curl?
    Thanks,
    Roma

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.