在PHP中推进过程控制

时间:2012-01-02 19:07:23

标签: php command-line execution

我需要构建一个用户将文件发送到服务器的系统 然后php将使用system()运行命令行工具(示例tool.exe userfile) 我需要一种方法来查看进程的pid以了解启动该工具的用户 以及了解工具何时停止的方法。

这在Windows Vista机器上是否可行,我无法移动到Linux服务器。

此外,当用户关闭浏览器窗口时,代码必须继续运行

1 个答案:

答案 0 :(得分:3)

我认为你想做的事情不是试图获取进程的ID并监视它运行的时间,而是有一个处理前/后处理的“包装”进程,例如日志记录或数据库操作。

第一步是创建一个异步进程,它将独立于父进程运行,并允许通过调用网页来启动它。

要在Windows上执行此操作,我们使用WshShell:

$cmdToExecute = "tool.exe \"$userfile\"";
$WshShell = new COM("WScript.Shell"); 
$result = $WshShell->Run($cmdToExecute, 0, FALSE);

...和(为了完整性)如果我们想在* nix上执行,我们将> /dev/null 2>&1 &附加到命令:

$cmdToExecute = "/usr/bin/tool \"$userfile\"";
exec("$cmdToExecute > /dev/null 2>&1 &");

所以,现在你知道如何启动一个不会阻塞脚本的外部进程,并在脚本完成后继续执行。但这并没有完成图片 - 因为您想跟踪外部流程的开始和结束时间。这很简单 - 我们只需将它包装在一个PHP脚本中,我们称之为......

<强> wrapper.php

<?php

  // Fetch the arguments we need to pass on to the external tool
  $userfile = $argv[1];

  // Do any necessary pre-processing of the file here
  $startTime = microtime(TRUE);

  // Execute the external program
  exec("C:/path/to/tool.exe \"$userfile\"");

  // By the time we get here, the external tool has finished - because
  // we know that a standard call to exec() will block until the called
  // process finishes
  $endTime = microtime(TRUE);

  // Log the times etc and do any post processing here

因此,我们不是直接执行工具,而是在主脚本中创建命令:

$cmdToExecute = "php wrapper.php \"$userfile\"";

......我们应该为你想做的事情提供一个精确可控的解决方案。

N.B。在必要时不要忘记escapeshellarg()