Created
September 19, 2018 18:47
-
-
Save ghassani/36dd8b592c58d97ec21ad268d850d7bb to your computer and use it in GitHub Desktop.
PHP FTP, SFTP, and SSH2 Function Wrappers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @class FtpClient | |
* | |
* Example usage: | |
* $host = 'ftp.mivamerchantdev.com'; | |
* $port = 21; | |
* $username = 'myusername'; | |
* $password = 'mypassword'; | |
* | |
* $ftp = new FtpClient($host, $username, $password, $port, array( | |
* 'passive' => true, | |
* 'blocking' => false, | |
* 'mode' => FTP_BINARY, | |
* 'timeout' => 90, | |
* )); | |
* | |
* Alternately: | |
* $ftp = new FtpClient($host, $username, $password, $port); | |
* $ftp->setPassiveMode(true); | |
* $ftp->setMode(FTP_BINARY); | |
* $ftp->setNonBlocking(true); | |
* | |
* Then Connect: | |
* $ftp->connect(); | |
* | |
* Get directory contents: | |
* $directoryContents = $ftp->ls('/'); | |
* | |
* Get File contents: | |
* $fileContent = $ftp->getFileData('/path/to/remote/file'); | |
* | |
* Save file localy: | |
* $result = $ftp->get('/path/to/local/file', '/path/to/remote/file'); | |
* | |
* Save file to fp: | |
* $fp = fopen('some/file','a+'); | |
* $result = $ftp->fget($fp, '/path/to/remote/file'); | |
* | |
* Put a file from variable: | |
* $data = loaded_from_somewhere(); | |
* $ftp->putFileData($data, '/path/to/remote/file'); | |
* | |
* Put file from path: | |
* $ftp->put('/path/to/remote/file', '/path/to/local/file'); | |
* | |
* Put file from fp: | |
* $fp = fopen('some/file','a+'); | |
* $ftp->put('/path/to/remote/file', $fp); | |
* | |
* Disconnect: | |
* Class will auto disconnect on destruction | |
* Manually disconnect: | |
* $ftp->disconnect(); | |
*/ | |
class FtpClient | |
{ | |
protected $host; | |
protected $username; | |
protected $password; | |
protected $port; | |
protected $isConnected = false; | |
protected $blocking = false; | |
protected $ssl = false; | |
protected $passive = true; | |
protected $ignorePassiveAddress = false; | |
protected $timeout = 90; | |
protected $mode = FTP_ASCII; | |
protected $handle = false; | |
/** | |
* @param $host | |
* @param $username | |
* @param $password | |
* @param int $port | |
*/ | |
public function __construct($host, $username = null, $password = null, $port = 21, array $options = array()) | |
{ | |
$this->host = $host; | |
$this->username = $username; | |
$this->password = $password; | |
foreach (array('ssl', 'passive', 'timeout', 'blocking', 'mode', 'ignorePassiveAddress') as $availableOption) { | |
if (isset($options[$availableOption])) { | |
$this->$availableOption = $options[$availableOption]; | |
} | |
} | |
if(!defined('FTP_USEPASVADDRESS')) { | |
define('FTP_USEPASVADDRESS', 2); | |
} | |
} | |
/** | |
* Destructor | |
* | |
* Will disconnect from the server if connected | |
*/ | |
public function __destruct() | |
{ | |
if ($this->isConnected()) { | |
$this->disconnect(); | |
} | |
} | |
/** | |
* getHost | |
* | |
* @return string | |
*/ | |
public function getHost() | |
{ | |
return $this->host; | |
} | |
/** | |
* setHost | |
* | |
* @param string $host | |
*/ | |
public function setHost($host) | |
{ | |
$this->host = $host; | |
return $this; | |
} | |
/** | |
* getUsername | |
* | |
* @return string | |
*/ | |
public function getUsername() | |
{ | |
return $this->username; | |
} | |
/** | |
* setUsername | |
* | |
* @param string $username | |
*/ | |
public function setUsername($username) | |
{ | |
$this->username = $username; | |
return $this; | |
} | |
/** | |
* getPassword | |
* | |
* @return string | |
*/ | |
public function getPassword() | |
{ | |
return $this->password; | |
} | |
/** | |
* getPassword | |
* | |
* @param string $password | |
*/ | |
public function setPassword($password) | |
{ | |
$this->password = $password; | |
return $this; | |
} | |
/** | |
* getPort | |
* | |
* @return int | |
*/ | |
public function getPort() | |
{ | |
return $this->port; | |
} | |
/** | |
* setPort | |
* | |
* @param int $port | |
*/ | |
public function setPort($port) | |
{ | |
$this->port = $port; | |
return $this; | |
} | |
public function setMode($mode) | |
{ | |
if (!in_array($mode, array(FTP_ASCII, FTP_BINARY))) { | |
throw new \InvalidArgumentExecption(sprintf('Invalid mode specified. Valid values are FTP_ASCII (%d) and FTP_BINARY (%d)', | |
FTP_ASCII, | |
FTP_BINARY | |
)); | |
} | |
$this->mode = $mode; | |
return $this; | |
} | |
/** | |
* getMode | |
* | |
* @return int | |
*/ | |
public function getMode() | |
{ | |
return $this->mode; | |
} | |
/** | |
* isNonBlocking | |
* | |
* If this session should use non blocking operations or not | |
* | |
* @return boolean | |
*/ | |
public function isNonBlocking() | |
{ | |
return !$this->blocking; | |
} | |
/** | |
* setIsNonBlocking | |
* | |
* Set ff this session should use non blocking operations or not | |
* | |
* @param boolean $nonBlocking | |
*/ | |
public function setNonBlocking($blocking) | |
{ | |
$this->blocking = ((bool)!$blocking); | |
return $this; | |
} | |
/** | |
* getTimeout | |
* | |
* @return int | |
*/ | |
public function getTimeout() | |
{ | |
return $this->timeout; | |
} | |
/** | |
* setTimeout | |
* | |
* @param int $timeout | |
*/ | |
public function setTimeout($timeout) | |
{ | |
$this->timeout = $timeout; | |
return $this; | |
} | |
/** | |
* isPassive | |
* | |
* @return boolean | |
*/ | |
public function isPassiveMode() | |
{ | |
return $this->passive; | |
} | |
/** | |
* setPassiveMode | |
* | |
* Set connection mode to passive or not | |
* | |
* @param boolean $passive | |
*/ | |
public function setPassiveMode($passive) | |
{ | |
$this->passive = $passive; | |
if ($this->isConnected()) { | |
ftp_set_option($this->handle, FTP_USEPASVADDRESS, $this->getIgnorePassiveAddress()); | |
ftp_pasv($this->handle, true); | |
} | |
} | |
/** | |
* setIgnorePassiveAddress | |
*/ | |
public function setIgnorePassiveAddress($value) | |
{ | |
$this->ignorePassiveAddress = (bool) $value; | |
return $this; | |
} | |
/** | |
* getIgnorePassiveAddress | |
*/ | |
public function getIgnorePassiveAddress() | |
{ | |
return $this->ignorePassiveAddress; | |
} | |
/** | |
* isSsl | |
* | |
* If this connection is (or is to) use SSL to connect | |
* | |
* @return boolean | |
*/ | |
public function isSsl() | |
{ | |
return $this->ssl; | |
} | |
/** | |
* setSsl | |
* | |
* Set the connection to use SSL or not | |
* | |
* @param boolean $ssl | |
*/ | |
public function setSsl($ssl) | |
{ | |
$this->ssl = $ssl; | |
return $this; | |
} | |
/** | |
* isConnected | |
* | |
* @return bool | |
*/ | |
public function isConnected() | |
{ | |
return is_resource($this->handle); | |
} | |
/** | |
* connect | |
* | |
* Connect to the server with provided credentials and settings | |
* | |
* @throws \Exception - When can't connect | |
*/ | |
public function connect() | |
{ | |
if ($this->isSsl()) { | |
$this->handle = ftp_ssl_connect( | |
$this->getHost(), | |
$this->getPort(), | |
$this->getTimeout() | |
); | |
} else { | |
$this->handle = ftp_connect( | |
$this->getHost(), | |
$this->getPort(), | |
$this->getTimeout() | |
); | |
} | |
if (false === $this->handle) { | |
throw new \Exception(sprintf('Could not connect to %s on port %d', | |
$this->getHost(), | |
$this->getPort() | |
)); | |
} | |
if ($this->getUsername() && $this->getPassword()) { | |
ftp_login($this->handle, $this->getUsername(), $this->getPassword()); | |
} | |
ftp_set_option($this->handle, FTP_USEPASVADDRESS, $this->getIgnorePassiveAddress()); | |
if ($this->isPassiveMode()) { | |
ftp_pasv($this->handle, true); | |
} | |
} | |
/** | |
* disconnect | |
* | |
* Disconnect from the server, if connected | |
* | |
* @return void | |
*/ | |
public function disconnect() | |
{ | |
if ($this->isConnected()) { | |
ftp_close($this->handle); | |
} | |
$this->handle = false; | |
} | |
/** | |
* ls | |
* | |
* List a directories contents | |
* | |
* @param $path | |
* @return array|bool | |
*/ | |
public function ls($path) | |
{ | |
if (!$this->isConnected()) { | |
return false; | |
} | |
return ftp_nlist($this->handle, $path); | |
} | |
/** | |
* mkdir | |
* | |
* Create a directory | |
* | |
* @param $path | |
* @return bool|string | |
*/ | |
public function mkdir($path) | |
{ | |
if (!$this->isConnected()) { | |
return false; | |
} | |
return ftp_mkdir($this->handle, $path); | |
} | |
/** | |
* rmdir | |
* | |
* Remove a directory | |
* | |
* @param $path | |
* @return bool | |
*/ | |
public function rmdir($path) | |
{ | |
if (!$this->isConnected()) { | |
return false; | |
} | |
return ftp_rmdir($this->handle, $path); | |
} | |
/** | |
* fget | |
* | |
* Transfers a remote file to a local file handle. It will read from the remote | |
* file starting at specified $resumepos | |
* | |
* @param $fp | |
* @param $remoteFile | |
* @param int $resumepos | |
* @return bool | |
*/ | |
public function fget($fp, $remoteFile, $resumepos = 0) | |
{ | |
if (!$this->isConnected()) { | |
return false; | |
} | |
if (!is_resource($fp)) { | |
throw new \InvalidArgumentException('Provided file handle is not a valid resource'); | |
} | |
if ($this->isNonBlocking()) { | |
$ret = ftp_nb_fget($this->handle, $fp, $remoteFile, $this->getMode(), $resumepos); | |
} else { | |
$ret = ftp_fget($this->handle, $fp, $remoteFile, $this->getMode(), $resumepos); | |
} | |
while($this->isNonBlocking() && $ret == FTP_MOREDATA) { | |
$ret = ftp_nb_continue($this->handle); | |
} | |
return $ret == FTP_FINISHED ? true : false; | |
} | |
/** | |
* fput | |
* | |
* Transfers a file to specified remote path given a handle to an | |
* open file with fopen. Operation will read from the file descriptor | |
* to load data starting at specified $start offset. | |
* | |
* @param $remoteFile | |
* @param $fp | |
* @param int $start | |
* @return bool | |
*/ | |
public function fput($remoteFile, $fp, $start = 0 ) | |
{ | |
if (!$this->isConnected()) { | |
return false; | |
} | |
if (!is_resource($fp)) { | |
throw new \InvalidArgumentException('Provided file handle is not a valid resource'); | |
} | |
if ($this->isNonBlocking()) { | |
$ret = ftp_nb_fput($this->handle, $remoteFile, $fp, $this->getMode(), $start); | |
} else { | |
$ret = ftp_fput($this->handle, $remoteFile, $fp, $this->getMode(), $start); | |
} | |
while($this->isNonBlocking() && $ret == FTP_MOREDATA) { | |
$ret = ftp_nb_continue($this->handle); | |
} | |
return $ret == FTP_FINISHED ? true : false; | |
} | |
/** | |
* get | |
* | |
* Transfers a file to specified local path given a remote path | |
* to a file | |
* | |
* @param $localFile | |
* @param $remoteFile | |
* @param int $resumepos | |
* @return bool | |
*/ | |
public function get($localFile, $remoteFile, $resumepos = 0) | |
{ | |
if ($this->isNonBlocking()) { | |
$ret = ftp_nb_get($this->handle, $localFile, $remoteFile, $this->getMode(), $resumepos); | |
} else { | |
$ret = ftp_get($this->handle, $localFile, $remoteFile, $this->getMode(), $resumepos); | |
} | |
while($this->isNonBlocking() && $ret == FTP_MOREDATA) { | |
$ret = ftp_nb_continue($this->handle); | |
} | |
return $ret == FTP_FINISHED ? true : false; | |
} | |
/** | |
* getFileData | |
* | |
* Get a remote file and return its contents as a variable | |
* | |
* @param unknown $remoteFile | |
* @param number $resumepos | |
* @return boolean|Ambigous <NULL, string> | |
*/ | |
public function getFileData($remoteFile, $resumepos = 0) | |
{ | |
$tmpFile = tempnam(sys_get_temp_dir(), "Ftp_getFileData"); | |
$temp = fopen($tmpFile, 'a+'); | |
$fileSize = $this->getSize($remoteFile); | |
if (!$fileSize) { | |
return false; | |
} | |
$ret = $this->fget($temp, $remoteFile, $resumepos); | |
$contents = null; | |
if ($ret == FTP_FINISHED) { | |
fseek($temp, 0); | |
$contents = fread($temp, $fileSize); | |
} | |
fclose($temp); | |
unlink($tmpFile); | |
return $contents; | |
} | |
/** | |
* put | |
* | |
* Transfers a file to specified remote path given a local path | |
* to a file | |
* | |
* @param $remoteFile | |
* @param $localFile | |
* @param int $resumepos | |
* @return bool | |
*/ | |
public function put($remoteFile, $localFile, $resumepos = 0) | |
{ | |
if ($this->isNonBlocking()) { | |
$ret = ftp_nb_put($this->handle, $remoteFile, $localFile, $this->getMode(), $resumepos); | |
} else { | |
$ret = ftp_put($this->handle, $remoteFile, $localFile, $this->getMode(), $resumepos); | |
} | |
while($this->isNonBlocking() && $ret == FTP_MOREDATA) { | |
$ret = ftp_nb_continue($this->handle); | |
} | |
return $ret == FTP_FINISHED ? true : false; | |
} | |
/** | |
* putFileData | |
* | |
* Put data in a string into a remote file | |
* | |
* @param unknown $data | |
* @param unknown $remoteFile | |
* @param number $resumepos | |
* @return boolean | |
*/ | |
public function putFileData($data, $remoteFile, $resumepos = 0) | |
{ | |
$tmpFile = tempnam(sys_get_temp_dir(), "Ftp_getFileData"); | |
$temp = fopen($tmpFile, 'a+'); | |
fwrite($temp, $data, strlen($data)); | |
fseek($temp, 0); | |
$ret = $this->fput($remoteFile, $temp, $resumepos); | |
fclose($temp); | |
unlink($tmpFile); | |
return $ret == FTP_FINISHED ? true : false; | |
} | |
/** | |
* @return bool|string | |
*/ | |
public function getPwd() | |
{ | |
if (!$this->isConnected()) { | |
return false; | |
} | |
return ftp_pwd($this->handle); | |
} | |
/** | |
* @return bool|string | |
*/ | |
public function getSystype() | |
{ | |
if (!$this->isConnected()) { | |
return false; | |
} | |
return ftp_systype($this->handle); | |
} | |
/** | |
* @param $remotePath | |
* @return bool|int | |
*/ | |
public function getLastModified($remotePath) | |
{ | |
if (!$this->isConnected()) { | |
return false; | |
} | |
return ftp_mdtm($this->handle, $remotePath); | |
} | |
/** | |
* @param $remotePath | |
* @return bool|int | |
*/ | |
public function getSize($remotePath) | |
{ | |
if (!$this->isConnected()) { | |
return false; | |
} | |
return ftp_size($this->handle, $remotePath); | |
} | |
/** | |
* exec | |
* | |
* Sends a SITE EXEC command request to the FTP server. | |
* | |
* @param $command | |
* @return bool | |
*/ | |
public function exec($command) | |
{ | |
if (!$this->isConnected()) { | |
return false; | |
} | |
return ftp_exec($this->handle, $command); | |
} | |
/** | |
* sendCommand | |
* | |
* Send a raw command to the server | |
* | |
* @param $command | |
* @return bool|int | |
*/ | |
public function sendCommand($command) | |
{ | |
if (!$this->isConnected()) { | |
return false; | |
} | |
return ftp_raw($this->handle, $command); | |
} | |
} | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class SftpClient extends Ssh2Client | |
{ | |
protected $sftpHandle = null; | |
/** | |
* connect | |
* @see Ssh2Client::connect() | |
*/ | |
public function connect() | |
{ | |
parent::connect(); | |
ssh2_sftp($this->handle); | |
} | |
/** | |
* isConnected | |
* @see Ssh2Client::isConnected() | |
*/ | |
public function isConnected() | |
{ | |
return parent::isConnected() && is_resource($this->sftpHandle); | |
} | |
/** | |
* chmod | |
* | |
* Change a file/directory permissions | |
* @param string $path | |
* @param string $mode | |
*/ | |
public function chmod($path, $mode) | |
{ | |
return ssh2_sftp_chmod($this->sftpHandle, $path, $mode); | |
} | |
/** | |
* lstat | |
* | |
* Get information on a symbolic link | |
* | |
* @param string $path | |
*/ | |
public function lstat($path) | |
{ | |
return ssh2_sftp_lstat($this->sftpHandle, $path); | |
} | |
/** | |
* mkdir | |
* | |
* Create a directory | |
* | |
* @param string $path | |
* @param string $mode | |
* @param string $recursive | |
*/ | |
public function mkdir($path, $mode, $recursive = false) | |
{ | |
return ssh2_sftp_mkdir($this->sftpHandle, $path, $mode = 0644, $recursive); | |
} | |
/** | |
* readlink | |
* | |
* Read a symlink and get its true path | |
* | |
* @param string $path | |
* @param string $mode | |
* @param string $recursive | |
*/ | |
public function readlink($path) | |
{ | |
return ssh2_sftp_readlink($this->sftpHandle, $path); | |
} | |
/** | |
* realpath | |
* | |
* Get a file/directories real path | |
* | |
* @param string $path | |
* @return string | |
*/ | |
public function realpath($path) | |
{ | |
return ssh2_sftp_realpath($this->sftpHandle, $path); | |
} | |
/** | |
* rename | |
* | |
* Rename a file/directory | |
* | |
* @param unknown $from | |
* @param unknown $to | |
*/ | |
public function rename($from, $to) | |
{ | |
return ssh2_sftp_rename($this->sftpHandle, $from, $to); | |
} | |
/** | |
* rmdir | |
* | |
* Remove a directory | |
* | |
* @param string $path | |
*/ | |
public function rmdir($path) | |
{ | |
return ssh2_sftp_rmdir($this->sftpHandle, $path); | |
} | |
/** | |
* stat | |
* | |
* Get information on a file/directory | |
* | |
* @param string $path | |
*/ | |
public function stat($path) | |
{ | |
return ssh2_sftp_stat($this->sftpHandle, $path); | |
} | |
/** | |
* symlink | |
* | |
* Create a symlink | |
* | |
* @param string $from | |
* @param string $to | |
*/ | |
public function symlink($from, $to) | |
{ | |
return ssh2_sftp_symlink($this->sftpHandle, $from, $to); | |
} | |
/** | |
* unlink | |
* | |
* Delete a file | |
* | |
* @param string $path | |
*/ | |
public function unlink($path) | |
{ | |
return ssh2_sftp_unlink($this->sftpHandle, $path); | |
} | |
} | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Ssh2Client | |
{ | |
const AUTH_TYPE_NONE = 0; | |
const AUTH_TYPE_PASSWORD = 1; | |
const AUTH_TYPE_KEY = 2; | |
protected $host = null; | |
protected $username = null; | |
protected $password = null; | |
protected $port = 22; | |
protected $isConnected = false; | |
protected $handle = false; | |
protected $methods = array( | |
'kex' => 'diffie-hellman-group1-sha1', | |
'client_to_server' => array( | |
'crypt' => '3des-cbc', | |
'comp' => 'none' | |
), | |
'server_to_client' => array( | |
'crypt' => 'aes256-cbc,aes192-cbc,aes128-cbc', | |
'comp' => 'none' | |
) | |
); | |
protected $callbacks = array(); | |
protected $environment = array(); | |
protected $shellWidth = SSH2_DEFAULT_TERM_WIDTH; | |
protected $shellHeight = SSH2_DEFAULT_TERM_HEIGHT; | |
protected $shellType = SSH2_TERM_UNIT_CHARS; | |
protected $authType = self::AUTH_TYPE_PASSWORD; | |
protected $isAuthenticated = false; | |
protected $key = array(); | |
/** | |
* @param string $host | |
* @param string $username | |
* @param string $password | |
* @param int $port | |
* @param array $environment | |
*/ | |
public function __construct($host, $username = null, $password = null, $port = 22, array $environment = array()) | |
{ | |
if (!function_exists('ssh2_connect')) { | |
throw new Exception('This utility class requires the ssh2 extension'); | |
} | |
$this->host = $host; | |
$this->username = $username; | |
$this->password = $password; | |
$this->port = $port; | |
$this->environment = $environment; | |
} | |
/** | |
* Destructor | |
* | |
* Will disconnect from the server if connected | |
*/ | |
public function __destruct() | |
{ | |
if ($this->isConnected()) { | |
$this->disconnect(); | |
} | |
} | |
/** | |
* setAuthType | |
* | |
* @param int $type | |
* @throws Exception | |
* @return Ssh2Client | |
*/ | |
public function setAuthType($type) | |
{ | |
if (!in_array($type, array(static::AUTH_TYPE_NONE, static::AUTH_TYPE_PASSWORD, static::AUTH_TYPE_KEY))) { | |
throw new Exception(sprintf('Specified authentication type %d is invalid', $type)); | |
} | |
$this->authType = $type; | |
return $this; | |
} | |
/** | |
* getAuthType | |
* | |
* @return int | |
*/ | |
public function getAuthType() | |
{ | |
return $this->authType; | |
} | |
/** | |
* getHost | |
* | |
* @return string | |
*/ | |
public function getHost() | |
{ | |
return $this->host; | |
} | |
/** | |
* setHost | |
* | |
* @param string $host | |
*/ | |
public function setHost($host) | |
{ | |
$this->host = $host; | |
return $this; | |
} | |
/** | |
* getUsername | |
* | |
* @return string | |
*/ | |
public function getUsername() | |
{ | |
return $this->username; | |
} | |
/** | |
* setUsername | |
* | |
* @param string $username | |
*/ | |
public function setUsername($username) | |
{ | |
$this->username = $username; | |
return $this; | |
} | |
/** | |
* getPassword | |
* | |
* @return string | |
*/ | |
public function getPassword() | |
{ | |
return $this->password; | |
} | |
/** | |
* getPassword | |
* | |
* @param string $password | |
*/ | |
public function setPassword($password) | |
{ | |
$this->password = $password; | |
return $this; | |
} | |
/** | |
* setKey | |
* | |
* @param string $publicKeyPath | |
* @param string $privateKeyPath | |
* @param string $secret - If the private key is encrypted with a password. | |
* | |
* @return Ssh2Client | |
*/ | |
public function setKey($publicKeyPath, $privateKeyPath, $secret = null) | |
{ | |
$this->key = array( | |
'public' => $publicKeyPath, | |
'private' => $privateKeyPath, | |
'secret' => $secret | |
); | |
return $this; | |
} | |
/** | |
* getKey | |
* | |
* Get the set public/private key pair for authentication | |
* | |
* @return array | |
*/ | |
public function getKey() | |
{ | |
return $this->key; | |
} | |
/** | |
* setShellOptions | |
* @param int $width | |
* @param int $height | |
* @param int $type - One of SSH2_TERM_UNIT_* | |
* @return Ssh2Client | |
*/ | |
public function setShellOptions($width, $height, $type) | |
{ | |
if (!in_array($type, array(SSH2_TERM_UNIT_CHARS, SSH2_TERM_UNIT_PIXELS))) { | |
throw new InvalidArgumentException(sprintf('Shell type %d is invalid. | |
Valid values are SSH2_TERM_UNIT_CHARS and SSH2_TERM_UNIT_PIXELS', $type)); | |
} | |
$this->shellWidth = $width; | |
$this->shellHeight = $height; | |
$this->shellType = $type; | |
return $this; | |
} | |
/** | |
* getPort | |
* | |
* @return int | |
*/ | |
public function getPort() | |
{ | |
return $this->port; | |
} | |
/** | |
* setPort | |
* | |
* @param int $port | |
*/ | |
public function setPort($port) | |
{ | |
$this->port = $port; | |
return $this; | |
} | |
/** | |
* connect | |
* | |
* @throws Exception | |
* @return boolean | |
*/ | |
public function connect() | |
{ | |
$callbacks = count($this->callbacks) ? $this->callbacks : array( | |
'disconnect' => array($this, 'disconnect'), | |
'macerror' => array($this, 'onError') | |
); | |
$this->handle = ssh2_connect($this->getHost(), $this->getPort(), $this->methods, $callbacks); | |
if (!$this->isConnected()) { | |
return false; | |
} | |
$auth = false; | |
// authenicate if needed | |
if ($this->getAuthType() == static::AUTH_TYPE_KEY) { | |
if (!$this->getUsername() || !$this->key) { | |
throw new Exception('AUTH_TYPE_KEY requires a username as well as key details set'); | |
} else if (!file_exists($this->key['public'])) { | |
throw new Exception(sprintf('Public key file %s not found', $this->key['public'])); | |
} else if (!file_exists($this->key['private'])) { | |
throw new Exception(sprintf('Private key file %s not found', $this->key['private'])); | |
} | |
$auth = ssh2_auth_pubkey_file( | |
$this->handle, | |
$this->getUsername(), | |
$this->key['public'], | |
$this->key['private'], | |
$this->key['secret'] | |
); | |
} else if($this->getAuthType() == static::AUTH_TYPE_PASSWORD) { | |
if (!$this->getUsername() || !$this->getPassword()) { | |
throw new Exception('AUTH_TYPE_PASSWORD requires a username as and password'); | |
} | |
$auth = ssh2_auth_password($this->handle, $this->getUsername(), $this->getPassword()); | |
} else if($this->getAuthType() == static::AUTH_TYPE_NONE) { | |
if (!$this->getUsername()) { | |
throw new Exception('AUTH_TYPE_NONE requires a username'); | |
} | |
$auth = ssh2_auth_none($this->handle, $this->getUsername()); | |
if (is_array($auth)) { | |
throw new Exception(sprintf('Server does not accept no authentication. Available methods: %s', | |
implode(', ', $auth) | |
)); | |
} | |
} else { | |
throw new Exception('Invalid auth type specified'); | |
} | |
if (true === $auth) { | |
$this->isAuthenticated = true; | |
} | |
return $auth; | |
} | |
/** | |
* isConnected | |
* | |
* Check if already connected | |
* | |
* @return boolean | |
*/ | |
public function isConnected() | |
{ | |
return is_resource($this->handle); | |
} | |
/** | |
* isAuthenticated | |
* | |
* Check if you have been authenticated | |
* | |
* @return boolean | |
*/ | |
public function isAuthenticated() | |
{ | |
return $this->isAuthenticated; | |
} | |
/** | |
* disconnect | |
* | |
* Disconnect from the server | |
* | |
* @return void | |
*/ | |
public function disconnect($reason = null, $message = null, $language = null) | |
{ | |
if (!is_null($reason)) { | |
printf('Disconnecting. Reason: %s - Message: %s'.PHP_EOL, $reason, $message); | |
} | |
if ($this->isConnected() && $this->isAuthenticated()) { | |
//$this->exec("exit"); | |
} | |
$this->handle = NULL; | |
$this->isAuthenticated = false; | |
} | |
/** | |
* getFingerprint | |
* | |
* Get the servers fingerprint in various formats | |
* | |
* @see SSH2_FINGERPRINT_* constants for available flags | |
* @param int $flags | |
* @return string | |
*/ | |
public function getFingerprint($flags = null) | |
{ | |
if (is_null($flags)) { | |
$flags = SSH2_FINGERPRINT_MD5 | SSH2_FINGERPRINT_HEX; | |
} | |
return ssh2_fingerprint($this->handle, $flags); | |
} | |
/** | |
* getNegotiatedMethods | |
* | |
* @return multitype: | |
*/ | |
public function getNegotiatedMethods() | |
{ | |
if (!$this->isConnected()) { | |
} | |
return ssh2_methods_negotiated($this->resource); | |
} | |
/** | |
* exec | |
* | |
* Execute a raw command | |
* | |
* @param string $command | |
* @param string $pty - Terminal type. i.e. xterm, vt102 | |
*/ | |
public function exec($command, $pty = null) | |
{ | |
$stream = ssh2_exec( | |
$this->handle, | |
$command, | |
$pty, | |
$this->getEnvironment(), | |
$this->shellWidth, | |
$this->shellHeight, | |
$this->shellType | |
); | |
stream_set_blocking($stream, true); | |
$streamContent = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO); | |
$result = stream_get_contents($streamContent); | |
fclose($stream); | |
return $result; | |
} | |
/** | |
* hasEnvironmentVariable | |
* | |
* See if a specific environment variable is set | |
* | |
* @param string $name | |
* @return bool | |
*/ | |
public function hasEnvironmentVariable($name) | |
{ | |
return isset($this->environment[$name]); | |
} | |
/** | |
* setEnvironmentVariable | |
* | |
* Sets a specific environment variable | |
* | |
* @param string $name | |
* @param string $value | |
* @return Ssh2Client | |
*/ | |
public function setEnvironmentVariable($name, $value) | |
{ | |
$this->environment[$name] = $value; | |
return $this; | |
} | |
/** | |
* getEnvironmentVariable | |
* | |
* Get the valie of a set environment variable | |
* @param string $name | |
* | |
* @return string | |
*/ | |
public function getEnvironmentVariable($name) | |
{ | |
if (!$this->hasEnvironmentVariable($name)) { | |
throw new Exception(sprintf('Environment variable %s does not exist', $name)); | |
} | |
return $this->environment[$name]; | |
} | |
/** | |
* setEnvironment | |
* | |
* Set the environment array | |
* | |
* @param array $environment | |
* @return Ssh2Client | |
*/ | |
public function setEnvironment(array $environment) | |
{ | |
$this->environment = $environment; | |
return $this; | |
} | |
/** | |
* getEnvironment | |
* | |
* @return Ambigous <multitype:, unknown, array> | |
*/ | |
public function getEnvironment() | |
{ | |
return $this->environment; | |
} | |
/** | |
* spawnShell | |
* | |
* @param string $pty - Terminal type. i.e. xterm, vt102 | |
* @return resource | |
*/ | |
public function spawnShell($pty = null, $showWelcome = true) | |
{ | |
$stream = ssh2_shell($this->handle, $pty, $this->getEnvironment(), $this->shellHeight, $this->shellHeight, $this->shellType); | |
if (!is_resource($stream)) { | |
throw new Exception('Error spawning shell. Did not receive resource'); | |
} | |
sleep(1); | |
stream_set_blocking($stream, true); | |
$welcome = stream_get_contents($stream); | |
if ($showWelcome) { | |
echo $welcome; | |
} | |
return $stream; | |
} | |
public function shellExec($shell, $command) | |
{ | |
$command = $command.PHP_EOL; | |
$written = fwrite($shell, $command); | |
if (!$written) { | |
throw new Exception('SSH2 Shell. Wrote 0 bytes'); | |
} | |
$result = null; | |
while($response = fread($shell, 4096)) { | |
$result .= $response; | |
} | |
return $result; | |
} | |
public function onError($packet = null) | |
{ | |
// currently no error handler is used | |
return false; | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment