Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
83.33% |
15 / 18 |
|
0.00% |
0 / 1 |
CRAP | |
0.00% |
0 / 1 |
ShellExec | |
83.33% |
15 / 18 |
|
0.00% |
0 / 1 |
9.37 | |
0.00% |
0 / 1 |
exec | |
83.33% |
15 / 18 |
|
0.00% |
0 / 1 |
9.37 |
1 | <?php |
2 | |
3 | namespace ExecWithFallback; |
4 | |
5 | /** |
6 | * Emulate exec() with system() |
7 | * |
8 | * @package ExecWithFallback |
9 | * @author Bjørn Rosell <it@rosell.dk> |
10 | */ |
11 | class ShellExec |
12 | { |
13 | |
14 | /** |
15 | * Emulate exec() with shell_exec() |
16 | * |
17 | * @param string $command The command to execute |
18 | * @param string &$output (optional) |
19 | * @param int &$result_code (optional) |
20 | * |
21 | * @return string | false The last line of output or false in case of failure |
22 | */ |
23 | public static function exec($command, &$output = null, &$result_code = null) |
24 | { |
25 | $resultCodeSupplied = (func_num_args() >= 3); |
26 | if ($resultCodeSupplied) { |
27 | throw new \Exception('ShellExec::exec() does not support $result_code argument'); |
28 | } |
29 | |
30 | $result = shell_exec($command); |
31 | |
32 | // result: |
33 | // - A string containing the output from the executed command, |
34 | // - false if the pipe cannot be established |
35 | // - or null if an error occurs or the command produces no output. |
36 | // PHP stan complains on systems which reports that shell_exec returns string|null (not false) |
37 | // So, we added the ignore line AND we have set "reportUnmatchedIgnoredErrors: false" in phpstan config |
38 | |
39 | /** @phpstan-ignore-next-line */ |
40 | if ($result === false) { |
41 | return false; |
42 | } |
43 | |
44 | if (is_null($result)) { |
45 | // hm, "null if an error occurs or the command produces no output." |
46 | // What were they thinking? |
47 | // And yes, it does return null, when no output, which is confirmed in the test "echo hi 1>/dev/null" |
48 | // What should we do? Throw or accept? |
49 | // Perhaps shell_exec throws in newer versions of PHP instead of returning null. |
50 | // We are counting on it until proved wrong. |
51 | return ''; |
52 | } |
53 | |
54 | $theOutput = preg_split('/\s*\r\n|\s*\n\r|\s*\n|\s*\r/', $result); |
55 | |
56 | // remove the last element if it is blank |
57 | if ((count($theOutput) > 0) && ($theOutput[count($theOutput) -1] == '')) { |
58 | array_pop($theOutput); |
59 | } |
60 | |
61 | if (count($theOutput) == 0) { |
62 | return ''; |
63 | } |
64 | if (gettype($output) == 'array') { |
65 | foreach ($theOutput as $line) { |
66 | $output[] = $line; |
67 | } |
68 | } else { |
69 | $output = $theOutput; |
70 | } |
71 | return $theOutput[count($theOutput) -1]; |
72 | } |
73 | } |