mikehaertl/php-shellcommand
Run and manage shell commands from PHP with a simple, safe API. Capture output, exit codes, and errors; set timeouts, working dir, env vars, and pipes; build commands with proper escaping. Useful for CLI wrappers and background jobs.
Start by requiring the package via Composer: composer require mikehaertl/php-shellcommand. Then, instantiate a ShellCommand object with the base command and execute it:
use mikehaertl\ShellCommand\ShellCommand;
$command = new ShellCommand(['ls', '-la', '/tmp']);
if ($command->execute()) {
echo $command->getOutput(); // stdout
echo $command->getErrorOutput(); // stderr
echo $command->getExitCode(); // 0 on success
} else {
throw new \RuntimeException($command->getError());
}
First use case: integrating with system CLI tools (e.g., ffmpeg, convert, git, node) from web tasks like media processing, file generation, or CI orchestration—without messy string concatenation or manual escapeshellarg() calls.
new ShellCommand(['git', 'clone', $url, $dir]) automatically escapes args.setEnv() to define process-specific env vars without polluting the global environment:$command->setEnv(['PATH' => '/usr/local/bin', 'CUSTOM_VAR' => 'value'])setCwd('/app/tmp') ensures commands run in the right context—especially useful for tools like npm or composer.setTimeout(30) (seconds) or setTimeout(0) for no limit.executeAsync() to spawn background processes (e.g., sending notifications, report generation), then poll isRunning() or wait().setStdin('content'), useful for tools expecting pipe input (e.g., gzip, sha256sum).getFullCommand() for logging the exact shell invocation used (helps reproducibility).['binary', '--flag', 'value'] over string commands—avoid cmd.exe pitfalls by using full paths where possible.grep, rsync) return non-zero exit codes for non-error conditions. Always cross-check with getErrorOutput() and tool documentation.getOutput() loads entire output into memory. For large outputs (e.g., tail -f or find . | xargs), consider streaming: implement outputCallback via setOutputCallback(fn($line) => fwrite(STDOUT, $line)).executeAsync(), explicitly wait() or end() to avoid zombie processes—especially in CLI scripts.setShowError(true) on the ShellCommand instance to see the raw proc_open() error message when execution fails unexpectedly.open_basedir or safe_mode (deprecated but still present) may block command execution—always test in production-like environments.How can I help you explore Laravel packages today?