解决方案 »

  1.   

    你试下这个php是不是要指定路径 /bin/php 之类的。 
      

  2.   

    php 1.php
    这里改绝对路径试试。
    php /home/xxx/web/1.php 这种。
      

  3.   

    你的 $descriptorspec 是怎么写的?
      

  4.   

    我的代码这样的,其实就是php.net下面回复的一个STDIN STDOUT example例子,不过看时间诗6年前的,我开始还以为是buf的问题,没有读,加上stdbuf -o0也不行,我试了在ubuntu下面不行,但是windows和mac下面用xampp一切都顺利,这个问题难道是系统的问题?
    1.php<?php
    $descriptorspec = array(
       0 => array("pipe", "r"), 
       1 => array("pipe", "w"), 
       2 => array("pipe", "r")
    );
    $process = proc_open("php 2.php", $descriptorspec, $pipes, null, null); 
    echo ("Start process:\n");
    if (is_resource($process)) 
    {
        fwrite($pipes[0], "start\n");    // send start
        echo ("\n\nStart ....".stream_get_contents($pipes[1])); //get answer
        fwrite($pipes[0], "get\n");    // send get
        echo ("Get: ".fgets($pipes[1],4096));    //get answer
        fwrite($pipes[0], "stop\n");    //send stop
        echo ("\n\nStop ....".fgets($pipes[1],4096));  //get answer    fclose($pipes[0]);
        fclose($pipes[1]);
        fclose($pipes[2]);
        $return_value = proc_close($process);  //stop test_gen.php
        echo ("Returned:".$return_value."\n");
    }
    ?>2.php<?php
    $keys=0;
    function play_stop()
    {
    global $keys;
            $stdin_stat_arr=fstat(STDIN);
            if($stdin_stat_arr[size]!=0)
            {
                $val_in=fread(STDIN,1024);
                switch($val_in)
                {
                case "start\n":    echo "Started\n";
                        return false;
                        break;
                case "stop\n":    echo "Stopped\n";
                        $keys=0;
                        return false;
                        break;
                case "pause\n":    echo "Paused\n";
                        return false;
                        break;
                case "get\n":    echo ($keys."\n");
                        return true;
                        break;
                default:    echo("Передан не верный параметр: ".$val_in."\n"); 
                        return true;
                        exit();
                }
            }else{return true;}
    }
    while(true)
    {
    while(play_stop()){usleep(1000);}
    while(play_stop()){$keys++;usleep(10);}
    }
    ?>
      

  5.   

    首先看参数 descriptorspec  的说明
    number and the value represents how PHP will pass that descriptor to the child process. 0 is stdin, 1 is stdout, while 2 is stderr.
    一个索引的数组的键表示的描述符的数量和价值是如何PHP将通过描述符给子进程。0是标准输入,1是标准输出,而2是stderr。
    你的是 2 => array("pipe", "r") 没有给错误出路
    再看手册中的范例$descriptorspec = array(
       0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
       1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
       2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to
    );
    将出现的错误写入了文件所以你至少要在调试时记录下可能出现的错误
      

  6.   

    非常感谢你的回答,我按照你的方法试了一下,发现了一个notice,就是2.php 第七行$stdin_stat_arr[size]!=0里面的size没有加引号,我加了引号之后,日志文件就什么也不再输出了.
      

  7.   

    现在这个好像2.php里面的if($stdin_stat_arr[size]!=0)这个条件一直无法成立,无限循环
      

  8.   

    $stdin_stat_arr=fstat(STDIN); ???
    函数用错了$stdin_stat_arr = file_get_contents('php://input');
    或许可以
      

  9.   

    php://input好像更多用在服务器与客户端的交互之上,而这个php://stdin主要就是读取进程的输入流,(详细见http://php.net/manual/zh/wrappers.php.php),STDIN用在这里我觉得应该是没错的,而且我也实验了一下换成php://input,但是还是不行.这个问题确实挺纠结人的,不知道有没有可以替代的函数?
      

  10.   

    但是 fstat 是有缓存的,用在这里肯定是不合适的
      

  11.   

    这个fstat用在这里确实不好,STDIN是个流,不是文件,这个问题我google了一下,发现好多人都遇到这个问题,一直处于阻塞状态,http://stackoverflow.com/questions/9356152/non-blocking-on-stdin-in-php-cli
    https://bugs.php.net/bug.php?id=23424
    我看过一个博客,但是地址记不得了,他也遇到了这个问题,但是他是用了ffflush(),然后就OK了,我这里试了一下,没效果,实在不行考虑换个别的方法来实现好了