- How do I replace Laravel’s `exec()` or `shell_exec()` with this package in an Artisan command?
- Use the `Shell` class to run commands via `$shell->run('command')`, then access output with `$result->getOutput()` and exit codes with `$result->getExitCode()`. For example, replace `exec('git pull', $output)` with `$shell->run('git pull')->getOutput()`. The package handles escaping and error management automatically.
- Does this package support Laravel’s queued jobs for async shell execution?
- Yes, but streaming output (introduced in v6.1.1) requires buffering—store chunks in Redis or a database during job execution. For non-streaming jobs, use `$shell->run()` directly, as it returns structured results immediately. Async jobs should avoid streaming unless you implement chunk storage.
- Will this work on Windows for Laravel’s cross-platform CLI tools?
- The package supports Windows, but streaming may have quirks (e.g., `cmd.exe` line buffering). Test commands like `php artisan serve` or `composer install` on Windows to verify output consistency. For critical tools, use blocking mode (`$shell->run()`) or implement OS-specific fallbacks.
- How does argument escaping prevent command injection in Laravel?
- The package escapes arguments by default (e.g., `$shell->run('git checkout', ['branch/' . $userInput])` safely handles special characters). For dynamic inputs, use `Command::create()->addArgument($input)` with the package’s escaping layer. This mitigates risks in Laravel’s sensitive workflows (e.g., deployments or `.env`-driven commands).
- Can I stream shell output in real-time for Laravel’s deployments or logs?
- Yes, use `$shell->run('command')->stream(fn($chunk) => Log::info($chunk))` to process output incrementally. For Laravel deployments, this enables live Docker logs or Git streamed output. Buffer chunks in Redis or a database if the job is queued, as streaming callbacks aren’t persisted by default.
- What’s the difference between this and Symfony’s ProcessComponent for Laravel?
- Both provide secure shell execution, but this package focuses on a minimal API with built-in stderr separation and streaming (v6.1.1+). Symfony’s `Process` is more feature-rich (e.g., signals, timeouts) but lacks Laravel-specific integrations like Artisan or queue buffering. Choose this for simplicity; use Symfony if you need advanced process control.
- How do I handle errors or failed commands in Laravel’s exception layer?
- Check `$result->getExitCode() !== 0` or extend `CommandResult` to add custom failure handlers. For example, `$result->onFailure(fn() => Log::error('Command failed: ' . $result->getErrorOutput()))`. Streaming failures (partial output) may require custom logic, like logging the last chunk before the failure.
- Is this package compatible with Laravel 10+ and PHP 8.1+?
- Yes, the package targets modern PHP (8.1+) and integrates with Laravel’s service container via dependency injection (`public function __construct(private Shell $shell)`). Tested features include streaming (PHP 8.1+), which aligns with Laravel’s async-first approach. Check the [docs](https://php-standard-library.dev) for version-specific notes.
- How do I mock this package in PHPUnit for Laravel tests?
- Mock the `Shell` class to return predefined `CommandResult` objects. For example, `$this->mock(Shell::class)->shouldReceive('run')->andReturn(new CommandResult(0, 'output', 'stderr'))`. Streaming tests require custom assertions to verify callback invocations, as mocking callbacks is framework-specific.
- What’s the maintenance status of this package, and should I use it in production?
- The package is actively developed as part of PHP Standard Library but has low adoption (0 stars). For production, evaluate its [issue tracker](https://github.com/php-standard-library/php-standard-library/issues) and test edge cases like streaming failures. Consider wrapping it in a Laravel service layer for easier maintenance or fallback to Symfony’s `Process` if stability is critical.