php-standard-library/process
Typed, non-blocking PHP API for spawning, monitoring, and controlling child processes. Manage stdin/stdout/stderr streams, retrieve exit codes, and handle timeouts and signals with a clean, reliable interface for long-running and parallel tasks.
Bus/Dispatchable) and real-time output streaming for logging or progress tracking.stdout/stderr) and exit code validation provide a foundation for integrating with Laravel’s monitoring tools (e.g., Telescope, Sentry) or custom observability pipelines.exec() calls.Process facade (e.g., Process::run('command')) to mimic Laravel’s fluent API, improving developer ergonomics and consistency.ProcessJob extending ShouldQueue), with output captured and logged post-execution.Artisan::call() for CLI tools, enabling richer process management (e.g., timeouts, streaming) without reinventing the wheel.setTimeout()).ulimit in Docker).Illuminate\Contracts\Queue\ShouldBeQueued for idempotency.Scope of Adoption:
exec()/shell_exec() calls, or only specific workflows (e.g., CLI tools vs. API endpoints)?Error Handling Strategy:
ProcessFailed) or rollback transactions?spatie/laravel-queue-retries.)Performance Benchmarks:
proc_open()) in terms of:
Security Hardening:
rm -rf)?Observability:
stdout/stderr) be archived for auditing?Long-Term Maintenance:
Laravel CLI Tools:
exec(): Migrate custom Artisan commands from raw shell calls to php-standard-library/process for safer, structured execution.exec('git pull') with:
Process::run(['git', 'pull'])->throwUnlessSuccessful();
Symfony/Style for Artisan).Background Jobs:
ProcessJob extending ShouldQueue) to avoid blocking HTTP requests.stdout/stderr in the database or log files for async processing.ProcessJob::dispatch('docker build -t app:latest .')
->afterRelease(function ($job, $process) {
Log::info('Process output:', ['output' => $process->getOutput()]);
});
API Integrations:
docker, ffmpeg) or APIs with structured error handling.$process = Process::run('curl -s https://api.example.com/data | jq .status');
if ($process->isSuccessful() && $process->getOutput() === 'ok') {
// Proceed
}
Testing:
Process to test command outcomes without executing subprocesses.$mockProcess = Mockery::mock(Process::class);
$mockProcess->shouldReceive('run')->andReturnSelf();
$mockProcess->shouldReceive('isSuccessful')->andReturn(true);
Phase 1: Core Integration (1–2 Sprints)
exec() calls in CLI commands and critical paths.Process service class (e.g., App\Services\ProcessManager) to centralize usage.Process::run()) for consistency with Laravel’s conventions.throwUnlessSuccessful()).Process component with documentation for common use cases.Phase 2: Queue Integration (2–3 Sprints)
ProcessJob class extending ShouldQueue.Phase 3: Observability & Security (Ongoing)
PHP Version:
composer require php:^8.2 and test with Laravel’s PHP version matrix.OS Dependencies:
$process->run(['git', 'status'], ['cwd' => str_replace('\\', '/', base_path())]);
Laravel Facades:
// config/app.php
'aliases' => [
'Process' => App\Facades\Process::class,
];
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class Process extends Facade {
protected static function getFacadeAccessor() {
return 'process.manager';
}
}
Foundational Layer:
ProcessManager service class with core methods (run, isSuccessful, getOutput).AppServiceProvider.Error Handling:
ProcessException class and tie it to Laravel’s exception handler.How can I help you explore Laravel packages today?