Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 90 additions & 49 deletions src/BackgroundProcess.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
* @license http://opensource.org/licenses/MIT The MIT License
* @link https://florian.ec/articles/running-background-processes-in-php/ Running background processes in PHP
*/
class BackgroundProcess
{
class BackgroundProcess {

const OS_WINDOWS = 1;
const OS_NIX = 2;
const OS_OTHER = 3;
const OS_NIX = 2;
const OS_OTHER = 3;

/**
* @var string
Expand All @@ -47,9 +47,8 @@ class BackgroundProcess
*
* @codeCoverageIgnore
*/
public function __construct($command = null)
{
$this->command = $command;
public function __construct($command = null) {
$this->command = $command;
$this->serverOS = $this->getOS();
}

Expand All @@ -60,25 +59,43 @@ public function __construct($command = null)
* currently $outputFile has no effect when used in conjunction with a Windows server
* @param bool $append - set to true if output should be appended to $outputfile
*/
public function run($outputFile = '/dev/null', $append = false)
{
if($this->command === null) {
public function run($outputFile = '/dev/null', $append = false) {
if ($this->command === null) {
return;
}

switch ($this->getOS()) {
case self::OS_WINDOWS:
shell_exec(sprintf('%s &', $this->command, $outputFile));

$startDir = ".";

$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
);

$prog = proc_open("start /b " . $this->command, $descriptorspec, $pipes, $startDir, NULL);
if (is_resource($prog)) {
$ppid = proc_get_status($prog)['pid'];
} else {
throw new RuntimeException(sprintf(
'Could not execute command "%s"', $this->command
));
}

$output = array_filter(explode(" ", shell_exec("wmic process get parentprocessid,processid | find \"$ppid\"")));
array_pop($output);
$this->pid = end($output);

//shell_exec(sprintf('%s &', $this->command, $outputFile));
break;
case self::OS_NIX:
$this->pid = (int)shell_exec(sprintf('%s %s %s 2>&1 & echo $!', $this->command, ($append) ? '>>' : '>', $outputFile));
$this->pid = (int) shell_exec(sprintf('%s %s %s 2>&1 & echo $!', $this->command, ($append) ? '>>' : '>', $outputFile));
break;
default:
throw new RuntimeException(sprintf(
'Could not execute command "%s" because operating system "%s" is not supported by '.
'Cocur\BackgroundProcess.',
$this->command,
PHP_OS
'Could not execute command "%s" because operating system "%s" is not supported by ' .
'Cocur\BackgroundProcess.', $this->command, PHP_OS
));
}
}
Expand All @@ -88,17 +105,28 @@ public function run($outputFile = '/dev/null', $append = false)
*
* @return bool TRUE if the process is running, FALSE if not.
*/
public function isRunning()
{
$this->checkSupportingOS('Cocur\BackgroundProcess can only check if a process is running on *nix-based '.
'systems, such as Unix, Linux or Mac OS X. You are running "%s".');

try {
$result = shell_exec(sprintf('ps %d 2>&1', $this->pid));
if (count(preg_split("/\n/", $result)) > 2 && !preg_match('/ERROR: Process ID out of range/', $result)) {
return true;
}
} catch (Exception $e) {
public function isRunning() {
$this->checkSupportingOS('Cocur\BackgroundProcess can only check if a process is running on *nix-based ' .
'systems, such as Unix, Linux or Mac OS X. You are running "%s".');

switch ($this->getOS()) {
case self::OS_WINDOWS:
$result = shell_exec("tasklist /fi \"PID eq $this->pid\"");
if (!(preg_match('/INFO: No tasks are running which match the specified criteria/', $result)) && preg_match('/' . $this->pid . '/', $result)) {
return true;
}
break;

case self::OS_NIX:
try {
$result = shell_exec(sprintf('ps %d 2>&1', $this->pid));
if (count(preg_split("/\n/", $result)) > 2 && !preg_match('/ERROR: Process ID out of range/', $result)) {
return true;
}
} catch (Exception $e) {

}
break;
}

return false;
Expand All @@ -109,19 +137,35 @@ public function isRunning()
*
* @return bool `true` if the processes was stopped, `false` otherwise.
*/
public function stop()
{
$this->checkSupportingOS('Cocur\BackgroundProcess can only stop a process on *nix-based systems, such as '.
'Unix, Linux or Mac OS X. You are running "%s".');

try {
$result = shell_exec(sprintf('kill %d 2>&1', $this->pid));
if (!preg_match('/No such process/', $result)) {
return true;
}
} catch (Exception $e) {
public function stop() {
$this->checkSupportingOS('Cocur\BackgroundProcess can only stop a process on *nix-based systems, such as ' .
'Unix, Linux or Mac OS X. You are running "%s".');

switch ($this->getOS()) {
case self::OS_WINDOWS:
try {
$result = shell_exec("taskkill /F /PID $this->pid 2>&1");
if (preg_match('/SUCCESS: The process with PID ' . $this->pid . ' has been terminated./', $result)) {
return true;
}
} catch (Exception $e) {

}
break;

case self::OS_NIX:
try {
$result = shell_exec(sprintf('kill %d 2>&1', $this->pid));
if (!preg_match('/No such process/', $result)) {
return true;
}
} catch (Exception $e) {

}
break;
}


return false;
}

Expand All @@ -130,10 +174,9 @@ public function stop()
*
* @return int The ID of the process
*/
public function getPid()
{
$this->checkSupportingOS('Cocur\BackgroundProcess can only return the PID of a process on *nix-based systems, '.
'such as Unix, Linux or Mac OS X. You are running "%s".');
public function getPid() {
$this->checkSupportingOS('Cocur\BackgroundProcess can only return the PID of a process on *nix-based systems, ' .
'such as Unix, Linux or Mac OS X. You are running "%s".');

return $this->pid;
}
Expand All @@ -143,16 +186,14 @@ public function getPid()
*
* @param $pid
*/
protected function setPid($pid)
{
protected function setPid($pid) {
$this->pid = $pid;
}

/**
* @return int
*/
protected function getOS()
{
protected function getOS() {
$os = strtoupper(PHP_OS);

if (substr($os, 0, 3) === 'WIN') {
Expand All @@ -171,9 +212,8 @@ protected function getOS()
*
* @codeCoverageIgnore
*/
protected function checkSupportingOS($message)
{
if ($this->getOS() !== self::OS_NIX) {
protected function checkSupportingOS($message) {
if (!in_array($this->getOS(), array(self::OS_NIX, self::OS_WINDOWS))) {
throw new RuntimeException(sprintf($message, PHP_OS));
}
}
Expand All @@ -189,4 +229,5 @@ static public function createFromPID($pid) {

return $process;
}

}