предварительное управление процессом в PHP - PullRequest
1 голос
/ 02 января 2012

Мне нужно построить систему, чтобы пользователь отправлял файл на сервер Затем php запустит инструмент командной строки, используя system () (пример tool.exe, файл пользователя) мне нужен способ увидеть pid процесса, чтобы узнать пользователя, который запустил инструмент и способ узнать, когда инструмент остановился.

Возможно ли это на компьютере с Windows Vista, я не могу перейти на сервер Linux.

кроме того, что код должен продолжать выполняться, когда пользователь закрывает окна браузера

1 Ответ

3 голосов
/ 03 января 2012

Вместо того, чтобы пытаться получить идентификатор процесса и отслеживать, как долго он выполняется, я думаю, что вам нужно иметь «обертку», которая обрабатывает предварительную / последующую обработку, такую ​​как ведение журнала или манипулирование базой данных.

Первый шаг - создание асинхронного процесса, который будет запускаться независимо от родительского процесса и запускаться при обращении к веб-странице.

Для этого в 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\"";

... и у нас должно быть точно контролируемое решение для того, что вы хотите сделать.

NB. Не забудьте escapeshellarg(), где это необходимо!

...