ホームページ  >  記事  >  バックエンド開発  >  PHP ノンブロッキング SSH クライアントの例_PHP チュートリアル

PHP ノンブロッキング SSH クライアントの例_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-13 10:47:401202ブラウズ

以前の仕事では、遅延とパケット損失の問題が非常に深刻で、SQL ステートメントの入力が非常に面倒でした。 Google で検索したところ、PHP には SSH2 拡張機能があり、コマンドベースの SSH クライアントは標準の入出力を使用して実装できるため、ネットワークの問題を解決するために開発しました。 PHP ノンブロッキング SSH クライアント

値:

  • コマンドに基づいて、ネットワーク遅延とパケット損失の問題を最大限に解決します。
  • Windows と Linux でのテストに合格しました。

短所:

  • オートコンプリート機能なし
  • sftpやscpなどの他の機能はありません
  • 色なしで大胆
  • 場合によっては、表示が完璧ではない場合があります
  • 今は基本的に使っていないので、当面は改善しません。

Linux 実行効果
PHP ノンブロッキング SSH クライアントの例_PHP チュートリアル
窓の下でのランニング効果
PHP ノンブロッキング SSH クライアントの例_PHP チュートリアル
PHP ノンブロッキング SSH クライアントの例_PHP チュートリアル
PHP ノンブロッキング SSH クライアントの例_PHP チュートリアル

フレームワーク内のクラスなので、一部の共通関数(debug_print()など)は自分で用意する必要があるため、ここでは書き換えません

コードは次のとおりです コードをコピー

クラス FSSH{
プライベート $conn;
プライベート $shell;

/**
* key=文字列パスワード認証、key=array('pub'=>,'pri'=>,'type'=>,'phrase'=>) キー認証
※鍵認証にはssh-rsa、ssh-dssの2種類があります
* $host[addr]=文字列アドレス,$host['fp']=array() サーバーフィンガープリント
​*/
 関数 __construct($host,$user,$key){
  if(empty($host['addr'])){
   debug_print('ホストを空にすることはできません',E_USER_ERROR);
  }
  if(empty($host['fp'])){
   debug_print('指紋認証が指定されていません',E_USER_ERROR);
  }
  $this->stdin=fopen('php://stdin','r');
  $this->stdout=fopen('php://stdout','w');
  if(false!==strpos($host['addr'],':')){
   $temp=explode(':',$host['addr']);
   $host['addr']=$temp[0];
   $port=$temp[1];
  }その他{
   $ポート=22;
  }
  if(is_string($key) || empty($key['type'])){
   $methods=null;
  }その他{
   $methods=array('hostkey'=>$key['type']);
  }
  $conn=ssh2_connect($host['addr'],$port,$methods,array('disconnect'=>array($this,'disconnect')));
  $fp=ssh2_fingerprint($conn,SSH2_FINGERPRINT_MD5);
  $success=false;
  $fpOK=false;
  if(in_array($fp,$host['fp'])){
   $fpOK=true;
  }その他{
   fwrite($this->stdout,"$fpn指紋はOKですか?(y/n)");
   $input=strto lower(stream_get_line($this->stdin,1));
   if($input=='y'){
    $fpOK=true;
   }その他{
    $fpOK=false;
   }
  }
  if($fpOK){
   if(is_array($key)){
    if (ssh2_auth_pubkey_file($conn,$user,$key['pub'],$key['pri'],$key['phrase'])){
     $success=true;
    }その他{
     debug_print('公開鍵認証に失敗しました',E_USER_ERROR);
    }
   }elseif(is_string($key)){
    if(ssh2_auth_password($conn,$user,$key)){
     $success=true;
    }その他{
     debug_print('パスワード認証に失敗しました',E_USER_ERROR);
    }
   }
  }その他{
   debug_print('指紋が無効です',E_USER_ERROR);
  }
  if($成功){
   $this->conn=$conn;
   $this->shell=ssh2_shell($conn,null,null,1024);
  }
  $success を返します;
 }

関数シェル(){
  //最後の一条コマンド
  $last='';
  //先结束シェル、再结束while
  $signalTerminate=false;
  while(true){
   $cmd=$this->fread($this->標準入力);
   $out=stream_get_contents($this->shell,1024);
   if(!empty($out) と !empty($last)){
    $l1=strlen($out);
    $l2=strlen($last);
    $l=$l1>$l2?$l2:$l1;
    $last=substr($last,$l);
    $out=substr($out,$l);
   }
   echo ltrim($out);
   if($signalTerminate){
    休憩;
   }
   if(in_array(trim($cmd),array('exit'))){
    $signalTerminate=true;
   }
   if(!empty($cmd)){
    $last=$cmd;
    fwrite($this->shell,$cmd);
   }
  }
 }

//Windows コマンドラインの読み取りの問題を解決する他の方法はありません。
プライベート関数 fread($fd){
静的 $data='';
$read = 配列($fd);
$write = array();
$excel = array();
$result = stream_select($read,$write,$excel,0,1000);
if($result === false)
debug_print('stream_select に失敗しました',E_USER_ERROR);
if($result !== 0){
$c= stream_get_line($fd,1);
if($c!=chr(13))
$data.=$c;
if($c==chr(10)){
$t=$データ;
$data='';
$t;
を返します }
}
}

関数__destruct(){
fclose($this->stdin);
fclose($this->stdout);
$this->disconnect();
}

プライベート関数切断(){
if(is_resource($this->conn)){
設定を解除($this->conn);
fclose($this->shell);
}
}
}


デモ

コードは次のとおりです コードをコピー

//$ssh=new FSSH(array('addr'=>'x.x.x.x:22','fp'=>array('')),'tunnel',array('pub'=>'E :Identity.pub','pri'=>'E:Identity','type'=>'ssh-rsa'));
$ssh=新しい FSSH(array('addr'=>'192.168.2.205','fp'=>array('54ECC700B844DCF0D40554A56C57C01E')),'root','123456');
$ssh->shell();

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/632846.html技術記事以前の仕事では、遅延とパケット損失の問題が非常に深刻で、SQL ステートメントの入力が非常に面倒になることがありました。 Google 検索...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。