如何用PHPSecLib复刻PECL PHP的ssh2_shell()及ssh2_shell_resize()功能
问题
我希望使用PHPSecLib复刻PECL PHP交互式shell函数ssh2_shell()的功能,从而完全迁移不再依赖libssh。我注意到openShell()最近被设为公开函数,但未找到使用示例,不确定是否需要用它。这不像调用ssh->write()那么简单,因为需要维持一个持续开放的流,轮询也不可行——我之前用PHPSecLib尝试过轮询,效果远不如ssh2_shell()的持续流。
以下是我当前使用的ssh2_shell()函数,用于基于Ratchet的实时PHP流控制台(代码基于PHP-SSH2-Web-Client开源项目):
/** * SSH2 shell getter. For Ratchet stream console * * @param [type] $session * @param string $termType * @param [type] $env * @param string $width * @param string $height * @param string $widthHeightType * @return void */ public function getShell($termType = 'vanilla', $env = null, $width = 80, $height = 25, $widthHeightType = SSH2_TERM_UNIT_CHARS) { return ssh2_shell($this->ssh, $termType, $env, $width, $height, $widthHeightType); }
另外,我还希望复刻ssh2_shell_resize()的功能,该函数可动态调整shell大小,是PECL SSH2 v1.4版本新增的较新功能。
解决方案
1. 复刻ssh2_shell()功能
PHPSecLib的SSH2类中公开的openShell()方法正是实现交互式shell的核心接口,它的参数可以和ssh2_shell()一一对应,完全满足持续流交互的需求。
实现代码
use phpseclib3\Net\SSH2; /** * PHPSecLib SSH shell getter. 适配Ratchet流控制台 * * @param string $termType * @param array|null $env * @param int $width * @param int $height * @param int $widthHeightType * @return resource|\phpseclib3\Net\SSH2\Shell */ public function getShell($termType = 'vanilla', $env = null, $width = 80, $height = 25, $widthHeightType = SSH2_TERM_UNIT_CHARS) { // 统一环境变量为数组格式 $env = $env ?? []; // 映射PECL与PHPSecLib的终端尺寸单位常量 $dimUnit = $widthHeightType === SSH2_TERM_UNIT_CHARS ? SSH2::WIDTH_CHARS : SSH2::WIDTH_PIXELS; // 调用openShell创建交互式Shell对象 $shell = $this->ssh->openShell($termType, $env, $width, $height, $dimUnit, $dimUnit); // 若Ratchet依赖PHP原生流,直接返回转换后的流资源 return $shell->getStream(); // 若无需原生流,可直接返回Shell对象,它本身支持write/read持续交互 // return $shell; }
关键说明
openShell()底层基于SSH channel机制维护连接,和ssh2_shell()逻辑一致,无需额外轮询即可维持持续流。- 参数完全对应,只需将PECL的终端尺寸常量映射为PHPSecLib的对应常量即可。
- 调用
$shell->getStream()可获取标准PHP读写流,直接替换原ssh2_shell()返回的流即可适配Ratchet现有逻辑。
2. 复刻ssh2_shell_resize()功能
PHPSecLib的Shell类内置了resize()方法,专门用于动态调整终端窗口大小,功能与ssh2_shell_resize()完全匹配。
实现代码
use phpseclib3\Net\SSH2; /** * 调整SSH Shell窗口大小 * * @param \phpseclib3\Net\SSH2\Shell $shell * @param int $width * @param int $height * @param int $widthHeightType * @return bool */ public function resizeShell($shell, $width = 80, $height = 25, $widthHeightType = SSH2_TERM_UNIT_CHARS) { $dimUnit = $widthHeightType === SSH2_TERM_UNIT_CHARS ? SSH2::WIDTH_CHARS : SSH2::WIDTH_PIXELS; return $shell->resize($width, $height, $dimUnit, $dimUnit); }
关键说明
- 只需传入
openShell()获取的Shell对象(或其对应的流资源),即可动态调整终端尺寸。 - 返回布尔值表示调整操作是否成功,与
ssh2_shell_resize()的返回逻辑完全一致。
内容的提问来源于stack exchange,提问作者fred
相关产品推荐
相关产品推荐

