I can successfully transfer files to and from my server using the following code:

$connection = ssh2_connect('hostname', 3222);
ssh2_auth_password($connection, 'username', 'password');

$sftp = ssh2_sftp($connection);

ssh2_scp_send($connection, '/local/directory/bug.gif', '/remote/directory/bug.gif', 0644);
ssh2_scp_recv($connection, '/remote/directory/bug.gif', '/local/directory/bug2.gif');

but when I try to do the same with a second server (have not tried a third) I get

Warning: ssh2_scp_send(): Failure creating remote file in /media/data/srv/www/test/sftp/prototype.php on line 8

Warning: ssh2_scp_recv(): Unable to receive remote file in /media/data/srv/www/test/sftp/prototype.php on line 9

The second server uses port 3222. I can in fact scp into this second server and transfer files via the command line as well as FileZilla and gFTP just fine. I do in fact have read/write permission on the target directory.

What's going on? Please help if possible--it's very urgent.

    a month later

    Hi,

    I have similar problem: ssh2_scp_send fails for absolutely no reason. In my case I have a loop through an array of files and sending them one by one to another server. In 80% of the times the first file fails to be sent, and the rest are transferred OK. The code I use is as simple as it can get:

    $fileList[0] = '/dir_name/file_01.txt';
    $fileList[1] = '/dir_name/file_02.txt';
    $fileList[2] = '/dir_name/file_03.txt';
    
    $conn = ssh2_connect('my.server.com', 22);
    ssh2_auth_password($conn, 'username', 'password');
    
    
    foreach ($fileList as $srcFile) {
    
    $dstFile = "/var/tmp" . $srcFile;
    
    // Create the directory first if not exist
    if (!$sshStream = ssh2_exec($conn, "mkdir -p '" . dirname($dstFile) . "';") ) {
    	echo "Failed to execute SSH2 command: [mkdir -p <filename>]";
    	continue;
    }
    stream_set_blocking( $sshStream, true );
    $res = stream_get_contents($sshStream);
    
    if ( !ssh2_scp_send($conn, $srcFile, $dstFile) ) {
    	echo "Failed to copy file [".$srcFile."] to [".$dstFile."].";
    }
    }
    

    I've spent a lot of time testing various things and another thing that puzzles me is that I cannot get any response from this either:

    if (!$sshStream = ssh2_exec($conn, "ls -l /var/tmp;") ) {
    	echo "Failed to execute SSH2 command: [mkdir -p <filename>]";
    }
    stream_set_blocking( $sshStream, true );
    echo stream_get_contents($sshStream);
    

    Echo is basically always empty.

    Any clues anyone?

    Cheers,

    Pimmy

      My problem was solved by using fopen + fwrite to send the file, and file_get_contents to download the file. Note these functions wrapped around the SSH and SFTP functionality. See the PHP docs for more details.

        Thanks very much. I've tried already the SFTP, but it doesnt work at all for me for some reason. Any chance for a snipped from your code?

        Cheers,

        Pimmy

          This will upload an image and download it again to another file. You may have to play around with the try/catch exception handling code (there may be a bug in this snippet).

          Note you should not need to have shell access enabled for this to work.

          $connection = ssh2_connect('host', 22);
          ssh2_auth_password($connection, 'user', 'pass');
          
          $sftp = ssh2_sftp($connection);
          
          $stream = @fopen("ssh2.sftp://$sftp/path/to/image.gif", 'w');
          
          try {
                  if (! $stream)
                      throw new Exception("Could not open file: $remote_file");
          
              $data_to_send = @file_get_contents("image.gif");
              if ($data_to_send === false)
                  throw new Exception("Could not open local file: $local_file.");
          
              if (@fwrite($stream, $data_to_send) === false)
                  throw new Exception("Could not send data from file: $local_file.");
          
          } catch (Exception $e) {
            echo $e->getMessage();
          }
          
          @fclose($stream);
          
          $data = file_get_contents("ssh2.sftp://$sftp/path/to/image.gif");
          
          print "Size of data: " . strlen($data);
          
          file_put_contents("image2.gif", $data);
          

            Thanks Chad,

            I will try this out today. I really appreciate your help.

            Cheers,
            Pimmy

              Hi Chad,

              It may sound strange, but SFTP read/write also fails on the first file. It fails around 90% of the tests, and only on the first file from the list - never on any other file. What or which file is the first one is also irrelevant.

              Can you or anyone else suggest what else can I do or any clues what could be causing this.

              Thanks,

              Pimmy

                Hi,

                It was all my bad: In a function which gets executed before the recursive file transfer I had the following:

                    if (!$sshStream = ssh2_exec($conn, "rm -rf '" . $rootPath . "';") ) {
                        echo "Failed to execute SSH2 command: [rm -rf <filename>]";
                        break;
                    }
                    stream_set_blocking( $sshStream, true );
                

                I wasnt reading the output from the command:

                $res = stream_get_contents($sshStream);
                

                In the PHP docs this actually is not mentioned anywhere, so I've excluded it as a possible cause of the problem. Anyway adding this line solved the problem.

                Just as a reference:

                sftp->fopen->file_get_contents->fwrite has much better performance than ssh2_scp_send
                

                So, thanks Chad..

                Cheers,

                Pimmy

                  Write a Reply...