Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Process Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require php-standard-library/process
    

    No additional configuration is required—just autoload.

  2. First Use Case: Running a Command in a Laravel Artisan Command

    use PhpStandardLibrary\Process\Process;
    
    class RunSystemCommand extends Command
    {
        protected $signature = 'app:run {command}';
    
        public function handle()
        {
            $process = new Process($this->argument('command'));
            $process->run();
    
            $this->info($process->getOutput());
            if (!$process->isSuccessful()) {
                $this->error($process->getErrorOutput());
            }
        }
    }
    

    Run with:

    php artisan app:run "ls -la"
    
  3. Where to Look First

    • API Reference: Focus on Process::run(), isSuccessful(), getOutput(), and getErrorOutput().
    • Laravel Integration: Use the package in Console/Kernel.php or custom commands for CLI tools.
    • Documentation: PHP Standard Library Docs for advanced features like timeouts and environment variables.

Implementation Patterns

Core Workflows

1. Running Commands in Background Jobs

use PhpStandardLibrary\Process\Process;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class ProcessJob implements ShouldQueue
{
    use Dispatchable, Queueable;

    public function handle()
    {
        $process = new Process(['git', 'pull']);
        $process->setWorkingDirectory(base_path());
        $process->run();

        if (!$process->isSuccessful()) {
            throw new RuntimeException($process->getErrorOutput());
        }
    }
}

Dispatch with:

ProcessJob::dispatch();

2. Streaming Output in Real-Time

$process = new Process('tail -f storage/logs/laravel.log');
$process->start(); // Non-blocking

while ($process->isRunning()) {
    $output = $process->getOutput();
    if (!empty($output)) {
        $this->line($output);
    }
    usleep(100000); // Throttle
}

3. Environment-Specific Process Execution

$process = new Process('php artisan migrate');
$process->setEnv([
    'APP_ENV' => 'testing',
    'DB_CONNECTION' => 'sqlite',
]);
$process->run();

4. Timeout Handling

$process = new Process('php artisan queue:work --once');
$process->setTimeout(60); // 60 seconds
$process->run();

if ($process->isTimedOut()) {
    $process->terminate();
    $this->error('Process timed out!');
}

Laravel-Specific Patterns

1. Service Provider Integration

Bind the Process class to Laravel’s container for dependency injection:

// app/Providers/AppServiceProvider.php
public function register()
{
    $this->app->bind(Process::class, function () {
        return new Process(config('app.default_command'));
    });
}

Use in controllers/commands:

public function __construct(private Process $process) {}

2. Custom Facade (Optional)

Create a facade for cleaner syntax:

// app/Facades/Process.php
namespace App\Facades;

use Illuminate\Support\Facades\Facade;
use PhpStandardLibrary\Process\Process;

class Process extends Facade
{
    protected static function getFacadeAccessor()
    {
        return Process::class;
    }
}

Usage:

Process::run('ls -la')->getOutput();

3. Event-Driven Process Management

Listen for process completion in Laravel events:

// app/Listeners/ProcessCompletedListener.php
public function handle($event)
{
    if (!$event->process->isSuccessful()) {
        event(new ProcessFailed($event->process));
    }
}

Gotchas and Tips

Common Pitfalls

  1. Blocking Calls in Synchronous Contexts

    • Issue: Process::run() blocks execution. If called in a route or middleware, it may time out.
    • Fix: Use Process::start() + Process::wait() for async workflows or offload to queues.
  2. Output Buffering Issues

    • Issue: Commands like ffmpeg or docker may buffer output, causing getOutput() to return empty.
    • Fix: Use --no-buffer flags or stream incrementally with start() + isRunning().
  3. Environment Variable Conflicts

    • Issue: setEnv() overwrites existing vars. Missing vars (e.g., PATH) can break commands.
    • Fix: Merge env vars explicitly:
      $env = array_merge($_ENV, ['CUSTOM_VAR' => 'value']);
      $process->setEnv($env);
      
  4. Working Directory Permissions

    • Issue: Subprocesses inherit PHP’s umask. Commands may fail if the target directory lacks write permissions.
    • Fix: Set permissions before running:
      $process->setWorkingDirectory(storage_path('logs'));
      chmod(storage_path('logs'), 0755);
      
  5. Signal Handling Limitations

    • Issue: The package doesn’t expose SIGKILL or SIGTERM. Forceful termination may leave zombie processes.
    • Fix: Use Process::terminate() for graceful stops and handle failures:
      if (!$process->isSuccessful()) {
          $process->terminate();
          throw new RuntimeException('Process failed');
      }
      

Debugging Tips

  1. Log Raw Output Always log both stdout and stderr for debugging:

    $this->info('STDOUT: ' . $process->getOutput());
    $this->error('STDERR: ' . $process->getErrorOutput());
    
  2. Check Exit Codes Exit codes beyond 0 (success) or 1 (error) may indicate specific failures. Map them in your code:

    switch ($process->getExitCode()) {
        case 127: throw new RuntimeException('Command not found');
        case 137: throw new RuntimeException('Process killed (OOM?)');
        default: throw new RuntimeException('Unknown error');
    }
    
  3. Use strace for Low-Level Debugging On Linux, trace system calls to diagnose hangs:

    strace -f php artisan app:run "your-command"
    

Extension Points

  1. Custom Process Builder Extend the Process class to add Laravel-specific features:

    class LaravelProcess extends Process
    {
        public function withLaravelEnv()
        {
            $this->setEnv([
                'APP_ENV' => env('APP_ENV'),
                'APP_KEY' => env('APP_KEY'),
            ]);
            return $this;
        }
    }
    
  2. Process Middleware Create middleware to validate commands or inject env vars:

    class ProcessMiddleware
    {
        public function handle(Process $process, Closure $next)
        {
            if (str_contains($process->getCommand(), 'dangerous')) {
                throw new \RuntimeException('Command blocked');
            }
            return $next($process);
        }
    }
    
  3. Observability Hooks Add logging/metrics before/after process execution:

    $process->onStart(function () {
        Log::info('Process started', ['command' => $process->getCommand()]);
    });
    
    $process->onComplete(function () {
        Log::info('Process completed', [
            'exit_code' => $process->getExitCode(),
            'duration' => $process->getDuration(),
        ]);
    });
    

Configuration Quirks

  1. Windows-Specific Paths

    • Use forward slashes (/), not backslashes (\), in commands to avoid issues:
      $process = new Process(['cmd', '/c', 'dir', 'C:/path/to/dir']);
      
  2. Shebang Lines

    • If running scripts, ensure the shebang (e.g., #!/usr/bin/env php) is executable:
      chmod('path/to/script', 0755);
      $process = new Process(['./path/to/script']);
      
  3. Resource Limits

    • Long-running processes may hit PHP’s max_execution_time. Adjust via:
      ini_set('max_execution_time', 300); // 5 minutes
      $process->run();
      

Performance Considerations

  1. **A
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
calliostro/spotify-bundle
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle