Click the Castor logo or press Ctrl Alt T to change theme.
# Starting processes `Process::start()` is the lower-level entry point for interactive or manually controlled processes. ```php Process::start(array|string $command, ?string $cwd = null, ?array $env = null): Process ``` Internally it opens a child process with PHP's `proc_open()` and attaches the three process pipes to Castor IO native streams. If you only need to run a command and collect its output, prefer `Process::run()` from the [getting started guide](getting-started.html#run-a-command). ## Prefer argument arrays The safest and most portable shape is an array where the first element is the executable and the remaining elements are arguments: ```php <?php use Castor\Os\Process; $process = Process::start(['git', 'status', '--short']); ``` Use this form when any argument comes from a variable: ```php $branch = 'main'; $process = Process::start(['git', 'rev-parse', '--verify', $branch]); ``` With an array command, each array item is passed as one argument. You do not need to quote spaces for the shell, and user input is not interpreted as shell syntax by Castor Process. ## Command strings `Process::start()` also accepts a command string because `proc_open()` accepts one: ```php $process = Process::start('printf "%s\n" "$HOME"'); ``` Use a string only when you deliberately want shell parsing, shell expansions, pipes, redirects, or compound commands. If dynamic values are interpolated into a string command, escape them with PHP's shell-escaping functions before passing the command to `Process::start()`. ```php $file = '/tmp/report name.txt'; $process = Process::start('cat ' . escapeshellarg($file)); ``` ## Working directory Pass `cwd` to run the child process from a specific directory: ```php $process = Process::start(['git', 'status', '--short'], cwd: '/srv/app'); ``` When `cwd` is `null`, PHP uses the current working directory of the parent PHP process. ## Environment variables Pass `env` as an associative array of string keys and string values: ```php <?php use Castor\Os\Process; use function Castor\Io\read_all; $process = Process::start( ['php', '-r', 'echo getenv("APP_ENV");'], env: ['APP_ENV' => 'test'], ); $exitCode = $process->wait(); $output = read_all($process->stdout); $process->close(); echo $exitCode; // 0 echo $output; // test ``` `Process::start()` formats the array as `KEY=value` entries for `proc_open()`. Keep keys and values as strings and avoid embedding null bytes or platform-specific environment syntax. ## Process object returned by start A successful call returns a `Process` object with these public streams: ```php $process->stdin; // Castor\Io\Writer&Castor\Io\Closer $process->stdout; // Castor\Io\Reader&Castor\Io\Closer $process->stderr; // Castor\Io\Reader&Castor\Io\Closer ``` The process begins running immediately. You can write to `stdin`, send newline-terminated input with `stdin->sendLine()`, read from `stdout` or `stderr`, poll with `isRunning()`, wait with `wait()`, terminate with `terminate()`, or close resources with `close()`. ## Startup failures `Process::start()` delegates startup to `proc_open()`. Invalid descriptors, invalid argument types, disabled functions, missing executables, permission problems, or operating-system failures surface according to PHP and the platform. Some failures happen at startup; others start a shell or executable successfully and then produce stderr output plus a non-zero exit code. Do not assume that `Process::start()` returning a `Process` means the command succeeded. It only means the child process was opened. Use `wait()` and `getExitCode()` to inspect the command result.
Castor ecosystem