Skip to content

[Process] Introduce InputStream and iterator for output #6424

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 64 additions & 1 deletion components/process.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,32 @@ 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 :method:`Symfony\\Component\\Process\\Process::getIncrementalOutput`
and :method:`Symfony\\Component\\Process\\Process::getIncrementalErrorOutput`
methods returns the new outputs since the last call.
methods return the new output since their last call.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make this fix in all affected lower branches too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see #6658


The :method:`Symfony\\Component\\Process\\Process::clearOutput` method clears
the contents of the output and
:method:`Symfony\\Component\\Process\\Process::clearErrorOutput` clears
the contents of the error output.

.. versionadded:: 3.1
Support for streaming the output of a process was introduced in
Symfony 3.1.

You can also use the :class:`Symfony\\Component\\Process\\Process` class with the
foreach construct to get the output while it is generated. By default, the loop waits
for new output before going to the next iteration::

$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;
}
}

The ``mustRun()`` method is identical to ``run()``, except that it will throw
a :class:`Symfony\\Component\\Process\\Exception\\ProcessFailedException`
if the process couldn't be executed successfully (i.e. the process exited
Expand Down Expand Up @@ -128,6 +147,50 @@ are done doing other stuff::
which means that your code will halt at this line until the external
process is completed.

Streaming to the Standard Input of a Process
--------------------------------------------

.. versionadded:: 3.1
Support for streaming the input of a process was introduced in
Symfony 3.1.

Before a process is started, you can specify its standard input using either the
:method:`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::

$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 :class:`Symfony\\Component\\Process\\InputStream` class::

$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 :method:`Symfony\\Component\\Process\\InputStream::write` method accepts scalars,
stream resources or Traversable objects as argument. As shown in the above example,
you need to explicitly call the :method:`Symfony\\Component\\Process\\InputStream::close`
method when you are done writing to the standard input of the subprocess.

Stopping a Process
------------------

Expand Down