小韦云面板使用教程

利用SSH2打造PHP同步和异步操作linux的方法

小韦云科技-区块链+小程序+公众号+商城+分销+直播+企业官网+外贸电商-为您提供优质的开发服务-电话/微信联系:18123611282

在小韦云面板开发中,我们总结了PHP操作linux服务器两个场景:一是获取当前服务器的信息,这是要求实时返回的,属于同步(阻塞)模式。二是命令执行时间比较长,而且要看执行过程日志的,比如安装软件,执行软件更新等操作,这属于异步模式,PHP打开一个日志界面,然后调用执行命令,再通过websocket实时返回日志显示在界面上。

我们先看看小韦云面板使用的同步模式的函数:

$command 要是执行的命令,即shell 的命令
$show_err 直接显示错误信息,调试专用

函数详细见注释

function ssh_execute($command, $show_err = false)
{
    if (!function_exists('ssh2_connect')) return ['code' => 3, 'msg' => 'PHP的ssh2扩展没安装'];
    set_time_limit(0);

    static $conn;
    if (!$conn) {
        try {
            $conn = ssh2_connect(SSH_IP, '22', ['hostkey' => 'ssh-rsa']);   //初始化连接
            if (!ssh2_auth_pubkey_file($conn, 'root', SITE_PATH . '/config/.ssh/id_rsa.pub', SITE_PATH . '/config/.ssh/id_rsa', 'bctos')) {
                return ['code' => 2, 'msg' => 'Public Key Authentication Failed'];
            }
        } catch (\Exception $e) {
            return ['code' => 2, 'msg' => $e->getMessage()];
        }
    }
    //执行命令
    $stream = ssh2_exec($conn, $command);

    $dio_stream = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO);  //获得标准输入输出留
    $err_stream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);  //获得错误输出留

    stream_set_blocking($err_stream, true);
    stream_set_blocking($dio_stream, true);
    $result_err = stream_get_contents($err_stream);
    $output = stream_get_contents($dio_stream); //获取流的内容,即命令的返回内容

    fclose($stream);
    if (!empty($result_err)) {
        if ($show_err) {
            dump($command);
            dump($result_err);
            dump($output);
            exit;
        }
        if (strpos($result_err, '[notice]') === false && strpos($result_err, '[Warning]') === false) {
            return ['code' => 1, 'msg' => $result_err];
        } else {
            return ['code' => 0, 'msg' => $output];
        }
    }
    return ['code' => 0, 'msg' => $output];
}

它先判断SSH2扩展有没有安装,然后通过证书连接上服务器,然后执行命令,最后通过stream_get_contents获取返回的内容。

异步模式的输入类似同步模式,但它通过2>&1把所有输出的内容合并在一起,然后使用while (true)一直循环获取日志,直到出现我们自己约定==over==结束标示才停止,如果由于异常无法取到结束标示,也会在超过30分钟自动结束。

日志推送到网页是使用web_msg方法,它是web-msg-sender(websocket工具)的发送方式

function ssh_execute_msg($command, $show_err = false)
{
    if (!function_exists('ssh2_connect')) {
        web_msg('PHP的ssh2扩展没安装==over==error');
        return ['code' => 3, 'msg' => 'PHP的ssh2扩展没安装'];
    }
    set_time_limit(0);

    static $conn;
    if (!$conn) {
        $conn = ssh2_connect(SSH_IP, '22');   //初始化连接
        if (!ssh2_auth_pubkey_file($conn, 'root', SITE_PATH . '/config/.ssh/id_rsa.pub', SITE_PATH . '/config/.ssh/id_rsa', 'bctos')) {
            return ['code' => 2, 'msg' => 'Public Key Authentication Failed'];
        }
    }

    $command .= " 2>&1";
    file_log($command, 'ssh_execute');
    $stream = ssh2_exec($conn, $command);
    sleep(1);
    $dio_stream = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO);  //获得标准输入输出留

    $time = time();
    while (true) {
        $data = stream_get_contents($dio_stream);
        if (!empty($data)) {
            web_msg($data);
            if (strpos($data, "==over==") !== false) {
                break;
            } else {
                $time = time();
            }
        }
        if (empty($data)) {
            if (time() - $time > 1800) {
                //空转超过30分钟自动结束,防止长期运行
                web_msg('超时结束==over==error');
                break;
            }
        }
    }

    fclose($stream);
}

function web_msg($content)
{
    // 指明给谁推送,为空表示向所有在线用户推送
    $to_uid = 1;

    // 推送的url地址,使用自己的服务器地址
    $push_api_url = "http://" . SSH_IP . ":2121/";
    $post_data = array(
        "type" => "publish",
        "content" => str_replace("\n", "\r\n", $content),
        "to" => $to_uid,
    );
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $push_api_url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("Expect:"));
    curl_exec($ch);
    curl_close($ch);
}

本文由小韦云原创,转载请注明出处:http://bctos.cn/doc/2/1952,否则追究其法律责任

关键词:SSH2 PHP 小韦云面板

广告位招商