phpseclib\Net\SFTP::put PHP Method

put() public method

By default, \phpseclib\Net\SFTP::put() does not read from the local filesystem. $data is dumped directly into $remote_file. So, for example, if you set $data to 'filename.ext' and then do \phpseclib\Net\SFTP::get(), you will get a file, twelve bytes long, containing 'filename.ext' as its contents. Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior. With self::SOURCE_LOCAL_FILE, $remote_file will contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how large $remote_file will be, as well. Setting $mode to self::SOURCE_CALLBACK will use $data as callback function, which gets only one parameter -- number of bytes to return, and returns a string if there is some data or null if there is no more data If $data is a resource then it'll be used as a resource instead. Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take care of that, yourself. $mode can take an additional two parameters - self::RESUME and self::RESUME_START. These are bitwise AND'd with $mode. So if you want to resume upload of a 300mb file on the local file system you'd set $mode to the following: self::SOURCE_LOCAL_FILE | self::RESUME If you wanted to simply append the full contents of a local file to the full contents of a remote file you'd replace self::RESUME with self::RESUME_START. If $mode & (self::RESUME | self::RESUME_START) then self::RESUME_START will be assumed. $start and $local_start give you more fine grained control over this process and take precident over self::RESUME when they're non-negative. ie. $start could let you write at the end of a file (like self::RESUME) or in the middle of one. $local_start could let you start your reading from the end of a file (like self::RESUME_START) or in the middle of one. Setting $local_start to > 0 or $mode | self::RESUME_START doesn't do anything unless $mode | self::SOURCE_LOCAL_FILE.
public put ( string $remote_file, string | resource $data, integer $mode = self::SOURCE_STRING, integer $start, integer $local_start, callable | null $progressCallback = null ) : boolean
$remote_file string
$data string | resource
$mode integer
$start integer
$local_start integer
$progressCallback callable | null
return boolean
    function put($remote_file, $data, $mode = self::SOURCE_STRING, $start = -1, $local_start = -1, $progressCallback = null)
    {
        if (!($this->bitmap & SSH2::MASK_LOGIN)) {
            return false;
        }
        $remote_file = $this->_realpath($remote_file);
        if ($remote_file === false) {
            return false;
        }
        $this->_remove_from_stat_cache($remote_file);
        $flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE;
        // according to the SFTP specs, NET_SFTP_OPEN_APPEND should "force all writes to append data at the end of the file."
        // in practice, it doesn't seem to do that.
        //$flags|= ($mode & self::RESUME) ? NET_SFTP_OPEN_APPEND : NET_SFTP_OPEN_TRUNCATE;
        if ($start >= 0) {
            $offset = $start;
        } elseif ($mode & self::RESUME) {
            // if NET_SFTP_OPEN_APPEND worked as it should _size() wouldn't need to be called
            $size = $this->size($remote_file);
            $offset = $size !== false ? $size : 0;
        } else {
            $offset = 0;
            $flags |= NET_SFTP_OPEN_TRUNCATE;
        }
        $packet = pack('Na*N2', strlen($remote_file), $remote_file, $flags, 0);
        if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {
            return false;
        }
        $response = $this->_get_sftp_packet();
        switch ($this->packet_type) {
            case NET_SFTP_HANDLE:
                $handle = substr($response, 4);
                break;
            case NET_SFTP_STATUS:
                $this->_logError($response);
                return false;
            default:
                throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
        }
        // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3
        $dataCallback = false;
        switch (true) {
            case $mode & self::SOURCE_CALLBACK:
                if (!is_callable($data)) {
                    throw new \BadFunctionCallException("\$data should be is_callable() if you specify SOURCE_CALLBACK flag");
                }
                $dataCallback = $data;
                // do nothing
                break;
            case is_resource($data):
                $mode = $mode & ~self::SOURCE_LOCAL_FILE;
                $fp = $data;
                break;
            case $mode & self::SOURCE_LOCAL_FILE:
                if (!is_file($data)) {
                    throw new FileNotFoundException("{$data} is not a valid file");
                }
                $fp = @fopen($data, 'rb');
                if (!$fp) {
                    return false;
                }
        }
        if (isset($fp)) {
            $stat = fstat($fp);
            $size = $stat['size'];
            if ($local_start >= 0) {
                fseek($fp, $local_start);
                $size -= $local_start;
            }
        } elseif ($dataCallback) {
            $size = 0;
        } else {
            $size = strlen($data);
        }
        $sent = 0;
        $size = $size < 0 ? ($size & 0x7fffffff) + 0x80000000 : $size;
        $sftp_packet_size = 4096;
        // PuTTY uses 4096
        // make the SFTP packet be exactly 4096 bytes by including the bytes in the NET_SFTP_WRITE packets "header"
        $sftp_packet_size -= strlen($handle) + 25;
        $i = 0;
        while ($dataCallback || ($size === 0 || $sent < $size)) {
            if ($dataCallback) {
                $temp = call_user_func($dataCallback, $sftp_packet_size);
                if (is_null($temp)) {
                    break;
                }
            } else {
                $temp = isset($fp) ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size);
                if ($temp === false || $temp === '') {
                    break;
                }
            }
            $subtemp = $offset + $sent;
            $packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp);
            if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet)) {
                if ($mode & self::SOURCE_LOCAL_FILE) {
                    fclose($fp);
                }
                return false;
            }
            $sent += strlen($temp);
            if (is_callable($progressCallback)) {
                call_user_func($progressCallback, $sent);
            }
            $i++;
            if ($i == NET_SFTP_QUEUE_SIZE) {
                if (!$this->_read_put_responses($i)) {
                    $i = 0;
                    break;
                }
                $i = 0;
            }
        }
        if (!$this->_read_put_responses($i)) {
            if ($mode & self::SOURCE_LOCAL_FILE) {
                fclose($fp);
            }
            $this->_close_handle($handle);
            return false;
        }
        if ($mode & self::SOURCE_LOCAL_FILE) {
            fclose($fp);
        }
        return $this->_close_handle($handle);
    }

Usage Example

Esempio n. 1
0
 /**
  * @return bool
  *
  * @throws \Exception
  */
 public function send()
 {
     $sent = true;
     $files = $this->backup->getFilesTobackup();
     if (!empty($files)) {
         foreach ($files as $file => $name) {
             $upload = $this->connection->put($this->folder . '/' . $name, $file, LibSFTP::SOURCE_LOCAL_FILE);
             if (!$upload) {
                 $sent = false;
                 echo 'SFTP upload manqu�e de ' . $file . ' vers ' . $this->folder . $name;
             }
         }
     }
     $streams = $this->backup->getStreamsTobackup();
     if (!empty($streams)) {
         foreach ($streams as $name => $stream) {
             $upload = $this->connection->put($this->folder . '/' . $name, $stream);
             if (!$upload) {
                 echo 'SFTP upload manqu�e de ' . $name . ' vers ' . $this->folder . $name;
                 $sent = false;
             }
         }
     }
     if (!$sent) {
         throw new \Exception('At least an upload didnt work.');
     }
     return $sent;
 }
All Usage Examples Of phpseclib\Net\SFTP::put