Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. Process.php

function Process::start

Starts the process and returns after writing the input to STDIN.

This method blocks until all STDIN data is sent to the process then it returns while the process runs in the background.

The termination of the process can be awaited with wait().

The callback receives the type of output (out or err) and some bytes from the output in real-time while writing the standard input to the process. It allows to have feedback from the independent process during execution.

Parameters

callable|null $callback A PHP callback to run whenever there is some: output available on STDOUT or STDERR

Throws

ProcessStartFailedException When process can't be launched

RuntimeException When process is already running

LogicException In case a callback is provided and output has been disabled

5 calls to Process::start()
PhpProcess::start in vendor/symfony/process/PhpProcess.php
Starts the process and returns after writing the input to STDIN.
PhpProcess::start in vendor/symfony/process/PhpProcess.php
Starts the process and returns after writing the input to STDIN.
PhpSubprocess::start in vendor/symfony/process/PhpSubprocess.php
Starts the process and returns after writing the input to STDIN.
PhpSubprocess::start in vendor/symfony/process/PhpSubprocess.php
Starts the process and returns after writing the input to STDIN.
Process::run in vendor/symfony/process/Process.php
Runs the process.
2 methods override Process::start()
PhpProcess::start in vendor/symfony/process/PhpProcess.php
Starts the process and returns after writing the input to STDIN.
PhpSubprocess::start in vendor/symfony/process/PhpSubprocess.php
Starts the process and returns after writing the input to STDIN.

File

vendor/symfony/process/Process.php, line 295

Class

Process
Process is a thin wrapper around proc_* functions to easily start independent PHP processes.

Namespace

Symfony\Component\Process

Code

public function start(?callable $callback = null, array $env = []) : void {
    if ($this->isRunning()) {
        throw new RuntimeException('Process is already running.');
    }
    $this->resetProcessData();
    $this->starttime = $this->lastOutputTime = microtime(true);
    $this->callback = $this->buildCallback($callback);
    $descriptors = $this->getDescriptors(null !== $callback);
    if ($this->env) {
        $env += '\\' === \DIRECTORY_SEPARATOR ? array_diff_ukey($this->env, $env, 'strcasecmp') : $this->env;
    }
    $env += '\\' === \DIRECTORY_SEPARATOR ? array_diff_ukey($this->getDefaultEnv(), $env, 'strcasecmp') : $this->getDefaultEnv();
    if (\is_array($commandline = $this->commandline)) {
        $commandline = array_values(array_map(strval(...), $commandline));
    }
    else {
        $commandline = $this->replacePlaceholders($commandline, $env);
    }
    if ('\\' === \DIRECTORY_SEPARATOR) {
        $commandline = $this->prepareWindowsCommandLine($commandline, $env);
    }
    elseif ($this->isSigchildEnabled()) {
        // last exit code is output on the fourth pipe and caught to work around --enable-sigchild
        $descriptors[3] = [
            'pipe',
            'w',
        ];
        if (\is_array($commandline)) {
            // exec is mandatory to deal with sending a signal to the process
            $commandline = 'exec ' . $this->buildShellCommandline($commandline);
        }
        // See https://unix.stackexchange.com/questions/71205/background-process-pipe-input
        $commandline = '{ (' . $commandline . ') <&3 3<&- 3>/dev/null & } 3<&0;';
        $commandline .= 'pid=$!; echo $pid >&3; wait $pid 2>/dev/null; code=$?; echo $code >&3; exit $code';
    }
    $envPairs = [];
    foreach ($env as $k => $v) {
        if (false !== $v && false === \in_array($k, [
            'argc',
            'argv',
            'ARGC',
            'ARGV',
        ], true)) {
            $envPairs[] = $k . '=' . $v;
        }
    }
    if (!is_dir($this->cwd)) {
        throw new RuntimeException(\sprintf('The provided cwd "%s" does not exist.', $this->cwd));
    }
    $lastError = null;
    set_error_handler(function ($type, $msg) use (&$lastError) {
        $lastError = $msg;
        return true;
    });
    $oldMask = [];
    if ($this->ignoredSignals && \function_exists('pcntl_sigprocmask')) {
        // we block signals we want to ignore, as proc_open will use fork / posix_spawn which will copy the signal mask this allow to block
        // signals in the child process
        pcntl_sigprocmask(\SIG_BLOCK, $this->ignoredSignals, $oldMask);
    }
    try {
        $process = @proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $this->options);
        // Ensure array vs string commands behave the same
        if (!$process && \is_array($commandline)) {
            $process = @proc_open('exec ' . $this->buildShellCommandline($commandline), $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $this->options);
        }
    } finally {
        if ($this->ignoredSignals && \function_exists('pcntl_sigprocmask')) {
            // we restore the signal mask here to avoid any side effects
            pcntl_sigprocmask(\SIG_SETMASK, $oldMask);
        }
        restore_error_handler();
    }
    if (!$process) {
        throw new ProcessStartFailedException($this, $lastError);
    }
    $this->process = $process;
    $this->status = self::STATUS_STARTED;
    if (isset($descriptors[3])) {
        $this->fallbackStatus['pid'] = (int) fgets($this->processPipes->pipes[3]);
    }
    if ($this->tty) {
        return;
    }
    $this->updateStatus(false);
    $this->checkTimeout();
}
RSS feed
Powered by Drupal