Bearsampp 2026.5.5
Loading...
Searching...
No Matches
CommandRunner Class Reference

Static Public Member Functions

static background (string $command)
static exec (string $executable, array $args=[], string &$stderr='')
static execCombined (string $executable, array $args=[])
static shellExec (string $command)
static stream (string $executable, array $args, callable $lineCallback)

Static Private Member Functions

static writeLog (string $log)

Detailed Description

Class CommandRunner

Centralizes all PHP shell-execution primitives (proc_open, popen, shell_exec) so that every external command goes through a single, auditable point with consistent argument escaping and logging.

Three execution modes:

  • exec() capture stdout/stderr, hidden console window (replaces proc_open)
  • stream() stream output line-by-line via callback (replaces popen)
  • shellExec() capture output from a fully-formed command (replaces shell_exec)

Rules:

  • exec() and stream() always escapeshellarg() every argument individually.
  • shellExec() is reserved for hardcoded commands with no dynamic user input. Pass dynamic arguments through exec() or stream() instead.

Definition at line 27 of file class.commandrunner.php.

Member Function Documentation

◆ background()

background ( string $command)
static

Launch a command in the background without waiting for output.

Uses the Windows "start /B" cmd.exe idiom to detach the process immediately. The caller is responsible for ensuring $command is properly constructed; use escapeshellarg() on any dynamic values before passing them in.

Parameters
string$commandFully-formed command string to run in the background.

Definition at line 168 of file class.commandrunner.php.

168 : void
169 {
170 self::writeLog('CommandRunner::background: ' . $command);
171 pclose(popen('start /B ' . $command, 'r'));
172 }
static writeLog(string $log)

References writeLog().

◆ exec()

exec ( string $executable,
array $args = [],
string & $stderr = '' )
static

Execute an executable with arguments, capturing stdout and stderr.

Each argument is individually escaped with escapeshellarg(). The console window is hidden on Windows via bypass_shell + CREATE_NO_WINDOW semantics.

Parameters
string$executablePath to the executable (will be escapeshellarg'd).
array$argsArguments, each will be escapeshellarg'd.
string$stderrPopulated with any stderr output on return.
Returns
string|false stdout output on success, false if the process could not start.

Definition at line 51 of file class.commandrunner.php.

51 : string|false
52 {
53 $cmd = escapeshellarg($executable);
54 foreach ($args as $arg) {
55 $cmd .= ' ' . escapeshellarg((string) $arg);
56 }
57
58 self::writeLog('CommandRunner::exec: ' . $cmd);
59
60 $descriptorspec = [
61 0 => ['pipe', 'r'],
62 1 => ['pipe', 'w'],
63 2 => ['pipe', 'w'],
64 ];
65
66 $process = @proc_open($cmd, $descriptorspec, $pipes, null, null, ['bypass_shell' => true]);
67
68 if (!is_resource($process)) {
69 self::writeLog('CommandRunner::exec: failed to start process: ' . $cmd);
70 return false;
71 }
72
73 fclose($pipes[0]);
74 $output = stream_get_contents($pipes[1]);
75 $stderr = stream_get_contents($pipes[2]);
76 fclose($pipes[1]);
77 fclose($pipes[2]);
78 proc_close($process);
79
80 if (!empty($stderr)) {
81 self::writeLog('CommandRunner::exec stderr: ' . $stderr);
82 }
83
84 return $output;
85 }

References writeLog().

Referenced by execCombined(), and Core\unzipFile().

◆ execCombined()

execCombined ( string $executable,
array $args = [] )
static

Execute an executable with arguments, combining stdout and stderr.

Convenience wrapper around exec() for callers that need both streams merged (e.g. sc.exe which may send status messages to either stream).

Parameters
string$executablePath to the executable (will be escapeshellarg'd).
array$argsArguments, each will be escapeshellarg'd.
Returns
string|false Combined output, or false if the process could not start.

Definition at line 97 of file class.commandrunner.php.

97 : string|false
98 {
99 $stderr = '';
100 $output = self::exec($executable, $args, $stderr);
101
102 if ($output === false) {
103 return false;
104 }
105
106 if (!empty($stderr)) {
107 $output .= "\n" . $stderr;
108 }
109
110 return $output;
111 }
static exec(string $executable, array $args=[], string &$stderr='')

References exec().

Referenced by Win32Service\fastServiceCheck().

◆ shellExec()

shellExec ( string $command)
static

Execute a fully-formed shell command and return its output.

Only use this for commands that contain no dynamic user input (e.g. hardcoded system queries such as "net session" or "whoami /groups"). For commands with dynamic arguments, use exec() or stream() instead so that escaping is enforced at the boundary.

Parameters
string$commandFully-formed command string. Must not contain unescaped user input.
Returns
string|null Command output, or null if the command could not be run.

Definition at line 185 of file class.commandrunner.php.

185 : ?string
186 {
187 self::writeLog('CommandRunner::shellExec: ' . $command);
188 return shell_exec($command);
189 }

References writeLog().

Referenced by Util\isAdmin().

◆ stream()

stream ( string $executable,
array $args,
callable $lineCallback )
static

Execute an executable with arguments, streaming output line-by-line.

Useful for long-running processes that emit progress information. Each argument is individually escaped with escapeshellarg(). Lines are split on carriage-return (\r) to match Windows progress-reporting conventions. Any data remaining in the buffer after EOF is flushed as a final line.

Parameters
string$executablePath to the executable (will be escapeshellarg'd).
array$argsArguments, each will be escapeshellarg'd.
callable$lineCallbackInvoked with each trimmed output line as a string.
Returns
int|false Process exit code on success, false if the process could not start.

Definition at line 126 of file class.commandrunner.php.

126 : int|false
127 {
128 $cmd = escapeshellarg($executable);
129 foreach ($args as $arg) {
130 $cmd .= ' ' . escapeshellarg((string) $arg);
131 }
132
133 self::writeLog('CommandRunner::stream: ' . $cmd);
134
135 $process = popen($cmd, 'rb');
136 if (!$process) {
137 self::writeLog('CommandRunner::stream: failed to start process: ' . $cmd);
138 return false;
139 }
140
141 $buffer = '';
142 while (!feof($process)) {
143 $buffer .= fread($process, 8192);
144 while (($pos = strpos($buffer, "\r")) !== false) {
145 $line = trim(substr($buffer, 0, $pos));
146 $buffer = substr($buffer, $pos + 1);
147 $lineCallback($line);
148 }
149 }
150
151 // Flush any remaining data not terminated by \r
152 if (!empty($buffer)) {
153 $lineCallback(trim($buffer));
154 }
155
156 return pclose($process);
157 }

References writeLog().

Referenced by Core\unzipFile().

◆ writeLog()

writeLog ( string $log)
staticprivate

Writes a log entry to the batch log file.

Parameters
string$logThe message to log.

Definition at line 34 of file class.commandrunner.php.

34 : void
35 {
36 global $bearsamppRoot;
37 Log::debug($log, $bearsamppRoot->getBatchLogFilePath());
38 }
global $bearsamppRoot
static debug($data, $file=null)

References $bearsamppRoot, and Log\debug().

Referenced by background(), exec(), shellExec(), and stream().


The documentation for this class was generated from the following file: