使用PHP exec()逐步发回信息

时间:2014-07-04 07:59:50

标签: php ajax bash composer-php command-line-interface

我使用PHP exec()安装 Composer 依赖项:

exec('php composer.phar install -d ' . dirname(__DIR__), $out);

这是通过ajax post请求触发的。一切正常,exec()的回复将打印到屏幕上。

exit(json_encode($out));

然而,我所追求的是一种定期将数据发送回ajax回调的方法,因此我可以渲染每一位信息而不是一次渲染整个块。

不确定这是否可行。

我应该提一下,运行它的服务器不会有像NodeJS这样的东西,很可能是共享主机。

1 个答案:

答案 0 :(得分:0)

除了按需执行的安全问题,如果您能够将输出的状态写入/记录到文件,您可以编写一个简单的AJAX轮询器(因为您不想使用WebSockets)。

在你的执行官中,试试:

添加-task.php

$jobId = uniqid();
$outfile = $jobId . "-results.txt";
exec('php composer.phar install -d ' . dirname(__DIR__) . " > $outfile &", $out);
$result = array("jobId" => $jobId);
echo json_encode($result);

好的,现在将$jobId发送给客户端,以便他们可以轮询更新。我在github上使用了一个概念项目的变体:https://github.com/panique/php-long-polling

<强> server.php

$jobid = isset($_GET['jobid']) ? $_GET['jobid'] : null;
$outputfile = $jobid . "-results.txt";
$lastTimestamp = isset($_GET['timestamp']) ? (int)$_GET['timestamp'] : null;

// get timestamp of when file has been changed the last time
clearstatcache();
$lastModified = filemtime($outputfile);

// if no timestamp delivered via ajax 
// or data.txt has been changed SINCE last ajax timestamp
if ($lastTimestamp == null || $lastModified > $lastTimestamp) {

    // get content of data.txt
    $data = file_get_contents($outputfile);

    // put data.txt's content and timestamp of 
    // last data.txt change into array
    $result = array(
        'data' => $data,
        'timestamp' => $lastTimestamp
    );

    // encode to JSON, render the result (for AJAX)
    $json = json_encode($result);

} else {

    // No updates in the file, just kick back the current time
    // and the client will check back later
    $result = array(
        'timestamp' => time()
    );

    $json = json_encode($result);
}

header("Content-Type: application/json");
echo $json;

然后,在浏览器中,您只有一个小客户端,可以轮询它的“工作”。检查状态。

<强> client.js

$(function () {

  var jobid = '12345';
  function checkForUpdates(timestamp) {
    $.ajax({
      type: 'GET',
      url: 'http://localhost/server.php',
      data: {
        'timestamp': timestamp,
        'jobid': jobid
      },
      success: function (data) {
        var obj = jQuery.parseJSON(data);
        if (obj.data) {
          // Update status content
          $('#response').text(obj.data);
        }
        // Check again in a second
        setTimeout(function () {
          checkForUpdates(obj.timestamp);
        }, 1000);
      }
    });
  }

  checkForUpdates();
});

<强>的index.html

<html>
    <head>
        <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
        <script type="text/javascript" src="client.js"></script>
    </head>
    <body>
        <h1>Status:</h1>
        <div><pre id="response"></pre></div>
    </body>
</html>