🕷️ Crawler Inspector

URL Lookup

Direct Parameter Lookup

Raw Queries and Responses

1. Shard Calculation

Query:
Response:
Calculated Shard: 148 (from laksa087)

2. Crawled Status Check

Query:
Response:

3. Robots.txt Check

Query:
Response:

4. Spam/Ban Check

Query:
Response:

5. Seen Status Check

ℹ️ Skipped - page is already crawled

📄
INDEXABLE
CRAWLED
9 hours ago
🤖
ROBOTS ALLOWED

Page Info Filters

FilterStatusConditionDetails
HTTP statusPASSdownload_http_code = 200HTTP 200
Age cutoffPASSdownload_stamp > now() - 6 MONTH0 months ago
History dropPASSisNull(history_drop_reason)No drop reason
Spam/banPASSfh_dont_index != 1 AND ml_spam_score = 0ml_spam_score=0
CanonicalPASSmeta_canonical IS NULL OR = '' OR = src_unparsedNot set

Page Details

PropertyValue
URLhttps://symfony.com/doc/current/components/process.html
Last Crawled2026-04-06 16:01:42 (9 hours ago)
First Indexed2015-06-16 03:38:45 (10 years ago)
HTTP Status Code200
Meta TitleThe Process Component (Symfony Docs)
Meta DescriptionThe Process component executes commands in sub-processes. Installation 1 $ composer require symfony/process Note If you…
Meta Canonicalnull
Boilerpipe Text
The Process component executes commands in sub-processes. Installation Note If you install this component outside of a Symfony application, you must require the vendor/autoload.php file in your code to enable the class autoloading mechanism provided by Composer. Read this article for more details. Usage The Process class executes a command in a sub-process, taking care of the differences between operating system and escaping arguments to prevent security issues. It replaces PHP functions like exec , passthru , shell_exec and system : The getOutput() method always returns the whole content of the standard output of the command and getErrorOutput() the content of the error output. Alternatively, the getIncrementalOutput() and getIncrementalErrorOutput() methods return the new output since the last call. The clearOutput() method clears the contents of the output and clearErrorOutput() clears the contents of the error output. You can also use the Process class with the for each construct to get the output while it is generated. By default, the loop waits for new output before going to the next iteration: Tip The Process component internally uses a PHP iterator to get the output while it is generated. That iterator is exposed via the getIterator() method to allow customizing its behavior: The mustRun() method is identical to run() , except that it will throw a ProcessFailedException if the process couldn't be executed successfully (i.e. the process exited with a non-zero code): Tip You can get the last output time in seconds by using the getLastOutputTime() method. This method returns null if the process wasn't started! Configuring Process Options Symfony uses the PHP proc_open function to run the processes. You can configure the options passed to the other_options argument of proc_open() using the setOptions() method: Warning Most of the options defined by proc_open() (such as create_new_console and suppress_errors ) are only supported on Windows operating systems. Check out the PHP documentation for proc_open() before using them. Using Features From the OS Shell Using an array of arguments is the recommended way to define commands. This saves you from any escaping and allows sending signals seamlessly (e.g. to stop processes while they run): If you need to use stream redirections, conditional execution, or any other feature provided by the shell of your operating system, you can also define commands as strings using the fromShellCommandline() static factory. Each operating system provides a different syntax for their command-lines, so it becomes your responsibility to deal with escaping and portability. When using strings to define commands, variable arguments are passed as environment variables using the second argument of the run() , mustRun() or start() methods. Referencing them is also OS-dependent: If you prefer to create portable commands that are independent from the operating system, you can write the above command as follows: Portable commands require using a syntax that is specific to the component: when enclosing a variable name into "${: and }" exactly, the process object will replace it with its escaped value, or will fail if the variable is not found in the list of environment variables attached to the command. Setting Environment Variables for Processes The constructor of the Process class and all of its methods related to executing processes ( run() , mustRun() , start() , etc.) allow passing an array of environment variables to set while running the process: In addition to the env vars passed explicitly, processes inherit all the env vars defined in your system. You can prevent this by setting the env vars you want to remove to false : Getting real-time Process Output When executing a long running command (like rsync to a remote server), you can give feedback to the end user in real-time by passing an anonymous function to the run() method: Note This feature won't work as expected in servers using PHP output buffering. In those cases, either disable the output_buffering PHP option or use the ob_flush PHP function to force sending the output buffer. Running Processes Asynchronously You can also start the subprocess and then let it run asynchronously, retrieving output and the status in your main process whenever you need it. Use the start() method to start an asynchronous process, the isRunning() method to check if the process is done and the getOutput() method to get the output: You can also wait for a process to end if you started it asynchronously and are done doing other stuff: Note The wait() method is blocking, which means that your code will halt at this line until the external process is completed. Note If a Response is sent before a child process had a chance to complete, the server process will be killed (depending on your OS). It means that your task will be stopped right away. Running an asynchronous process is not the same as running a process that survives its parent process. If you want your process to survive the request/response cycle, you can take advantage of the kernel.terminate event, and run your command synchronously inside this event. Be aware that kernel.terminate is called only if you use PHP-FPM. Danger Beware also that if you do that, the said PHP-FPM process will not be available to serve any new request until the subprocess is finished. This means you can quickly block your FPM pool if you're not careful enough. That is why it's generally way better not to do any fancy things even after the request is sent, but to use a job queue instead. wait() takes one optional argument: a callback that is called repeatedly while the process is still running, passing in the output and its type: Instead of waiting until the process has finished, you can use the waitUntil() method to keep or stop waiting based on some PHP logic. The following example starts a long running process and checks its output to wait until its fully initialized: Streaming to the Standard Input of a Process Before a process is started, you can specify its standard input using either the setInput() method or the 4th argument of the constructor. The provided input can be a string, a stream resource or a Traversable object: When this input is fully written to the subprocess standard input, the corresponding pipe is closed. In order to write to a subprocess standard input while it is running, the component provides the InputStream class: The write() method accepts scalars, stream resources or Traversable objects as arguments. As shown in the above example, you need to explicitly call the close() method when you are done writing to the standard input of the subprocess. Using TTY and PTY Modes All examples above show that your program has control over the input of a process (using setInput() ) and the output from that process (using getOutput() ). The Process component has two special modes that tweak the relationship between your program and the process: teletype (tty) and pseudo-teletype (pty). In TTY mode, you connect the input and output of the process to the input and output of your program. This allows for instance to open an editor like Vim or Nano as a process. You enable TTY mode by calling setTty() : In PTY mode, your program behaves as a terminal for the process instead of a plain input and output. Some programs behave differently when interacting with a real terminal instead of another program. For instance, some programs prompt for a password when talking with a terminal. Use setPty() to enable this mode. Stopping a Process Any asynchronous process can be stopped at any time with the stop() method. This method takes two arguments: a timeout and a signal. Once the timeout is reached, the signal is sent to the running process. The default signal sent to a process is SIGKILL . Please read the signal documentation below to find out more about signal handling in the Process component: Executing PHP Code in Isolation If you want to execute some PHP code in isolation, use the PhpProcess instead: Executing a PHP Child Process with the Same Configuration When you start a PHP process, it uses the default configuration defined in your php.ini file. You can bypass these options with the -d command line option. For example, if memory_limit is set to 256M , you can disable this memory limit when running some command like this: php -d memory_limit=-1 bin/console app:my-command . However, if you run the command via the Symfony Process class, PHP will use the settings defined in the php.ini file. You can solve this issue by using the PhpSubprocess class to run the command: Process Timeout By default processes have a timeout of 60 seconds, but you can change it passing a different timeout (in seconds) to the setTimeout() method: If the timeout is reached, a ProcessTimedOutException is thrown. For long running commands, it is your responsibility to perform the timeout check regularly: Tip You can get the process start time using the getStartTime() method. Process Idle Timeout In contrast to the timeout of the previous paragraph, the idle timeout only considers the time since the last output was produced by the process: In the case above, a process is considered timed out, when either the total runtime exceeds 3600 seconds, or the process does not produce any output for 60 seconds. Process Signals When running a program asynchronously, you can send it POSIX signals with the signal() method: You can make the process ignore signals by using the setIgnoredSignals() method. The given signals won't be propagated to the child process: Process Pid You can access the pid of a running process with the getPid() method: Disabling Output As standard output and error output are always fetched from the underlying process, it might be convenient to disable output in some cases to save memory. Use disableOutput() and enableOutput() to toggle this feature: Warning You cannot enable or disable the output while the process is running. If you disable the output, you cannot access getOutput() , getIncrementalOutput() , getErrorOutput() , getIncrementalErrorOutput() or setIdleTimeout() . However, it is possible to pass a callback to the start , run or mustRun methods to handle process output in a streaming fashion. Finding an Executable The Process component provides a utility class called ExecutableFinder which finds and returns the absolute path of an executable: The find() method also takes extra parameters to specify a default value to return and extra directories where to look for the executable: Finding the Executable PHP Binary This component also provides a special utility class called PhpExecutableFinder which returns the absolute path of the executable PHP binary available on your server: Checking for TTY Support Another utility provided by this component is a method called isTtySupported() which returns whether TTY is supported on the current operating system: This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
Markdown
[Skip to content](https://symfony.com/doc/current/components/process.html#main-content) [SymfonyHub](https://symfony.com/doc/current/components/process.html "Toggle Symfony menu") [SFH](https://symfony.com/doc/current/components/process.html "Toggle Symfony menu") [![](https://connect.symfony.com/uploads/sln/1c5498dd-0649-4d42-af4b-1de957825f62/8a08e0e0-cc2d-490f-9a2f-882979624a7f.png) Blackfire.io](https://www.blackfire.io/?utm_source=symfony&utm_medium=banner&utm_campaign=profiler) [![](https://connect.symfony.com/uploads/sln/1c5498dd-0649-4d42-af4b-1de957825f62/8a08e0e0-cc2d-490f-9a2f-882979624a7f.png) Blackfire.io: Fire up your PHP apps performance](https://www.blackfire.io/?utm_source=symfony&utm_medium=banner&utm_campaign=profiler) [![](https://connect.symfony.com/uploads/sln/1c5498dd-0649-4d42-af4b-1de957825f62/8a08e0e0-cc2d-490f-9a2f-882979624a7f.png) Blackfire.io: Fire up your PHP apps performance](https://www.blackfire.io/?utm_source=symfony&utm_medium=banner&utm_campaign=profiler) [Connect](https://symfony.com/connect/login?target=https://symfony.com/doc/current/components/process.html) ![SensioLabs](https://connect.symfony.com/assets/images/sln-v2/sensiolabs-9Agct9D.png) SensioLabs is the creator of Symfony and plays a pivotal role in supporting its growth. With a passionate team pushing the boundaries of PHP, SensioLabs helps organizations get the most out of Symfony through quality, high-performance, software vendor-level training and consulting services. - [International](https://sensiolabs.com/en) - [France](https://sensiolabs.com/fr) ## In the Spotlight [![SymfonyInsight](https://connect.symfony.com/assets/images/sln-v2/symfonyinsight-HwpmiQ3.png)](https://insight.symfony.com/) [![Blackfire](https://connect.symfony.com/assets/images/sln-v2/blackfire-ca6NfRp.png)](https://www.blackfire.io/?utm_source=symfony&utm_medium=banner&utm_campaign=profiler) ## Open Source - [Symfony - Web framework](https://symfony.com/) - [Twig - Templating](https://twig.symfony.com/) - [PHP Polyfills](https://github.com/symfony/polyfill) ## Products - [Insight: PHP Quality](https://insight.symfony.com/) - [Blackfire: Web App performance](https://www.blackfire.io/?utm_source=symfony&utm_medium=banner&utm_campaign=profiler) - [SymfonyCloud powered by Upsun](https://symfony.com/cloud) ## Solutions & Services - [Training](https://training.sensiolabs.com/) - [Certification](https://certification.symfony.com/) - [Technical Solutions](https://sensiolabs.com/solutions) - [SensioLabs University](https://university.sensiolabs.com/) - [Experts](https://expert.sensiolabs.com/) ## Community - [Community](https://connect.symfony.com/) - [Conferences](https://live.symfony.com/) - [Videos](https://www.youtube.com/symfonytv) - [Partners](https://network.sensiolabs.com/en/partenaires) ## Blogs [Symfony](https://symfony.com/blog/), [SensioLabs](https://blog.sensiolabs.com/), [Insight](https://blog.insight.symfony.com/), and [Blackfire](https://blog.blackfire.io/?utm_source=symfony&utm_medium=banner&utm_campaign=profiler). Close - About - [What is Symfony?](https://symfony.com/what-is-symfony) - [Community](https://symfony.com/community) - [News](https://symfony.com/blog/) - [Contributing](https://symfony.com/doc/current/contributing/index.html) - [Support](https://symfony.com/support) - Documentation - [Symfony Docs](https://symfony.com/doc) - [Symfony Book](https://symfony.com/book) - [Screencasts](https://symfonycasts.com/) - [Symfony Bundles](https://symfony.com/bundles) - [Symfony Cloud](https://symfony.com/doc/cloud/) - [Training](https://sensiolabs.com/training?utm_source=symfony&utm_medium=symfony_submenu&utm_campaign=permanent_referral) - Services - [Upsun for Symfony](https://symfony.com/cloud/) Best platform to deploy Symfony apps - [SymfonyInsight](https://insight.symfony.com/) Automatic quality checks for your apps - [Symfony Certification](https://certification.symfony.com/) Prove your knowledge and boost your career - [SensioLabs](https://sensiolabs.com/?utm_source=symfony&utm_medium=symfony_submenu&utm_campaign=permanent_referral) Professional services to help you with Symfony - [Blackfire](https://www.blackfire.io/?utm_source=symfony&utm_medium=symfonycom_footer&utm_campaign=profiler) Profile and monitor performance of your apps - Other - [Blog](https://symfony.com/blog/) - [Download](https://symfony.com/download) sponsored by [SymfonyDay Montreal 2026](https://live.symfony.com/2026-montreal) June 4, 2026 \+20 talks and workshops Register now 1. [Home](https://symfony.com/) 2. [Documentation](https://symfony.com/doc) 3. [Components](https://symfony.com/doc/current/components/index.html) 4. The Process Component Search Symfony Docs Version: Table of Contents - [Installation](https://symfony.com/doc/current/components/process.html#installation) - [Usage](https://symfony.com/doc/current/components/process.html#usage) - [Configuring Process Options](https://symfony.com/doc/current/components/process.html#configuring-process-options) - [Using Features From the OS Shell](https://symfony.com/doc/current/components/process.html#using-features-from-the-os-shell) - [Setting Environment Variables for Processes](https://symfony.com/doc/current/components/process.html#setting-environment-variables-for-processes) - [Getting real-time Process Output](https://symfony.com/doc/current/components/process.html#getting-real-time-process-output) - [Running Processes Asynchronously](https://symfony.com/doc/current/components/process.html#running-processes-asynchronously) - [Streaming to the Standard Input of a Process](https://symfony.com/doc/current/components/process.html#streaming-to-the-standard-input-of-a-process) - [Using PHP Streams as the Standard Input of a Process](https://symfony.com/doc/current/components/process.html#using-php-streams-as-the-standard-input-of-a-process) - [Using TTY and PTY Modes](https://symfony.com/doc/current/components/process.html#using-tty-and-pty-modes) - [Stopping a Process](https://symfony.com/doc/current/components/process.html#stopping-a-process) - [Executing PHP Code in Isolation](https://symfony.com/doc/current/components/process.html#executing-php-code-in-isolation) - [Executing a PHP Child Process with the Same Configuration](https://symfony.com/doc/current/components/process.html#executing-a-php-child-process-with-the-same-configuration) - [Process Timeout](https://symfony.com/doc/current/components/process.html#process-timeout) - [Process Idle Timeout](https://symfony.com/doc/current/components/process.html#process-idle-timeout) - [Process Signals](https://symfony.com/doc/current/components/process.html#process-signals) - [Process Pid](https://symfony.com/doc/current/components/process.html#process-pid) - [Disabling Output](https://symfony.com/doc/current/components/process.html#disabling-output) - [Finding an Executable](https://symfony.com/doc/current/components/process.html#finding-an-executable) - [Finding the Executable PHP Binary](https://symfony.com/doc/current/components/process.html#finding-the-executable-php-binary) - [Checking for TTY Support](https://symfony.com/doc/current/components/process.html#checking-for-tty-support) # The Process Component [Edit this page](https://github.com/symfony/symfony-docs/edit/8.0/components/process.rst) > The Process component executes commands in sub-processes. ## [Installation](https://symfony.com/doc/current/components/process.html#installation "Permalink to this headline") Copy ``` 1 ``` ``` $ composer require symfony/process ``` Note If you install this component outside of a Symfony application, you must require the `vendor/autoload.php` file in your code to enable the class autoloading mechanism provided by Composer. Read [this article](https://symfony.com/doc/current/components/using_components.html) for more details. ## [Usage](https://symfony.com/doc/current/components/process.html#usage "Permalink to this headline") The [Process](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php "Symfony\Component\Process\Process") class executes a command in a sub-process, taking care of the differences between operating system and escaping arguments to prevent security issues. It replaces PHP functions like [exec](https://secure.php.net/manual/en/function.exec.php "exec"), [passthru](https://secure.php.net/manual/en/function.passthru.php "passthru"), [shell\_exec](https://secure.php.net/manual/en/function.shell-exec.php "shell_exec") and [system](https://secure.php.net/manual/en/function.system.php "system"): ``` 1 2 3 4 5 6 7 8 9 10 11 12 ``` ``` use Symfony\Component\Process\Exception\ProcessFailedException; use Symfony\Component\Process\Process; $process = new Process(['ls', '-lsa']); $process->run(); // executes after the command finishes if (!$process->isSuccessful()) { throw new ProcessFailedException($process); } echo $process->getOutput(); ``` The `getOutput()` method always returns the whole content of the standard output of the command and `getErrorOutput()` the content of the error output. Alternatively, the [getIncrementalOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getIncrementalOutput "Symfony\Component\Process\Process::getIncrementalOutput()") and [getIncrementalErrorOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getIncrementalErrorOutput "Symfony\Component\Process\Process::getIncrementalErrorOutput()") methods return the new output since the last call. The [clearOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20clearOutput "Symfony\Component\Process\Process::clearOutput()") method clears the contents of the output and [clearErrorOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20clearErrorOutput "Symfony\Component\Process\Process::clearErrorOutput()") clears the contents of the error output. You can also use the [Process](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php "Symfony\Component\Process\Process") class with the for each construct to get the output while it is generated. By default, the loop waits for new output before going to the next iteration: ``` 1 2 3 4 5 6 7 8 9 10 ``` ``` $process = new Process(['ls', '-lsa']); $process->start(); foreach ($process as $type => $data) { if ($process::OUT === $type) { echo "\nRead from stdout: ".$data; } else { // $process::ERR === $type echo "\nRead from stderr: ".$data; } } ``` Tip The Process component internally uses a PHP iterator to get the output while it is generated. That iterator is exposed via the `getIterator()` method to allow customizing its behavior: ``` 1 2 3 4 5 6 ``` ``` $process = new Process(['ls', '-lsa']); $process->start(); $iterator = $process->getIterator($process::ITER_SKIP_ERR | $process::ITER_KEEP_OUTPUT); foreach ($iterator as $data) { echo $data."\n"; } ``` The `mustRun()` method is identical to `run()`, except that it will throw a [ProcessFailedException](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Exception/ProcessFailedException.php "Symfony\Component\Process\Exception\ProcessFailedException") if the process couldn't be executed successfully (i.e. the process exited with a non-zero code): ``` 1 2 3 4 5 6 7 8 9 10 11 12 ``` ``` use Symfony\Component\Process\Exception\ProcessFailedException; use Symfony\Component\Process\Process; $process = new Process(['ls', '-lsa']); try { $process->mustRun(); echo $process->getOutput(); } catch (ProcessFailedException $exception) { echo $exception->getMessage(); } ``` Tip You can get the last output time in seconds by using the [getLastOutputTime()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getLastOutputTime "Symfony\Component\Process\Process::getLastOutputTime()") method. This method returns `null` if the process wasn't started\! ## [Configuring Process Options](https://symfony.com/doc/current/components/process.html#configuring-process-options "Permalink to this headline") Symfony uses the PHP [proc\_open](https://secure.php.net/manual/en/function.proc-open.php "proc_open") function to run the processes. You can configure the options passed to the `other_options` argument of `proc_open()` using the `setOptions()` method: ``` 1 2 3 ``` ``` $process = new Process(['...', '...', '...']); // this option allows a subprocess to continue running after the main script exited $process->setOptions(['create_new_console' => true]); ``` Warning Most of the options defined by `proc_open()` (such as `create_new_console` and `suppress_errors`) are only supported on Windows operating systems. Check out the [PHP documentation for proc\_open()](https://www.php.net/manual/en/function.proc-open.php) before using them. ## [Using Features From the OS Shell](https://symfony.com/doc/current/components/process.html#using-features-from-the-os-shell "Permalink to this headline") Using an array of arguments is the recommended way to define commands. This saves you from any escaping and allows sending signals seamlessly (e.g. to stop processes while they run): ``` 1 2 ``` ``` $process = new Process(['/path/command', '--option', 'argument', 'etc.']); $process = new Process(['/path/to/php', '--define', 'memory_limit=1024M', '/path/to/script.php']); ``` If you need to use stream redirections, conditional execution, or any other feature provided by the shell of your operating system, you can also define commands as strings using the [fromShellCommandline()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20fromShellCommandline "Symfony\Component\Process\Process::fromShellCommandline()") static factory. Each operating system provides a different syntax for their command-lines, so it becomes your responsibility to deal with escaping and portability. When using strings to define commands, variable arguments are passed as environment variables using the second argument of the `run()`, `mustRun()` or `start()` methods. Referencing them is also OS-dependent: ``` 1 2 3 4 5 6 7 8 ``` ``` // On Unix-like OSes (Linux, macOS) $process = Process::fromShellCommandline('echo "$MESSAGE"'); // On Windows $process = Process::fromShellCommandline('echo "!MESSAGE!"'); // On both Unix-like and Windows $process->run(null, ['MESSAGE' => 'Something to output']); ``` If you prefer to create portable commands that are independent from the operating system, you can write the above command as follows: ``` 1 2 ``` ``` // works the same on Windows , Linux and macOS $process = Process::fromShellCommandline('echo "${:MESSAGE}"'); ``` Portable commands require using a syntax that is specific to the component: when enclosing a variable name into `"${:` and `}"` exactly, the process object will replace it with its escaped value, or will fail if the variable is not found in the list of environment variables attached to the command. ## [Setting Environment Variables for Processes](https://symfony.com/doc/current/components/process.html#setting-environment-variables-for-processes "Permalink to this headline") The constructor of the [Process](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php "Symfony\Component\Process\Process") class and all of its methods related to executing processes (`run()`, `mustRun()`, `start()`, etc.) allow passing an array of environment variables to set while running the process: ``` 1 2 3 ``` ``` $process = new Process(['...'], null, ['ENV_VAR_NAME' => 'value']); $process = Process::fromShellCommandline('...', null, ['ENV_VAR_NAME' => 'value']); $process->run(null, ['ENV_VAR_NAME' => 'value']); ``` In addition to the env vars passed explicitly, processes inherit all the env vars defined in your system. You can prevent this by setting the env vars you want to remove to `false`: ``` 1 2 3 4 ``` ``` $process = new Process(['...'], null, [ 'APP_ENV' => false, 'SYMFONY_DOTENV_VARS' => false, ]); ``` ## [Getting real-time Process Output](https://symfony.com/doc/current/components/process.html#getting-real-time-process-output "Permalink to this headline") When executing a long running command (like `rsync` to a remote server), you can give feedback to the end user in real-time by passing an anonymous function to the [run()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20run "Symfony\Component\Process\Process::run()") method: ``` 1 2 3 4 5 6 7 8 9 10 ``` ``` use Symfony\Component\Process\Process; $process = new Process(['ls', '-lsa']); $process->run(function ($type, $buffer): void { if (Process::ERR === $type) { echo 'ERR > '.$buffer; } else { echo 'OUT > '.$buffer; } }); ``` Note This feature won't work as expected in servers using PHP output buffering. In those cases, either disable the [output\_buffering](https://www.php.net/manual/en/outcontrol.configuration.php) PHP option or use the [ob\_flush](https://secure.php.net/manual/en/function.ob-flush.php "ob_flush") PHP function to force sending the output buffer. ## [Running Processes Asynchronously](https://symfony.com/doc/current/components/process.html#running-processes-asynchronously "Permalink to this headline") You can also start the subprocess and then let it run asynchronously, retrieving output and the status in your main process whenever you need it. Use the [start()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20start "Symfony\Component\Process\Process::start()") method to start an asynchronous process, the [isRunning()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20isRunning "Symfony\Component\Process\Process::isRunning()") method to check if the process is done and the [getOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getOutput "Symfony\Component\Process\Process::getOutput()") method to get the output: ``` 1 2 3 4 5 6 7 8 ``` ``` $process = new Process(['ls', '-lsa']); $process->start(); while ($process->isRunning()) { // waiting for process to finish } echo $process->getOutput(); ``` You can also wait for a process to end if you started it asynchronously and are done doing other stuff: ``` 1 2 3 4 5 6 7 8 ``` ``` $process = new Process(['ls', '-lsa']); $process->start(); // ... do other things $process->wait(); // ... do things after the process has finished ``` Note The [wait()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20wait "Symfony\Component\Process\Process::wait()") method is blocking, which means that your code will halt at this line until the external process is completed. Note If a `Response` is sent **before** a child process had a chance to complete, the server process will be killed (depending on your OS). It means that your task will be stopped right away. Running an asynchronous process is not the same as running a process that survives its parent process. If you want your process to survive the request/response cycle, you can take advantage of the `kernel.terminate` event, and run your command **synchronously** inside this event. Be aware that `kernel.terminate` is called only if you use PHP-FPM. Danger Beware also that if you do that, the said PHP-FPM process will not be available to serve any new request until the subprocess is finished. This means you can quickly block your FPM pool if you're not careful enough. That is why it's generally way better not to do any fancy things even after the request is sent, but to use a job queue instead. [wait()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20wait "Symfony\Component\Process\Process::wait()") takes one optional argument: a callback that is called repeatedly while the process is still running, passing in the output and its type: ``` 1 2 3 4 5 6 7 8 9 10 ``` ``` $process = new Process(['ls', '-lsa']); $process->start(); $process->wait(function ($type, $buffer): void { if (Process::ERR === $type) { echo 'ERR > '.$buffer; } else { echo 'OUT > '.$buffer; } }); ``` Instead of waiting until the process has finished, you can use the [waitUntil()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20waitUntil "Symfony\Component\Process\Process::waitUntil()") method to keep or stop waiting based on some PHP logic. The following example starts a long running process and checks its output to wait until its fully initialized: ``` 1 2 3 4 5 6 7 8 9 10 11 ``` ``` $process = new Process(['/usr/bin/php', 'slow-starting-server.php']); $process->start(); // ... do other things // waits until the given anonymous function returns true $process->waitUntil(function ($type, $output): bool { return $output === 'Ready. Waiting for commands...'; }); // ... do things after the process is ready ``` ## [Streaming to the Standard Input of a Process](https://symfony.com/doc/current/components/process.html#streaming-to-the-standard-input-of-a-process "Permalink to this headline") Before a process is started, you can specify its standard input using either the [setInput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20setInput "Symfony\Component\Process\Process::setInput()") method or the 4th argument of the constructor. The provided input can be a string, a stream resource or a `Traversable` object: ``` 1 2 3 ``` ``` $process = new Process(['cat']); $process->setInput('foobar'); $process->run(); ``` When this input is fully written to the subprocess standard input, the corresponding pipe is closed. In order to write to a subprocess standard input while it is running, the component provides the [InputStream](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/InputStream.php "Symfony\Component\Process\InputStream") class: ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ``` ``` $input = new InputStream(); $input->write('foo'); $process = new Process(['cat']); $process->setInput($input); $process->start(); // ... read process output or do other things $input->write('bar'); $input->close(); $process->wait(); // will echo: foobar echo $process->getOutput(); ``` The [write()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/InputStream.php#:~:text=function%20write "Symfony\Component\Process\InputStream::write()") method accepts scalars, stream resources or `Traversable` objects as arguments. As shown in the above example, you need to explicitly call the [close()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/InputStream.php#:~:text=function%20close "Symfony\Component\Process\InputStream::close()") method when you are done writing to the standard input of the subprocess. ### [Using PHP Streams as the Standard Input of a Process](https://symfony.com/doc/current/components/process.html#using-php-streams-as-the-standard-input-of-a-process "Permalink to this headline") The input of a process can also be defined using [PHP streams](https://www.php.net/manual/en/book.stream.php): ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ``` ``` $stream = fopen('php://temporary', 'w+'); $process = new Process(['cat']); $process->setInput($stream); $process->start(); fwrite($stream, 'foo'); // ... read process output or do other things fwrite($stream, 'bar'); fclose($stream); $process->wait(); // will echo: 'foobar' echo $process->getOutput(); ``` ## [Using TTY and PTY Modes](https://symfony.com/doc/current/components/process.html#using-tty-and-pty-modes "Permalink to this headline") All examples above show that your program has control over the input of a process (using `setInput()`) and the output from that process (using `getOutput()`). The Process component has two special modes that tweak the relationship between your program and the process: teletype (tty) and pseudo-teletype (pty). In TTY mode, you connect the input and output of the process to the input and output of your program. This allows for instance to open an editor like Vim or Nano as a process. You enable TTY mode by calling [setTty()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20setTty "Symfony\Component\Process\Process::setTty()"): ``` 1 2 3 4 5 6 7 ``` ``` $process = new Process(['vim']); $process->setTty(true); $process->run(); // As the output is connected to the terminal, it is no longer possible // to read or modify the output from the process! dump($process->getOutput()); // null ``` In PTY mode, your program behaves as a terminal for the process instead of a plain input and output. Some programs behave differently when interacting with a real terminal instead of another program. For instance, some programs prompt for a password when talking with a terminal. Use [setPty()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20setPty "Symfony\Component\Process\Process::setPty()") to enable this mode. ## [Stopping a Process](https://symfony.com/doc/current/components/process.html#stopping-a-process "Permalink to this headline") Any asynchronous process can be stopped at any time with the [stop()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20stop "Symfony\Component\Process\Process::stop()") method. This method takes two arguments: a timeout and a signal. Once the timeout is reached, the signal is sent to the running process. The default signal sent to a process is `SIGKILL`. Please read the [signal documentation below](https://symfony.com/doc/current/components/process.html#reference-process-signal) to find out more about signal handling in the Process component: ``` 1 2 3 4 5 6 ``` ``` $process = new Process(['ls', '-lsa']); $process->start(); // ... do other things $process->stop(3, SIGINT); ``` ## [Executing PHP Code in Isolation](https://symfony.com/doc/current/components/process.html#executing-php-code-in-isolation "Permalink to this headline") If you want to execute some PHP code in isolation, use the `PhpProcess` instead: ``` 1 2 3 4 5 6 7 ``` ``` use Symfony\Component\Process\PhpProcess; $process = new PhpProcess(<<<EOF <?= 'Hello World' ?> EOF ); $process->run(); ``` ## [Executing a PHP Child Process with the Same Configuration](https://symfony.com/doc/current/components/process.html#executing-a-php-child-process-with-the-same-configuration "Permalink to this headline") When you start a PHP process, it uses the default configuration defined in your `php.ini` file. You can bypass these options with the `-d` command line option. For example, if `memory_limit` is set to `256M`, you can disable this memory limit when running some command like this: `php -d memory_limit=-1 bin/console app:my-command`. However, if you run the command via the Symfony `Process` class, PHP will use the settings defined in the `php.ini` file. You can solve this issue by using the [PhpSubprocess](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/PhpSubprocess.php "Symfony\Component\Process\PhpSubprocess") class to run the command: ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ``` ``` use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Process\Process; #[AsCommand(name: 'app:my-command')] class MyCommand { public function __invoke(SymfonyStyle $io): int { // the memory_limit (and any other config option) of this command is // the one defined in php.ini instead of the new values (optionally) // passed via the '-d' command option $childProcess = new Process(['bin/console', 'cache:pool:prune']); // the memory_limit (and any other config option) of this command takes // into account the values (optionally) passed via the '-d' command option $childProcess = new PhpSubprocess(['bin/console', 'cache:pool:prune']); return 0; } } ``` ## [Process Timeout](https://symfony.com/doc/current/components/process.html#process-timeout "Permalink to this headline") By default processes have a timeout of 60 seconds, but you can change it passing a different timeout (in seconds) to the `setTimeout()` method: ``` 1 2 3 4 5 ``` ``` use Symfony\Component\Process\Process; $process = new Process(['ls', '-lsa']); $process->setTimeout(3600); $process->run(); ``` If the timeout is reached, a [ProcessTimedOutException](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Exception/ProcessTimedOutException.php "Symfony\Component\Process\Exception\ProcessTimedOutException") is thrown. For long running commands, it is your responsibility to perform the timeout check regularly: ``` 1 2 3 4 5 6 7 8 9 10 11 ``` ``` $process->setTimeout(3600); $process->start(); while ($condition) { // ... // check if the timeout is reached $process->checkTimeout(); usleep(200000); } ``` Tip You can get the process start time using the `getStartTime()` method. ## [Process Idle Timeout](https://symfony.com/doc/current/components/process.html#process-idle-timeout "Permalink to this headline") In contrast to the timeout of the previous paragraph, the idle timeout only considers the time since the last output was produced by the process: ``` 1 2 3 4 5 6 ``` ``` use Symfony\Component\Process\Process; $process = new Process(['something-with-variable-runtime']); $process->setTimeout(3600); $process->setIdleTimeout(60); $process->run(); ``` In the case above, a process is considered timed out, when either the total runtime exceeds 3600 seconds, or the process does not produce any output for 60 seconds. ## [Process Signals](https://symfony.com/doc/current/components/process.html#process-signals "Permalink to this headline") When running a program asynchronously, you can send it POSIX signals with the [signal()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20signal "Symfony\Component\Process\Process::signal()") method: ``` 1 2 3 4 5 6 7 ``` ``` use Symfony\Component\Process\Process; $process = new Process(['find', '/', '-name', 'rabbit']); $process->start(); // will send a SIGKILL to the process $process->signal(SIGKILL); ``` You can make the process ignore signals by using the [setIgnoredSignals()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20setIgnoredSignals "Symfony\Component\Process\Process::setIgnoredSignals()") method. The given signals won't be propagated to the child process: ``` 1 2 3 4 ``` ``` use Symfony\Component\Process\Process; $process = new Process(['find', '/', '-name', 'rabbit']); $process->setIgnoredSignals([SIGKILL, SIGUSR1]); ``` ## [Process Pid](https://symfony.com/doc/current/components/process.html#process-pid "Permalink to this headline") You can access the [pid](https://en.wikipedia.org/wiki/Process_identifier) of a running process with the [getPid()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getPid "Symfony\Component\Process\Process::getPid()") method: ``` 1 2 3 4 5 6 ``` ``` use Symfony\Component\Process\Process; $process = new Process(['/usr/bin/php', 'worker.php']); $process->start(); $pid = $process->getPid(); ``` ## [Disabling Output](https://symfony.com/doc/current/components/process.html#disabling-output "Permalink to this headline") As standard output and error output are always fetched from the underlying process, it might be convenient to disable output in some cases to save memory. Use [disableOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20disableOutput "Symfony\Component\Process\Process::disableOutput()") and [enableOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20enableOutput "Symfony\Component\Process\Process::enableOutput()") to toggle this feature: ``` 1 2 3 4 5 ``` ``` use Symfony\Component\Process\Process; $process = new Process(['/usr/bin/php', 'worker.php']); $process->disableOutput(); $process->run(); ``` Warning You cannot enable or disable the output while the process is running. If you disable the output, you cannot access `getOutput()`, `getIncrementalOutput()`, `getErrorOutput()`, `getIncrementalErrorOutput()` or `setIdleTimeout()`. However, it is possible to pass a callback to the `start`, `run` or `mustRun` methods to handle process output in a streaming fashion. ## [Finding an Executable](https://symfony.com/doc/current/components/process.html#finding-an-executable "Permalink to this headline") The Process component provides a utility class called [ExecutableFinder](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/ExecutableFinder.php "Symfony\Component\Process\ExecutableFinder") which finds and returns the absolute path of an executable: ``` 1 2 3 4 5 ``` ``` use Symfony\Component\Process\ExecutableFinder; $executableFinder = new ExecutableFinder(); $chromedriverPath = $executableFinder->find('chromedriver'); // $chromedriverPath = '/usr/local/bin/chromedriver' (the result will be different on your computer) ``` The [find()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/ExecutableFinder.php#:~:text=function%20find "Symfony\Component\Process\ExecutableFinder::find()") method also takes extra parameters to specify a default value to return and extra directories where to look for the executable: ``` 1 2 3 4 ``` ``` use Symfony\Component\Process\ExecutableFinder; $executableFinder = new ExecutableFinder(); $chromedriverPath = $executableFinder->find('chromedriver', '/path/to/chromedriver', ['local-bin/']); ``` ## [Finding the Executable PHP Binary](https://symfony.com/doc/current/components/process.html#finding-the-executable-php-binary "Permalink to this headline") This component also provides a special utility class called [PhpExecutableFinder](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/PhpExecutableFinder.php "Symfony\Component\Process\PhpExecutableFinder") which returns the absolute path of the executable PHP binary available on your server: ``` 1 2 3 4 5 ``` ``` use Symfony\Component\Process\PhpExecutableFinder; $phpBinaryFinder = new PhpExecutableFinder(); $phpBinaryPath = $phpBinaryFinder->find(); // $phpBinaryPath = '/usr/local/bin/php' (the result will be different on your computer) ``` ## [Checking for TTY Support](https://symfony.com/doc/current/components/process.html#checking-for-tty-support "Permalink to this headline") Another utility provided by this component is a method called [isTtySupported()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20isTtySupported "Symfony\Component\Process\Process::isTtySupported()") which returns whether [TTY](https://en.wikipedia.org/wiki/Tty_\(unix\)) is supported on the current operating system: ``` 1 2 3 ``` ``` use Symfony\Component\Process\Process; $process = new Process()->setTty(Process::isTtySupported()); ``` This work, including the code samples, is licensed under a [Creative Commons BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) license. TOC Search Version **Symfony 8.0** [backers](https://symfony.com/backers) [![Check Code Performance in Dev, Test, Staging & Production](https://symfony.com/images/network/blackfire_03.png)](https://www.blackfire.io/profiler?utm_source=symfony&utm_medium=ad_black_logo&utm_campaign=profiler) [Check Code Performance in Dev, Test, Staging & Production](https://www.blackfire.io/profiler?utm_source=symfony&utm_medium=ad_black_logo&utm_campaign=profiler) [![Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).](https://symfony.com/images/network/sltraining_01.webp)](https://sensiolabs.com/training/courses?utm_source=symfony&utm_medium=symfony_ads&utm_campaign=permanent_referral) [Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).](https://sensiolabs.com/training/courses?utm_source=symfony&utm_medium=symfony_ads&utm_campaign=permanent_referral) ## Symfony footer ![Avatar of Joan Cruz, a Symfony contributor](https://www.gravatar.com/avatar/66a120cf7d0a51846821b24005ede785?size=48&rating=g&default=retro) Thanks **Joan Cruz** for being a Symfony contributor **1** commit • **71** lines changed [View all contributors](https://symfony.com/contributors) that help us make Symfony ### Become a Symfony contributor Be an active part of the community and contribute ideas, code and bug fixes. Both experts and newcomers are welcome. [Learn how to contribute](https://symfony.com/doc/current/contributing/index.html) ![](https://symfony.com/assets/icons/logos/sf-20years-wordmark-dark--dFsFxh.webp) [Celebrating 20 years of Symfony](https://symfony.com/20years) **Symfony**™ is a trademark of Symfony SAS. [All rights reserved](https://symfony.com/trademark). - [What is Symfony?](https://symfony.com/what-is-symfony) - [What is Symfony?](https://symfony.com/what-is-symfony) - [Symfony at a Glance](https://symfony.com/at-a-glance) - [Symfony Packages](https://symfony.com/packages) - [Symfony Releases](https://symfony.com/releases) - [Security Policy](https://symfony.com/doc/current/contributing/code/security.html) - [Logo & Screenshots](https://symfony.com/logo) - [Trademark & Licenses](https://symfony.com/license) - [symfony1 Legacy](https://symfony.com/legacy) - [Learn Symfony](https://symfony.com/doc) - [Symfony Docs](https://symfony.com/doc) - [Symfony Book](https://symfony.com/book) - [Reference](https://symfony.com/doc/current/reference/index.html) - [Bundles](https://symfony.com/bundles) - [Best Practices](https://symfony.com/doc/current/best_practices.html) - [Training](https://sensiolabs.com/training/courses?utm_source=symfony&utm_medium=symfony_footer&utm_campaign=permanent_referral) - [eLearning Platform](https://university.sensiolabs.com/e-learning-platform?utm_source=symfony&utm_medium=symfony_footer&utm_campaign=permanent_referral) - [Certification](https://certification.symfony.com/) - [Screencasts](https://symfonycasts.com/) - [Learn Symfony](https://symfonycasts.com/tracks/symfony) - [Learn PHP](https://symfonycasts.com/tracks/php) - [Learn JavaScript](https://symfonycasts.com/tracks/javascript) - [Learn Drupal](https://symfonycasts.com/tracks/drupal) - [Learn RESTful APIs](https://symfonycasts.com/tracks/rest) - [Community](https://symfony.com/community) - [Symfony Community](https://symfony.com/community) - [SymfonyConnect](https://connect.symfony.com/) - [Events & Meetups](https://symfony.com/events/) - [Projects using Symfony](https://symfony.com/projects) - [Contributors](https://symfony.com/contributors) - [Symfony Jobs](https://symfony.com/jobs) - [Backers](https://symfony.com/backers) - [Code of Conduct](https://symfony.com/doc/current/contributing/code_of_conduct/code_of_conduct.html) - [Downloads Stats](https://symfony.com/stats/downloads) - [Support](https://symfony.com/support) - [Blog](https://symfony.com/blog/) - [All Blog Posts](https://symfony.com/blog/) - [A Week of Symfony](https://symfony.com/blog/category/a-week-of-symfony) - [Case Studies](https://symfony.com/blog/category/case-studies) - [Cloud](https://symfony.com/blog/category/cloud) - [Community](https://symfony.com/blog/category/community) - [Conferences](https://symfony.com/blog/category/conferences) - [Diversity](https://symfony.com/blog/category/diversity) - [Living on the edge](https://symfony.com/blog/category/living-on-the-edge) - [Releases](https://symfony.com/blog/category/releases) - [Security Advisories](https://symfony.com/blog/category/security-advisories) - [Symfony Insight](https://symfony.com/blog/category/symfony-insight) - [Twig](https://symfony.com/blog/category/twig) - [SensioLabs Blog](https://sensiolabs.com/blog?utm_source=symfony&utm_medium=symfony_footer&utm_campaign=permanent_referral) - [Services](https://sensiolabs.com/?utm_source=symfony&utm_medium=symfony_footer&utm_campaign=permanent_referral) - [SensioLabs services](https://sensiolabs.com/?utm_source=symfony&utm_medium=symfony_footer&utm_campaign=permanent_referral) - [Train developers](https://sensiolabs.com/training?utm_source=symfony&utm_medium=symfony_footer&utm_campaign=permanent_referral) - [Manage your project quality](https://insight.symfony.com/) - [Improve your project performance](https://www.blackfire.io/?utm_source=symfony&utm_medium=symfonycom_footer&utm_campaign=profiler) - [Host Symfony projects](https://symfony.com/cloud/) [Powered by](https://symfony.com/cloud/) [Formerly Platform.sh](https://symfony.com/cloud/ "Upsun, a Platform-as-a-Service optimized for Symfony developers") ### Follow Symfony CLOSE
Readable Markdown
> The Process component executes commands in sub-processes. ## [Installation](https://symfony.com/doc/current/components/process.html#installation "Permalink to this headline") Note If you install this component outside of a Symfony application, you must require the `vendor/autoload.php` file in your code to enable the class autoloading mechanism provided by Composer. Read [this article](https://symfony.com/doc/current/components/using_components.html) for more details. ## [Usage](https://symfony.com/doc/current/components/process.html#usage "Permalink to this headline") The [Process](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php "Symfony\Component\Process\Process") class executes a command in a sub-process, taking care of the differences between operating system and escaping arguments to prevent security issues. It replaces PHP functions like [exec](https://secure.php.net/manual/en/function.exec.php "exec"), [passthru](https://secure.php.net/manual/en/function.passthru.php "passthru"), [shell\_exec](https://secure.php.net/manual/en/function.shell-exec.php "shell_exec") and [system](https://secure.php.net/manual/en/function.system.php "system"): The `getOutput()` method always returns the whole content of the standard output of the command and `getErrorOutput()` the content of the error output. Alternatively, the [getIncrementalOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getIncrementalOutput "Symfony\Component\Process\Process::getIncrementalOutput()") and [getIncrementalErrorOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getIncrementalErrorOutput "Symfony\Component\Process\Process::getIncrementalErrorOutput()") methods return the new output since the last call. The [clearOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20clearOutput "Symfony\Component\Process\Process::clearOutput()") method clears the contents of the output and [clearErrorOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20clearErrorOutput "Symfony\Component\Process\Process::clearErrorOutput()") clears the contents of the error output. You can also use the [Process](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php "Symfony\Component\Process\Process") class with the for each construct to get the output while it is generated. By default, the loop waits for new output before going to the next iteration: Tip The Process component internally uses a PHP iterator to get the output while it is generated. That iterator is exposed via the `getIterator()` method to allow customizing its behavior: The `mustRun()` method is identical to `run()`, except that it will throw a [ProcessFailedException](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Exception/ProcessFailedException.php "Symfony\Component\Process\Exception\ProcessFailedException") if the process couldn't be executed successfully (i.e. the process exited with a non-zero code): Tip You can get the last output time in seconds by using the [getLastOutputTime()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getLastOutputTime "Symfony\Component\Process\Process::getLastOutputTime()") method. This method returns `null` if the process wasn't started\! ## [Configuring Process Options](https://symfony.com/doc/current/components/process.html#configuring-process-options "Permalink to this headline") Symfony uses the PHP [proc\_open](https://secure.php.net/manual/en/function.proc-open.php "proc_open") function to run the processes. You can configure the options passed to the `other_options` argument of `proc_open()` using the `setOptions()` method: Warning Most of the options defined by `proc_open()` (such as `create_new_console` and `suppress_errors`) are only supported on Windows operating systems. Check out the [PHP documentation for proc\_open()](https://www.php.net/manual/en/function.proc-open.php) before using them. ## [Using Features From the OS Shell](https://symfony.com/doc/current/components/process.html#using-features-from-the-os-shell "Permalink to this headline") Using an array of arguments is the recommended way to define commands. This saves you from any escaping and allows sending signals seamlessly (e.g. to stop processes while they run): If you need to use stream redirections, conditional execution, or any other feature provided by the shell of your operating system, you can also define commands as strings using the [fromShellCommandline()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20fromShellCommandline "Symfony\Component\Process\Process::fromShellCommandline()") static factory. Each operating system provides a different syntax for their command-lines, so it becomes your responsibility to deal with escaping and portability. When using strings to define commands, variable arguments are passed as environment variables using the second argument of the `run()`, `mustRun()` or `start()` methods. Referencing them is also OS-dependent: If you prefer to create portable commands that are independent from the operating system, you can write the above command as follows: Portable commands require using a syntax that is specific to the component: when enclosing a variable name into `"${:` and `}"` exactly, the process object will replace it with its escaped value, or will fail if the variable is not found in the list of environment variables attached to the command. ## [Setting Environment Variables for Processes](https://symfony.com/doc/current/components/process.html#setting-environment-variables-for-processes "Permalink to this headline") The constructor of the [Process](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php "Symfony\Component\Process\Process") class and all of its methods related to executing processes (`run()`, `mustRun()`, `start()`, etc.) allow passing an array of environment variables to set while running the process: In addition to the env vars passed explicitly, processes inherit all the env vars defined in your system. You can prevent this by setting the env vars you want to remove to `false`: ## [Getting real-time Process Output](https://symfony.com/doc/current/components/process.html#getting-real-time-process-output "Permalink to this headline") When executing a long running command (like `rsync` to a remote server), you can give feedback to the end user in real-time by passing an anonymous function to the [run()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20run "Symfony\Component\Process\Process::run()") method: Note This feature won't work as expected in servers using PHP output buffering. In those cases, either disable the [output\_buffering](https://www.php.net/manual/en/outcontrol.configuration.php) PHP option or use the [ob\_flush](https://secure.php.net/manual/en/function.ob-flush.php "ob_flush") PHP function to force sending the output buffer. ## [Running Processes Asynchronously](https://symfony.com/doc/current/components/process.html#running-processes-asynchronously "Permalink to this headline") You can also start the subprocess and then let it run asynchronously, retrieving output and the status in your main process whenever you need it. Use the [start()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20start "Symfony\Component\Process\Process::start()") method to start an asynchronous process, the [isRunning()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20isRunning "Symfony\Component\Process\Process::isRunning()") method to check if the process is done and the [getOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getOutput "Symfony\Component\Process\Process::getOutput()") method to get the output: You can also wait for a process to end if you started it asynchronously and are done doing other stuff: Note The [wait()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20wait "Symfony\Component\Process\Process::wait()") method is blocking, which means that your code will halt at this line until the external process is completed. Note If a `Response` is sent **before** a child process had a chance to complete, the server process will be killed (depending on your OS). It means that your task will be stopped right away. Running an asynchronous process is not the same as running a process that survives its parent process. If you want your process to survive the request/response cycle, you can take advantage of the `kernel.terminate` event, and run your command **synchronously** inside this event. Be aware that `kernel.terminate` is called only if you use PHP-FPM. Danger Beware also that if you do that, the said PHP-FPM process will not be available to serve any new request until the subprocess is finished. This means you can quickly block your FPM pool if you're not careful enough. That is why it's generally way better not to do any fancy things even after the request is sent, but to use a job queue instead. [wait()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20wait "Symfony\Component\Process\Process::wait()") takes one optional argument: a callback that is called repeatedly while the process is still running, passing in the output and its type: Instead of waiting until the process has finished, you can use the [waitUntil()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20waitUntil "Symfony\Component\Process\Process::waitUntil()") method to keep or stop waiting based on some PHP logic. The following example starts a long running process and checks its output to wait until its fully initialized: ## [Streaming to the Standard Input of a Process](https://symfony.com/doc/current/components/process.html#streaming-to-the-standard-input-of-a-process "Permalink to this headline") Before a process is started, you can specify its standard input using either the [setInput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20setInput "Symfony\Component\Process\Process::setInput()") method or the 4th argument of the constructor. The provided input can be a string, a stream resource or a `Traversable` object: When this input is fully written to the subprocess standard input, the corresponding pipe is closed. In order to write to a subprocess standard input while it is running, the component provides the [InputStream](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/InputStream.php "Symfony\Component\Process\InputStream") class: The [write()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/InputStream.php#:~:text=function%20write "Symfony\Component\Process\InputStream::write()") method accepts scalars, stream resources or `Traversable` objects as arguments. As shown in the above example, you need to explicitly call the [close()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/InputStream.php#:~:text=function%20close "Symfony\Component\Process\InputStream::close()") method when you are done writing to the standard input of the subprocess. ## [Using TTY and PTY Modes](https://symfony.com/doc/current/components/process.html#using-tty-and-pty-modes "Permalink to this headline") All examples above show that your program has control over the input of a process (using `setInput()`) and the output from that process (using `getOutput()`). The Process component has two special modes that tweak the relationship between your program and the process: teletype (tty) and pseudo-teletype (pty). In TTY mode, you connect the input and output of the process to the input and output of your program. This allows for instance to open an editor like Vim or Nano as a process. You enable TTY mode by calling [setTty()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20setTty "Symfony\Component\Process\Process::setTty()"): In PTY mode, your program behaves as a terminal for the process instead of a plain input and output. Some programs behave differently when interacting with a real terminal instead of another program. For instance, some programs prompt for a password when talking with a terminal. Use [setPty()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20setPty "Symfony\Component\Process\Process::setPty()") to enable this mode. ## [Stopping a Process](https://symfony.com/doc/current/components/process.html#stopping-a-process "Permalink to this headline") Any asynchronous process can be stopped at any time with the [stop()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20stop "Symfony\Component\Process\Process::stop()") method. This method takes two arguments: a timeout and a signal. Once the timeout is reached, the signal is sent to the running process. The default signal sent to a process is `SIGKILL`. Please read the [signal documentation below](https://symfony.com/doc/current/components/process.html#reference-process-signal) to find out more about signal handling in the Process component: ## [Executing PHP Code in Isolation](https://symfony.com/doc/current/components/process.html#executing-php-code-in-isolation "Permalink to this headline") If you want to execute some PHP code in isolation, use the `PhpProcess` instead: ## [Executing a PHP Child Process with the Same Configuration](https://symfony.com/doc/current/components/process.html#executing-a-php-child-process-with-the-same-configuration "Permalink to this headline") When you start a PHP process, it uses the default configuration defined in your `php.ini` file. You can bypass these options with the `-d` command line option. For example, if `memory_limit` is set to `256M`, you can disable this memory limit when running some command like this: `php -d memory_limit=-1 bin/console app:my-command`. However, if you run the command via the Symfony `Process` class, PHP will use the settings defined in the `php.ini` file. You can solve this issue by using the [PhpSubprocess](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/PhpSubprocess.php "Symfony\Component\Process\PhpSubprocess") class to run the command: ## [Process Timeout](https://symfony.com/doc/current/components/process.html#process-timeout "Permalink to this headline") By default processes have a timeout of 60 seconds, but you can change it passing a different timeout (in seconds) to the `setTimeout()` method: If the timeout is reached, a [ProcessTimedOutException](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Exception/ProcessTimedOutException.php "Symfony\Component\Process\Exception\ProcessTimedOutException") is thrown. For long running commands, it is your responsibility to perform the timeout check regularly: Tip You can get the process start time using the `getStartTime()` method. ## [Process Idle Timeout](https://symfony.com/doc/current/components/process.html#process-idle-timeout "Permalink to this headline") In contrast to the timeout of the previous paragraph, the idle timeout only considers the time since the last output was produced by the process: In the case above, a process is considered timed out, when either the total runtime exceeds 3600 seconds, or the process does not produce any output for 60 seconds. ## [Process Signals](https://symfony.com/doc/current/components/process.html#process-signals "Permalink to this headline") When running a program asynchronously, you can send it POSIX signals with the [signal()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20signal "Symfony\Component\Process\Process::signal()") method: You can make the process ignore signals by using the [setIgnoredSignals()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20setIgnoredSignals "Symfony\Component\Process\Process::setIgnoredSignals()") method. The given signals won't be propagated to the child process: ## [Process Pid](https://symfony.com/doc/current/components/process.html#process-pid "Permalink to this headline") You can access the [pid](https://en.wikipedia.org/wiki/Process_identifier) of a running process with the [getPid()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getPid "Symfony\Component\Process\Process::getPid()") method: ## [Disabling Output](https://symfony.com/doc/current/components/process.html#disabling-output "Permalink to this headline") As standard output and error output are always fetched from the underlying process, it might be convenient to disable output in some cases to save memory. Use [disableOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20disableOutput "Symfony\Component\Process\Process::disableOutput()") and [enableOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20enableOutput "Symfony\Component\Process\Process::enableOutput()") to toggle this feature: Warning You cannot enable or disable the output while the process is running. If you disable the output, you cannot access `getOutput()`, `getIncrementalOutput()`, `getErrorOutput()`, `getIncrementalErrorOutput()` or `setIdleTimeout()`. However, it is possible to pass a callback to the `start`, `run` or `mustRun` methods to handle process output in a streaming fashion. ## [Finding an Executable](https://symfony.com/doc/current/components/process.html#finding-an-executable "Permalink to this headline") The Process component provides a utility class called [ExecutableFinder](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/ExecutableFinder.php "Symfony\Component\Process\ExecutableFinder") which finds and returns the absolute path of an executable: The [find()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/ExecutableFinder.php#:~:text=function%20find "Symfony\Component\Process\ExecutableFinder::find()") method also takes extra parameters to specify a default value to return and extra directories where to look for the executable: ## [Finding the Executable PHP Binary](https://symfony.com/doc/current/components/process.html#finding-the-executable-php-binary "Permalink to this headline") This component also provides a special utility class called [PhpExecutableFinder](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/PhpExecutableFinder.php "Symfony\Component\Process\PhpExecutableFinder") which returns the absolute path of the executable PHP binary available on your server: ## [Checking for TTY Support](https://symfony.com/doc/current/components/process.html#checking-for-tty-support "Permalink to this headline") Another utility provided by this component is a method called [isTtySupported()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20isTtySupported "Symfony\Component\Process\Process::isTtySupported()") which returns whether [TTY](https://en.wikipedia.org/wiki/Tty_\(unix\)) is supported on the current operating system: This work, including the code samples, is licensed under a [Creative Commons BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) license.
Shard148 (laksa)
Root Hash16968411856917244348
Unparsed URLcom,symfony!/doc/current/components/process.html s443