传递参数以处理

时间:2017-08-18 06:36:25

标签: php proc

我从github下载了一个开源终端模拟器,并对其进行了一些修改。运行流程的类如下所示:

<?php

class CProcess {
    const PROC_OK = true;
    const PROC_FAILED = false;

    private static $instance = null;

    public static function factory() {
        if (!isset(self::$instance)) {
            self::$instance = new CProcess();
        }
        return self::$instance;
    }

    private $pipes;
    private $process;
    private $stdinref;
    private $stdoutref;
    private $stderref;

    private function __construct() {

    }

    public function __destruct() {
        return $this->close();
    }

    public function open($command) {
        $spec = array(
            array("pty"), // STDIN
            array("pty"), // STDOUT
            array("pty")  // STDERR
        );

        if (!$this->process = proc_open($command, $spec, $this->pipes)) {
            return self::PROC_FAILED;
        }
        $this->stdinref = &$this->pipes[0];
        $this->stdoutref = &$this->pipes[1];
        $this->stderref = &$this->pipes[2];

        $this->setBlocking(0);
        return self::PROC_OK;
    }

    public function isResource() {
        return is_resource($this->process);
    }

    public function setBlocking($blocking = 1) {
        return stream_set_blocking($this->stdoutref, $blocking);
    }

    public function getStatus() {
        return proc_get_status($this->process);
    }

    public function get() {
        $out = stream_get_contents($this->stdoutref);
        return $out;
    }

    public function put($data) {
        fwrite($this->stdinref, $data . "\n");
        sleep(1);
        fflush($this->stdinref);
    }

    public function close() {
        if (is_resource($this->process)) {
            fclose($this->stdinref);
            fclose($this->stdoutref);
            fclose($this->stderref);
            return proc_close($this->process);
        }
    }

    public function metaData() {
        return stream_get_meta_data($this->stdoutref);
    }

}

现在我想使用以下方法验证登录/密码对:

  public static function autenticate($login, $password) {
        if (true === DEBUG_MODE) {
            error_log("authenticate(): login={$login} password={$password}",0);
        }
        error_log("test");
        self::$username = $login;
        $process = CProcess::factory();
        $cmd = "su " . escapeshellarg($login);
        if (true === DEBUG_MODE) {
            error_log("authenticate(): cmd={$cmd}", 0);
        }

        $rc = $process->open($cmd);
        usleep(100000); // 500000
        if ($rc === CProcess::PROC_FAILED) {
            if (true === DEBUG_MODE) {
                error_log("authenticate(): process_open() returns {$rc}", 0);
            }

            return false;
        }
        if (true === DEBUG_MODE) {
            error_log("authenticate(): invoking process->put() with param={$password}");
        }

        $process->put($password);
        if (true === DEBUG_MODE) {
            error_log("authenticate(): process->put() returned its value");
        }

        usleep(100000);
        return (bool) !$process->close();
    }

问题是进入$process->put($password);时脚本会挂起。我的浏览器只显示&#39;等待本地主机&#39;它会永远持续下去。在课程put();的{​​{1}}方法中,我也尝试了CProcess而不是PHP_EOL,但结果是一样的。这段代码有什么问题?

1 个答案:

答案 0 :(得分:0)

您使用的管道应该更像,具有读/写类型选项......

$spec = array(
    0 => array("pipe", "r"),
    1 => array("pipe", "w"),
    2 => array("file", "/tmp/error-output.log", "a") );