Completed
Pull Request — master (#19)
by Frank
02:31
created

BackgroundProcess::isRunning()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 15
ccs 8
cts 8
cp 1
rs 9.2
cc 4
eloc 9
nc 4
nop 0
crap 4
1
<?php
2
3
/**
4
 * This file is part of cocur/background-process.
5
 *
6
 * (c) 2013-2015 Florian Eckerstorfer
7
 */
8
9
namespace Cocur\BackgroundProcess;
10
11
use Exception;
12
use RuntimeException;
13
14
/**
15
 * BackgroundProcess.
16
 *
17
 * Runs a process in the background.
18
 *
19
 * @author    Florian Eckerstorfer <[email protected]>
20
 * @copyright 2013-2015 Florian Eckerstorfer
21
 * @license   http://opensource.org/licenses/MIT The MIT License
22
 * @link      https://florian.ec/articles/running-background-processes-in-php/ Running background processes in PHP
23
 */
24
class BackgroundProcess
25
{
26
    const OS_WINDOWS = 1;
27
    const OS_NIX     = 2;
28
    const OS_OTHER   = 3;
29
30
    /**
31
     * @var string
32
     */
33
    private $command;
34
35
    /**
36
     * @var int
37
     */
38
    private $pid;
39
40
    /**
41
     * @var int
42
     */
43
    protected $serverOS;
44
45
    /**
46
     * @param string $command The command to execute
0 ignored issues
show
Documentation introduced by
Should the type for parameter $command not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
47
     *
48
     * @codeCoverageIgnore
49
     */
50
    public function __construct($command = null)
51
    {
52
        $this->command  = $command;
53
        $this->serverOS = $this->getOS();
54
    }
55
56
    /**
57
     * Runs the command in a background process.
58
     *
59
     * @param string $outputFile File to write the output of the process to; defaults to /dev/null
60
     *                           currently $outputFile has no effect when used in conjunction with a Windows server
61
     * @param bool $append - set to true if output should be appended to $outputfile
62
     */
63 2
    public function run($outputFile = '/dev/null', $append = false)
64
    {
65 2
        if(is_null($this->command)) return;
66 2
        switch ($this->getOS()) {
67 2
            case self::OS_WINDOWS:
68
                shell_exec(sprintf('%s &', $this->command, $outputFile));
69
                break;
70 2
            case self::OS_NIX:
71 2
                $this->pid = (int)shell_exec(sprintf('%s %s %s 2>&1 & echo $!', $this->command, ($append) ? '>>' : '>', $outputFile));
72 2
                break;
73
            default:
74
                throw new RuntimeException(sprintf(
75
                    'Could not execute command "%s" because operating system "%s" is not supported by '.
76
                    'Cocur\BackgroundProcess.',
77
                    $this->command,
78
                    PHP_OS
79
                ));
80 2
        }
81 2
    }
82
83
    /**
84
     * Returns if the process is currently running.
85
     *
86
     * @return bool TRUE if the process is running, FALSE if not.
87
     */
88 1
    public function isRunning()
89
    {
90 1
        $this->checkSupportingOS('Cocur\BackgroundProcess can only check if a process is running on *nix-based '.
91 1
                                 'systems, such as Unix, Linux or Mac OS X. You are running "%s".');
92
93
        try {
94 1
            $result = shell_exec(sprintf('ps %d 2>&1', $this->pid));
95 1
            if (count(preg_split("/\n/", $result)) > 2 && !preg_match('/ERROR: Process ID out of range/', $result)) {
96 1
                return true;
97
            }
98 1
        } catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
99
        }
100
101 1
        return false;
102
    }
103
104
    /**
105
     * Stops the process.
106
     *
107
     * @return bool `true` if the processes was stopped, `false` otherwise.
108
     */
109 1
    public function stop()
0 ignored issues
show
Coding Style introduced by
function stop() does not seem to conform to the naming convention (^(?:is|has|should|may|supports|filter)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
110
    {
111 1
        $this->checkSupportingOS('Cocur\BackgroundProcess can only stop a process on *nix-based systems, such as '.
112 1
                                 'Unix, Linux or Mac OS X. You are running "%s".');
113
114
        try {
115 1
            $result = shell_exec(sprintf('kill %d 2>&1', $this->pid));
116 1
            if (!preg_match('/No such process/', $result)) {
117 1
                return true;
118
            }
119
        } catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
120
        }
121
122
        return false;
123
    }
124
125
    /**
126
     * Returns the ID of the process.
127
     *
128
     * @return int The ID of the process
129
     */
130 1
    public function getPid()
131
    {
132 1
        $this->checkSupportingOS('Cocur\BackgroundProcess can only return the PID of a process on *nix-based systems, '.
133 1
                                 'such as Unix, Linux or Mac OS X. You are running "%s".');
134
135 1
        return $this->pid;
136
    }
137
    
138
    /**
139
     * Set the process id.
140
     * 
141
     * @param $pid
142
     */
143
    public function setPid($pid)
144
    {
145
        $this->pid = $pid;
146
    }
147
148
    /**
149
     * @return int
150
     */
151 5
    protected function getOS()
152
    {
153 5
        $os = strtoupper(PHP_OS);
154
155 5
        if (substr($os, 0, 3) === 'WIN') {
156
            return self::OS_WINDOWS;
157 5
        } else if ($os === 'LINUX' || $os === 'FREEBSD' || $os === 'DARWIN') {
158 5
            return self::OS_NIX;
159
        }
160
161
        return self::OS_OTHER;
162
    }
163
164
    /**
165
     * @param string $message Exception message if the OS is not supported
166
     *
167
     * @throws RuntimeException if the operating system is not supported by Cocur\BackgroundProcess
168
     *
169
     * @codeCoverageIgnore
170
     */
171
    protected function checkSupportingOS($message)
172
    {
173
        if ($this->getOS() !== self::OS_NIX) {
174
            throw new RuntimeException(sprintf($message, PHP_OS));
175
        }
176
    }
177
}
178