Object oriented solution for typical tasks over SSH and SFTP connection. Based on php-ssh2 library and compatible with all its versions starting from 0.9.0. On Linux php-ssh2 library can be easily installed from software repository, or as a PECL package, or manually, see https://www.php.net/manual/en/ssh2.installation.php
- Custom logger function
- Configurable default terminal settings
- Timeout based interactive command execution
- Recursive operations on files and directories
- PHP 5.4+ with ssh2 extension installed
- PHPUnit framework for tests, version 8.5.33 (PHP 7.2+)
Tested to work with PHP 5.6, 7.2, 7.4 and 8.1. Built-in test case under tests
directory requires PHP 7.2+. Compatibility with PHP 5.4-5.6 (and corresponding version of PHPUnit) can be reached after just removal of return type declarations.
Add the repo information in your composer.json:
{
"repositories": [{
"type": "git",
"url": "https://github.com/devoldemar/php-ssh2-client"
}]
}
Then run:
composer require devoldemar/php-ssh2-client:master
$ssh2 = new \Devoldemar\SSH2Client($host); // port 22 by default
// or
$ssh2 = new \Devoldemar\SSH2Client($host, $port);
Check the connection is established:
if ($ssh2->getIsConnected()) {
// do smth
}
Get MD5 fingerprint, verify public key hash (i.e. authenticity) of remote server:
if (!strcasecmp($ssh2->md5Fingerprint(), $knownValue))) {
// do smth
}
The host key to be returned as fingerprint can be one of several keys created on server. Priority depends on encryption algorithm, openssh library uses the following order: ECDSA, Ed25519, RSA.
Close connection:
$ssh2->disconnect();
// or
unset($ssh2);
Specify function which calls logging scenario of your application:
$ssh2->logger = function($method, $message, $isError, $props) {...}
Code example:
namespace myapp;
class MySSH2Client extends \Devoldemar\SSH2Client
{
public function __construct()
{
$this->logger = function($method, $message, $isError, $props) {
myapp::log("$method: $message, remote address = {$props['address']}, username = {$props['username']}", $isError ? myapp::LOG_LEVEL_ERROR : myapp::LOG_LEVEL_DEBUG);
};
parent::__construct();
}
}
$ssh2->authByPassword($username, $password): bool
$ssh2->authByKey($username, $publicKey, $privateKey, ?$passphrase = ''): bool
$ssh2->authByKeyFile($username, $publicKeyFile, $privateKeyFile, ?$passphrase = ''): bool
$ssh2->authByHost($username, $hostname, $publicKeyFile, $privateKeyFile, ?$passphrase = '', ?$husername = $username): bool
Public key file should be in OpenSSH (RFC4716, one line modification) format. For private key either OpenSSH or PEM format can be used.
Check authentication status:
if ($ssh2->getIsAuthenticated()) {
// do smth
}
$ssh2->shellExec($command, ?$env = null): string|false
$ssh2->shellExec($command, ['LANG' => 'en_US.UTF-8']): string|false
Note that the client may set only those environment variables which are listed under AcceptEnv
option of ssh daemon on the remote server.
Configure default terminal properties if needed:
$ssh2->terminal = ['type' => 'sh', 'env' => null, 'width' => 180, 'height' => 60];
Get command shell as I/O stream, optionally specify terminal type, environment variables, width and height in characters:
$ssh2->getShell(?$type = 'bash', ?$env = null, ?$width = 80, ?$height = 25): resource|false
Execute one or several commands in the same shell interactively:
$ssh2->useShell(?$type = 'bash', ?$env = null, ?$width = 80, ?$height = 25): bool
$ssh2->shellSend($command, ?$timeout = 1, ?$callback = null): string|false
Timeout is in seconds. Callback is an optional function that is to be called when some output exists but no more data to fetch. If it returns true the reading will be finished.
Execute all operations in the same SFTP channel (may not work with older php-ssh2 releases):
$ssh2->useSFTP(): bool
All methods below except renameFile
allow relative path to a corresponding file or a directory. The path also may start from alias sush as ./
and ../
.
$ssh2->getFileStat(string $file): array|false
Returns same array as lstat with is_link
and is_dir
flags added that indicate type of corresponding file system object.
Reading or writing file data:
$ssh2->getFileContents(string $file): string|false
$ssh2->readFile(string $file, callable $chunkHandler, ?int $chunkSize = 1024 * 1024): int // number of bytes read
$ssh2->writeFile(string $file, string|resource $data, ?string $mode = 'w+'): int // number of bytes written
$ssh2->unlinkFile(string $file): bool
$ssh2->renameFile(string $oldPath, string $newPath): bool
$ssh2->chmodFile(string $file, int $mode): bool
$ssh2->getRealPath(string $path): string|false
$ssh2->makeLink(string $target, string $link): bool
$ssh2->readLink(string $link): string|false
$ssh2->listFiles(string $dir, ?$stat = false): array|false
Make a directory:
$ssh2->makeDir(string $path, ?int $mode = 0775): bool
The method also works as mkdir -p
(make absent parent directories as needed).
Remove a directory recursively with maximum depth = $depth:
$ssh2->removeDir(string $dir, ?int $depth = 10): bool
MIT