Uploading Data via SFTP Using libssh2 (PHP 5)
Last week, I had a chance to work on transferring some data to the office server via SFTP , and one of the requirements was to put an excel file onto the server via SFTP. The steps below were done in Ubuntu 14.04 LTS .
Initial Research
I started with doing google for php sftp . The first result shown was from the official PHP manual website (http://php.net/manual/en/function.ssh2-sftp.php). I clicked into the link and saw that PECL ssh2 is the main library used. I also noticed the two methods shown at the bottom of the page.
1 2 |
ssh2_scp_recv() - Request a file via SCP ssh2_scp_send() - Send a file via SCP |
Immediately, I clicked intossh2_scp_send()
and TADA, there were three lines of a simple code shown:
1 2 3 4 5 6 |
<?php $connection = ssh2_connect('shell.example.com', 22); ssh2_auth_password($connection, 'username', 'password'); ssh2_scp_send($connection, '/local/filename', '/remote/filename', 0644); |
Frankly, the code satisfied me I would say, it was very simple, clean, and simple to use. I, then, did copy the code as usual into my IDE and peacefully tried to run it. Guess what!, the life was not too easy as we always think, yeh? I got the first error:
Fatal error: Call to undefined function ssh2_connect()
Installing PECL SSH2
That error was about missing the SSH2 PECL
package, so I managed to install it by using:
1 2 |
sudo apt-get update sudo apt-get install libssh2-php |
Restart the web server:
1 2 3 4 5 6 7 |
// For Nginx user sudo service nginx restart OR // For Apache user sudo service apache2 restart |
That’s the steps I found from http://php.net/manual/en/ssh2.installation.php
However, for me, it didn’t work, I needed to add one more line into php.ini
:
1 |
extension=ssh2.so |
at the last line (with nano, the shortcut for going to the last line is ctrl+v+w ) and then restart php5-fpm
1 |
sudo service php5-fpm restart |
That’s it, that error has already disappeared; still, I got a new error instead.
1 |
ssh2_scp_send(): Failure creating remote file: Invalid ACK response from remote |
Final Code
After seeing the error, I was spending some time to find the cause, and it seemed to be that for some reasons, ssh2_scp_send() won’t work in all server[1]. Hence, as I saw many suggestions about using PHP’s fopen that already natively supports several protocols including SSH2[2], I decided to go for it, and this is my final code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?php // source absolute path $src = '/foo.txt'; // remote absolute path (make sure you have a write permission) $dest = '/some-dir/' . 'foo.txt'; $remoteAddress = 'shell.example.com'; $connection = ssh2_connect($remoteAddress, 22); ssh2_auth_password($connection, 'username', 'password'); $sftp = ssh2_sftp($connection); $sftpStream = fopen('ssh2.sftp://' . $sftp . $dest, 'w'); if (!$sftpStream) { throw new \Exception('Could not open remote file: ' . $dest); } try { $dataToSend = file_get_contents($src); fwrite($sftpStream, $dataToSend); fclose($sftpStream); } catch (\Exception $e) { // log error fclose($sftpStream); } |
References:
- http://board.phpbuilder.com/showthread.php?10352595-SSH-SCP-functions-not-working-with-a-certain-server
- http://php.net/manual/en/wrappers.php