BackgroundProcess::stop()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.1406

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 15
ccs 6
cts 8
cp 0.75
rs 9.4285
cc 3
eloc 9
nc 4
nop 0
crap 3.1406
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($this->command === null) {
66
            return;
67
        }
68
69 2
        switch ($this->getOS()) {
70 2
            case self::OS_WINDOWS:
71
                shell_exec(sprintf('%s &', $this->command, $outputFile));
72
                break;
73 2
            case self::OS_NIX:
74 2
                $this->pid = (int)shell_exec(sprintf('%s %s %s 2>&1 & echo $!', $this->command, ($append) ? '>>' : '>', $outputFile));
75 2
                break;
76
            default:
77
                throw new RuntimeException(sprintf(
78
                    'Could not execute command "%s" because operating system "%s" is not supported by '.
79
                    'Cocur\BackgroundProcess.',
80
                    $this->command,
81
                    PHP_OS
82
                ));
83 2
        }
84 2
    }
85
86
    /**
87
     * Returns if the process is currently running.
88
     *
89
     * @return bool TRUE if the process is running, FALSE if not.
90
     */
91 1
    public function isRunning()
92
    {
93 1
        $this->checkSupportingOS('Cocur\BackgroundProcess can only check if a process is running on *nix-based '.
94 1
                                 'systems, such as Unix, Linux or Mac OS X. You are running "%s".');
95
96
        try {
97 1
            $result = shell_exec(sprintf('ps %d 2>&1', $this->pid));
98 1
            if (count(preg_split("/\n/", $result)) > 2 && !preg_match('/ERROR: Process ID out of range/', $result)) {
99 1
                return true;
100
            }
101 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...
102
        }
103
104 1
        return false;
105
    }
106
107
    /**
108
     * Stops the process.
109
     *
110
     * @return bool `true` if the processes was stopped, `false` otherwise.
111
     */
112 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...
113
    {
114 1
        $this->checkSupportingOS('Cocur\BackgroundProcess can only stop a process on *nix-based systems, such as '.
115 1
                                 'Unix, Linux or Mac OS X. You are running "%s".');
116
117
        try {
118 1
            $result = shell_exec(sprintf('kill %d 2>&1', $this->pid));
119 1
            if (!preg_match('/No such process/', $result)) {
120 1
                return true;
121
            }
122
        } catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
123
        }
124
125
        return false;
126
    }
127
128
    /**
129
     * Returns the ID of the process.
130
     *
131
     * @return int The ID of the process
132
     */
133 1
    public function getPid()
134
    {
135 1
        $this->checkSupportingOS('Cocur\BackgroundProcess can only return the PID of a process on *nix-based systems, '.
136 1
                                 'such as Unix, Linux or Mac OS X. You are running "%s".');
137
138 1
        return $this->pid;
139
    }
140
141
    /**
142
     * Set the process id.
143
     *
144
     * @param $pid
145
     */
146
    protected function setPid($pid)
147
    {
148
        $this->pid = $pid;
149
    }
150
151
    /**
152
     * @return int
153
     */
154 5
    protected function getOS()
155
    {
156 5
        $os = strtoupper(PHP_OS);
157
158 5
        if (substr($os, 0, 3) === 'WIN') {
159
            return self::OS_WINDOWS;
160 5
        } else if ($os === 'LINUX' || $os === 'FREEBSD' || $os === 'DARWIN') {
161 5
            return self::OS_NIX;
162
        }
163
164
        return self::OS_OTHER;
165
    }
166
167
    /**
168
     * @param string $message Exception message if the OS is not supported
169
     *
170
     * @throws RuntimeException if the operating system is not supported by Cocur\BackgroundProcess
171
     *
172
     * @codeCoverageIgnore
173
     */
174
    protected function checkSupportingOS($message)
175
    {
176
        if ($this->getOS() !== self::OS_NIX) {
177
            throw new RuntimeException(sprintf($message, PHP_OS));
178
        }
179
    }
180
181
    /**
182
     * @param int $pid PID of process to resume
183
     *
184
     * @return Cocur\BackgroundProcess\BackgroundProcess
0 ignored issues
show
Documentation introduced by
Should the return type not be BackgroundProcess?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
185
     */
186 1
    static public function createFromPID($pid) {
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
187 1
        $process = new self();
188 1
        $process->setPid($pid);
189
190 1
        return $process;
191
    }
192
}
193