- Dec. 24th, 2008
- 10 comments
PHP doesn't come with native support for making SSH connections via the libssh2 libraries. You must use the PECL SSH2 extensions. Installing them can be tricky, but Kevin van Zonneveld does a great job explaining how to install them over here. So I won't go there. The new version, 0.11.0, also seems to be compiling more reliably for everyone.
Unfortunately, the library is sparsely documented, and still buggy in some places. And most of the comments posted on http://www.php.net/ssh2 are just plain wrong! Kudos to Mike Sullivan for fixing some of the issues with non-blocking I/O (And let's not forget to thank Sara Golemon for writing it to begin with!). I list the most conspicuous problems at the bottom of this blog entry for interested parties. Everyone else can use our wrappers to smooth over some of the kinks and make most common tasks trivial to perform.
Our wrapper is released under GNU license and can be used, for example, as follows:
$php_ssh2 = new SSH2('YOURHOST.COM'); $php_ssh2->loginWithPassword('YOUR_LOGIN', 'YOUR_PASSWORD'); echo $php_ssh2->execCommandBlock('find /cat/food');
All Pertinent Features:
allows execution of a script ignoring output. Note that without blocking execution manually, 2 ssh2_execs will execute asychronously. So it should also be used for shell scripts that have no output. Why? If you never check for data, it will never block — yes, even in blocking mode! This is subtle … until it clicks.
$php_ssh2->setLogReads($setting = true)
enables or disables read logging on the current SSH2 stream.
$php_ssh2->setLogWrites($setting = true)
enables or disables write logging on the current SSH2 stream.
$php_ssh2->getShell($set_blocking = false, $term_type = 'vt102' ... )
opens a shell for the user — generally not needed and much harder to work with.
$php_ssh2->waitPrompt($prompt_regex = '> $', &$buf = '', $timeout_secs = 0)
waits for a specified prompt $prompt_regex (expressed as a regular expression) for $timeout_secs (or 0 to block forever). Returns true or false, leaves response (whether matching or not) buffer in &$buf parameter.
$php_ssh2->writePrompt($command, $add_newline = true)
writes the specified output to stream. Returns what it was able to write.
The rest of the functions are fairly self-explanatory. Check out the library here —
Problems/Gotchas I've Observed in PECL SSH2
1. Non-blocking mode buggy and/or coredumps in versions < 0.11.0. So make sure you upgrade.
2. FreeBSD Ports currently reports a patched "usr/ports/security/pecl-ssh2″ version 0.10.0 as 0.11.0 (Not strictly a PECL SSH2 problem, but worth noting as it caused me grief).
3. stream_set_timeout() does not work at all with SSH2 streams — silently always returns false.
4. stream_select() does not work with SSH2 streams — but prints a warning.
5. One must pass NULL to $pty — not false (like some comments on php.net claim), not "" — otherwise LFs ("\n") will get changed to CRLFs ("\r\n"). Text files will mostly survive this, but binary data will be corrupted! This took us a solid hour to debug and involved a hex-editor.
As a consequence of some of the above, there is no good way to do non-blocking I/O in versions < 0.11.0. Period. No timeouts, no polling, no selecting. If you need non-blocking I/O to work reliably, you must upgrade to 0.11.0.
"10 Wise Comments Banged Out Somewhere On The Internet ..."