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

Breadcrumb

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

class PhpSubprocess

PhpSubprocess runs a PHP command as a subprocess while keeping the original php.ini settings.

For this, it generates a temporary php.ini file taking over all the current settings and disables loading additional .ini files. Basically, your command gets prefixed using "php -n -c /tmp/temp.ini".

Given your php.ini contains "memory_limit=-1" and you have a "MemoryTest.php" with the following content:

<?php var_dump(ini_get('memory_limit'));

These are the differences between the regular Process and PhpSubprocess classes:

$p = new Process(['php', '-d', 'memory_limit=256M', 'MemoryTest.php']); $p->run(); print $p->getOutput()."\n";

This will output "string(2) "-1", because the process is started with the default php.ini settings.

$p = new PhpSubprocess(['MemoryTest.php'], null, null, 60, ['php', '-d', 'memory_limit=256M']); $p->run(); print $p->getOutput()."\n";

This will output "string(4) "256M"", because the process is started with the temporarily created php.ini settings.

@author Yanick Witschi <yanick.witschi@terminal42.ch> @author Partially copied and heavily inspired from composer/xdebug-handler by John Stevenson <john-stevenson@blueyonder.co.uk>

Hierarchy

  • class \Symfony\Component\Process\Process implements \Symfony\Component\Process\IteratorAggregate
    • class \Symfony\Component\Process\PhpSubprocess extends \Symfony\Component\Process\Process

Expanded class hierarchy of PhpSubprocess

File

vendor/symfony/process/PhpSubprocess.php, line 44

Namespace

Symfony\Component\Process
View source
class PhpSubprocess extends Process {
    
    /**
     * @param array       $command The command to run and its arguments listed as separate entries. They will automatically
     *                             get prefixed with the PHP binary
     * @param string|null $cwd     The working directory or null to use the working dir of the current PHP process
     * @param array|null  $env     The environment variables or null to use the same environment as the current PHP process
     * @param int         $timeout The timeout in seconds
     * @param array|null  $php     Path to the PHP binary to use with any additional arguments
     */
    public function __construct(array $command, ?string $cwd = null, ?array $env = null, int $timeout = 60, ?array $php = null) {
        if (null === $php) {
            $executableFinder = new PhpExecutableFinder();
            $php = $executableFinder->find(false);
            $php = false === $php ? null : array_merge([
                $php,
            ], $executableFinder->findArguments());
        }
        if (null === $php) {
            throw new RuntimeException('Unable to find PHP binary.');
        }
        $tmpIni = $this->writeTmpIni($this->getAllIniFiles(), sys_get_temp_dir());
        $php = array_merge($php, [
            '-n',
            '-c',
            $tmpIni,
        ]);
        register_shutdown_function('unlink', $tmpIni);
        $command = array_merge($php, $command);
        parent::__construct($command, $cwd, $env, null, $timeout);
    }
    public static function fromShellCommandline(string $command, ?string $cwd = null, ?array $env = null, mixed $input = null, ?float $timeout = 60) : static {
        throw new LogicException(\sprintf('The "%s()" method cannot be called when using "%s".', __METHOD__, self::class));
    }
    public function start(?callable $callback = null, array $env = []) : void {
        if (null === $this->getCommandLine()) {
            throw new RuntimeException('Unable to find the PHP executable.');
        }
        parent::start($callback, $env);
    }
    private function writeTmpIni(array $iniFiles, string $tmpDir) : string {
        if (false === ($tmpfile = @tempnam($tmpDir, ''))) {
            throw new RuntimeException('Unable to create temporary ini file.');
        }
        // $iniFiles has at least one item and it may be empty
        if ('' === $iniFiles[0]) {
            array_shift($iniFiles);
        }
        $content = '';
        foreach ($iniFiles as $file) {
            // Check for inaccessible ini files
            if (($data = @file_get_contents($file)) === false) {
                throw new RuntimeException('Unable to read ini: ' . $file);
            }
            // Check and remove directives after HOST and PATH sections
            if (preg_match('/^\\s*\\[(?:PATH|HOST)\\s*=/mi', $data, $matches, \PREG_OFFSET_CAPTURE)) {
                $data = substr($data, 0, $matches[0][1]);
            }
            $content .= $data . "\n";
        }
        // Merge loaded settings into our ini content, if it is valid
        $config = parse_ini_string($content);
        $loaded = ini_get_all(null, false);
        if (false === $config || false === $loaded) {
            throw new RuntimeException('Unable to parse ini data.');
        }
        $content .= $this->mergeLoadedConfig($loaded, $config);
        // Work-around for https://bugs.php.net/bug.php?id=75932
        $content .= "opcache.enable_cli=0\n";
        if (false === @file_put_contents($tmpfile, $content)) {
            throw new RuntimeException('Unable to write temporary ini file.');
        }
        return $tmpfile;
    }
    private function mergeLoadedConfig(array $loadedConfig, array $iniConfig) : string {
        $content = '';
        foreach ($loadedConfig as $name => $value) {
            if (!\is_string($value)) {
                continue;
            }
            if (!isset($iniConfig[$name]) || $iniConfig[$name] !== $value) {
                // Double-quote escape each value
                $content .= $name . '="' . addcslashes($value, '\\"') . "\"\n";
            }
        }
        return $content;
    }
    private function getAllIniFiles() : array {
        $paths = [
            (string) php_ini_loaded_file(),
        ];
        if (false !== ($scanned = php_ini_scanned_files())) {
            $paths = array_merge($paths, array_map('trim', explode(',', $scanned)));
        }
        return $paths;
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title
PhpSubprocess::fromShellCommandline public static function Creates a Process instance as a command-line to be run in a shell wrapper. Overrides Process::fromShellCommandline
PhpSubprocess::getAllIniFiles private function
PhpSubprocess::mergeLoadedConfig private function
PhpSubprocess::start public function Starts the process and returns after writing the input to STDIN. Overrides Process::start
PhpSubprocess::writeTmpIni private function
PhpSubprocess::__construct public function Overrides Process::__construct
Process::$cachedExitCode private property
Process::$callback private property
Process::$commandline private property
Process::$cwd private property
Process::$env private property
Process::$executables private static property
Process::$exitcode private property
Process::$exitCodes public static property Exit codes translation table.
Process::$fallbackStatus private property
Process::$idleTimeout private property
Process::$ignoredSignals private property
Process::$incrementalErrorOutputOffset private property
Process::$incrementalOutputOffset private property
Process::$input private property @var resource|string|\Iterator|null
Process::$lastOutputTime private property
Process::$latestSignal private property
Process::$options private property
Process::$outputDisabled private property
Process::$process private property @var resource|null
Process::$processInformation private property
Process::$processPipes private property
Process::$pty private property
Process::$sigchild private static property
Process::$starttime private property
Process::$status private property
Process::$stderr private property @var resource
Process::$stdout private property @var resource
Process::$timeout private property
Process::$tty private property
Process::addErrorOutput public function Adds a line to the STDERR stream.
Process::addOutput public function Adds a line to the STDOUT stream.
Process::buildCallback protected function Builds up the callback used by wait().
Process::buildShellCommandline private function
Process::checkTimeout public function Performs a check between the timeout definition and the time the process started.
Process::clearErrorOutput public function Clears the process output.
Process::clearOutput public function Clears the process output.
Process::close private function Closes process resource, closes file handles, sets the exitcode.
Process::disableOutput public function Disables fetching output and error output from the underlying process.
Process::doSignal private function Sends a POSIX signal to the process.
Process::enableOutput public function Enables fetching output and error output from the underlying process.
Process::ERR public constant
Process::escapeArgument private function Escapes a string to be used as a shell argument.
Process::getCommandLine public function Gets the command line to be executed.
Process::getDefaultEnv private function
Process::getDescriptors private function Creates the descriptors needed by the proc_open.
Process::getEnv public function Gets the environment variables.
Process::getErrorOutput public function Returns the current error output of the process (STDERR).
Process::getExitCode public function Returns the exit code returned by the process.
Process::getExitCodeText public function Returns a string representation for the exit code returned by the process.
Process::getIdleTimeout public function Gets the process idle timeout in seconds (max. time since last output).
Process::getIncrementalErrorOutput public function Returns the errorOutput incrementally.
Process::getIncrementalOutput public function Returns the output incrementally.
Process::getInput public function Gets the Process input.
Process::getIterator public function Returns an iterator to the output of the process, with the output type as keys (Process::OUT/ERR).
Process::getLastOutputTime public function Gets the last output time in seconds.
Process::getOutput public function Returns the current output of the process (STDOUT).
Process::getPid public function Returns the Pid (process identifier), if applicable.
Process::getStartTime public function
Process::getStatus public function Gets the process status.
Process::getStopSignal public function Returns the number of the signal that caused the child process to stop its execution.
Process::getTermSignal public function Returns the number of the signal that caused the child process to terminate its execution.
Process::getTimeout public function Gets the process timeout in seconds (max. runtime).
Process::getWorkingDirectory public function Gets the working directory.
Process::hasBeenSignaled public function Returns true if the child process has been terminated by an uncaught signal.
Process::hasBeenStopped public function Returns true if the child process has been stopped by a signal.
Process::isOutputDisabled public function Returns true in case the output is disabled, false otherwise.
Process::isPty public function Returns PTY state.
Process::isPtySupported public static function Returns whether PTY is supported on the current operating system.
Process::isRunning public function Checks if the process is currently running.
Process::isSigchildEnabled protected function Returns whether PHP has been compiled with the &#039;--enable-sigchild&#039; option or not.
Process::isStarted public function Checks if the process has been started with no regard to the current state.
Process::isSuccessful public function Checks if the process ended successfully.
Process::isTerminated public function Checks if the process is terminated.
Process::isTty public function Checks if the TTY mode is enabled.
Process::isTtySupported public static function Returns whether TTY is supported on the current operating system.
Process::ITER_KEEP_OUTPUT public constant
Process::ITER_NON_BLOCKING public constant
Process::ITER_SKIP_ERR public constant
Process::ITER_SKIP_OUT public constant
Process::mustRun public function Runs the process.
Process::OUT public constant
Process::prepareWindowsCommandLine private function
Process::readPipes private function Reads pipes, executes callback.
Process::readPipesForOutput private function Reads pipes for the freshest output.
Process::replacePlaceholders private function
Process::requireProcessIsStarted private function Ensures the process is running or terminated, throws a LogicException if the process has a not started.
Process::requireProcessIsTerminated private function Ensures the process is terminated, throws a LogicException if the process has a status different than &quot;terminated&quot;.
Process::resetProcessData private function Resets data related to the latest run of the process.
Process::restart public function Restarts the process.
Process::run public function Runs the process.
Process::setEnv public function Sets the environment variables.
Process::setIdleTimeout public function Sets the process idle timeout (max. time since last output) in seconds.
Process::setIgnoredSignals public function Defines a list of posix signals that will not be propagated to the process.
Process::setInput public function Sets the input.
Process::setOptions public function Defines options to pass to the underlying proc_open().
Process::setPty public function Sets PTY mode.
Process::setTimeout public function Sets the process timeout (max. runtime) in seconds.
Process::setTty public function Enables or disables the TTY mode.
Process::setWorkingDirectory public function Sets the current working directory.
Process::signal public function Sends a POSIX signal to the process.
Process::STATUS_READY public constant
Process::STATUS_STARTED public constant
Process::STATUS_TERMINATED public constant
Process::STDERR public constant
Process::STDIN public constant
Process::STDOUT public constant
Process::stop public function Stops the process.
Process::TIMEOUT_PRECISION public constant
Process::updateStatus protected function Updates the status of the process, reads pipes.
Process::validateTimeout private function Validates and returns the filtered timeout.
Process::wait public function Waits for the process to terminate.
Process::waitUntil public function Waits until the callback returns true.
Process::__clone public function
Process::__destruct public function
Process::__sleep public function
Process::__wakeup public function

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal