由PHP

时间:2016-08-03 23:12:18

标签: php curl

我正在为我们的技术团队的一部分构建一个内部工具套件,该套件涉及针对世界各地的远程服务器阵列运行命令。我遇到了一个小问题,但我不能轻易想到解决问题的方法。以下是该工具集的特定部分的过程:

  • 主服务器上的Web表单,用户输入检查类型和主机名/ IP
  • 将输入变量提交到主服务器上的PHP脚本,该服务器构建针对远程服务器的cURL,cURL的URL(仅限于此示例中的一个远程服务器),并回显其输出
  • 远程服务器接收带有变量的PHP脚本的Web请求,运行linux shell命令以满足请求,并通过cURL将其输出返回给主

所以这一切都很好,但我决定使用traceroute和ping工具,并通过使用popen()和fread()让他们实时输出浏览器,例如: / p>

#Get the variables
$type = $_GET['type'];
$hostname = $_GET['host'];

#Start switch to decide what to do
switch ($type) {
  case "trace":
      $cmd = "traceroute $hostname";
      while (@ ob_end_flush());
      $proc = popen($cmd, 'r');
      echo "<pre>";
      while (!feof($proc))
        {
          echo fread($proc, 4096);
          @ flush();
        }
      echo "</pre>";
    break;
  case "ping":
      $cmd = "ping -c 5 " . $hostname;
      while (@ ob_end_flush());
      $proc = popen($cmd, 'r');
      echo "<pre>";
      while (!feof($proc))
        {
          echo fread($proc, 4096);
          @ flush();
        }
      echo "</pre>";
   break;
}

在浏览器中直接针对远程服务器运行时,上述工作正常。但是当然,来自主控制器的cURL不会返回实时输出,它只是在达到断点时返回完成的输出。这是令人沮丧的,因为它们中有5-10个同时在一个页面上运行,而像traceroutes这样的东西我真的不需要等到30跳才超时才能从用户那里得到任何输出。

所以这里我的整体问题是..我怎样才能让cURL模仿像popen和fread这样的实时PHP输出? cURL甚至可以这样做吗?我可以使用另一个PHP函数从远程URL获取实时输出,直到它中断?

1 个答案:

答案 0 :(得分:0)

是的,它可以通过CURLOPT_PROGRESSFUNCTION / CURLOPT_WRITEFUNCTION ..未经测试,但我认为它会是这样的:

$ch=curl_init();
$buffer='';//your download buffer goes here.
function progressfunc($ch,$totalDownloadSize,$bytesDownloaded,$totalRequestSize,$bytesUploaded){
    global $buffer;
    echo $buffer;
    $buffer='';
    //echo str_repeat('<span></span>',100);//if you have buffering issues, this is an ugly workaround...
    flush();
};
function writefunc($ch,$data){
    global $buffer;
    static $written=0;
    $buffer.=$data;
    $written+=strlen($data);
    return $written;
};
if(!curl_setopt_array($ch,array(
CURLOPT_WRITEFUNCTION=>'writefunc',
CURLOPT_PROGRESSFUNCTION=>'progressfunc',
CURLOPT_URL=>'slow_download'
))){
    throw new RuntimeException('curl_setopt_array error. errno:'.curl_errno($ch).' error:'.curl_error($ch));
}
curl_exec($ch);