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

symfony/process

Symfony Process component runs external commands in sub-processes, with built-in support for piping input/output, timeouts, signals, and error handling. Ideal for safely launching CLI tools from PHP applications and capturing their output.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require symfony/process
    

    No additional configuration is required—just autoload via Composer.

  2. First Use Case: Execute a simple command and capture output:

    use Symfony\Component\Process\Process;
    use Symfony\Component\Process\Exception\ProcessFailedException;
    
    $process = new Process(['ls', '-la']);
    $process->run();
    
    if (!$process->isSuccessful()) {
        throw new ProcessFailedException($process);
    }
    
    echo $process->getOutput();
    
  3. Where to Look First:

    • Official Documentation (API reference, examples).
    • Process class methods: run(), getOutput(), getErrorOutput(), isSuccessful().
    • Environment variables: Use $process->setEnv(['KEY' => 'VALUE']) or $process->setEnv($arrayOfEnvs).

Implementation Patterns

Core Workflows

1. Command Execution with Output Handling

$process = new Process(['git', 'status']);
$process->run();

// Incremental output (streaming)
$process->setTimeout(3600); // 1-hour timeout
$process->start();
while ($process->isRunning()) {
    echo $process->getOutput();
    usleep(100); // Throttle to avoid CPU overload
}

2. Environment Variables

  • Array-based envs (Laravel-friendly):
    $envs = [
        'DB_HOST' => env('DB_HOST'),
        'APP_ENV' => 'testing',
        'ARRAY_VAR' => json_encode(['key' => 'value']), // Pass complex data
    ];
    $process->setEnv($envs);
    
  • Merge with system envs:
    $process->inheritEnvironmentVariables(false); // Disable inheritance
    $process->setEnv(['MY_VAR' => 'custom_value']);
    

3. Error Handling

  • Exit code checks:
    if ($process->isSuccessful()) {
        // Success logic
    } else {
        throw new \RuntimeException(
            "Command failed with exit code {$process->getExitCode()}. Error: {$process->getErrorOutput()}"
        );
    }
    
  • Custom exceptions:
    try {
        $process->mustRun(); // Throws ProcessFailedException on failure
    } catch (ProcessFailedException $e) {
        report($e);
    }
    

4. Integration with Laravel

  • Console Commands:
    use Symfony\Component\Process\Process;
    use Illuminate\Console\Command;
    
    class DeployCommand extends Command {
        protected $signature = 'deploy:run';
        public function handle() {
            $process = new Process(['./vendor/bin/deployer', 'deploy']);
            $process->run();
            $this->output->writeln($process->getOutput());
        }
    }
    
  • Artisan Process Wrapper:
    class ProcessService {
        public function run(string $command, array $env = []): string {
            $process = new Process(explode(' ', $command));
            $process->setEnv($env);
            $process->run();
            return $process->getOutput();
        }
    }
    

5. Real-Time Output Streaming

$process = new Process(['tail', '-f', 'app.log']);
$process->start();

while ($process->isRunning()) {
    $output = $process->getOutput();
    if (!empty($output)) {
        $this->log($output); // Custom logger (e.g., Laravel Log)
    }
    usleep(250000); // 0.25s delay
}

6. Timeouts and Resource Limits

$process = new Process(['php', 'artisan', 'queue:work', '--timeout=60']);
$process->setTimeout(300); // 5-minute timeout
$process->run();

7. Cross-Platform Commands

  • Windows/Linux compatibility:
    $command = PHP_OS === 'WINNT'
        ? ['powershell', '-command', 'Get-ChildItem']
        : ['ls', '-la'];
    $process = new Process($command);
    

Advanced Patterns

1. Pipes and Subprocess Chaining

$grep = new Process(['grep', 'error']);
$tail = new Process(['tail', '-n', '100', 'app.log']);

$grep->setInput($tail->getOutput());
$grep->run();

2. Environment Variable Sanitization

  • Filter invalid keys (Laravel .env integration):
    $validEnvKeys = ['APP_ENV', 'DB_HOST', 'QUEUE_CONNECTION'];
    $env = array_filter(envToArray(), fn($key) => in_array($key, $validEnvKeys));
    $process->setEnv($env);
    

3. Process Pooling (Parallel Execution)

use Symfony\Component\Process\Process;

$processes = [];
for ($i = 0; $i < 5; $i++) {
    $processes[] = new Process(['php', 'artisan', 'queue:work', '--queue=high']);
    $processes[$i]->start();
}

foreach ($processes as $process) {
    $process->wait();
}

4. Integration with Symfony Messenger

use Symfony\Component\Process\Process;
use Symfony\Component\Messenger\MessageBus;
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;

$message = new RunProcessMessage(
    command: ['php', 'artisan', 'queue:work'],
    env: ['QUEUE_CONNECTION' => 'database'],
    timeout: 300
);

$bus->dispatch($message);

5. Dynamic Command Generation

$command = [
    'php',
    'artisan',
    'migrate',
    '--database=' . env('DB_CONNECTION'),
    '--force'
];
$process = new Process($command);

Gotchas and Tips

Pitfalls

  1. Environment Variable Limits (Windows)

    • Issue: Windows has a ~32KB limit for environment blocks. Passing large arrays (e.g., json_encode()) may fail.
    • Fix: Use setEnv() with stringified data or split into multiple processes.
      if (PHP_OS === 'WINNT' && strlen(json_encode($env)) > 32000) {
          throw new \RuntimeException('Windows env limit exceeded. Split or stringify data.');
      }
      
  2. Stdin/Stdout Corruption

    • Issue: Broken pipes (e.g., closed stdin) can cause hangs or crashes.
    • Fix: Use mustRun() or check isRunning() before reading output.
      if (!$process->isRunning()) {
          throw new \RuntimeException('Process terminated unexpectedly.');
      }
      
  3. CGI/FastCGI Context Leaks

    • Issue: Subprocesses may inherit server context (e.g., $_SERVER vars), causing security risks.
    • Fix: Use inheritEnvironmentVariables(false) or clear sensitive vars.
      $process->inheritEnvironmentVariables(false);
      $process->setEnv(array_filter($_ENV, fn($key) => !str_starts_with($key, 'HTTP_'), ARRAY_FILTER_USE_KEY));
      
  4. Array Environment Variables

    • Issue: Arrays passed via setEnv() are stringified automatically, but malformed data may cause parsing errors in subprocesses.
    • Fix: Validate and stringify explicitly.
      $env = ['CONFIG' => json_encode(['key' => 'value'])];
      $process->setEnv($env);
      
  5. Timeout Handling

    • Issue: setTimeout() kills the process abruptly, which may leave locks/files in a bad state.
    • Fix: Use graceful shutdowns (e.g., signals) or implement retry logic.
      $process->setTimeout(60);
      try {
          $process->mustRun();
      } catch (ProcessTimedOutException $e) {
          $this->retryOrFail($process);
      }
      
  6. Cross-Platform Paths

    • Issue: Windows uses \, Linux/macOS /. Hardcoded paths may fail.
    • Fix: Normalize paths or use DIRECTORY_SEPARATOR.
      $command = ['php', str_replace('/', DIRECTORY_SEPARATOR, 'path/to/script.php')];
      
  7. PTY Mode Quirks

    • Issue: usePty(true) can mix stdout/stderr output unpredictably.
    • Fix: Avoid PTY
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.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony