Skip to content

Commit 6e32e52

Browse files
[Process] Introduce InputStream and iterator for output
1 parent d7724dd commit 6e32e52

File tree

1 file changed

+60
-1
lines changed

1 file changed

+60
-1
lines changed

components/process.rst

+60-1
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,28 @@ The ``getOutput()`` method always returns the whole content of the standard
4343
output of the command and ``getErrorOutput()`` the content of the error
4444
output. Alternatively, the :method:`Symfony\\Component\\Process\\Process::getIncrementalOutput`
4545
and :method:`Symfony\\Component\\Process\\Process::getIncrementalErrorOutput`
46-
methods returns the new outputs since the last call.
46+
methods return the new output since their last call.
4747

4848
The :method:`Symfony\\Component\\Process\\Process::clearOutput` method clears
4949
the contents of the output and
5050
:method:`Symfony\\Component\\Process\\Process::clearErrorOutput` clears
5151
the contents of the error output.
5252

53+
You can also use the :class:`Symfony\\Component\\Process\\Process` class with the
54+
foreach construct to get the output while it is generated. By default, the loop waits
55+
for new output before going to the next iteration::
56+
57+
$process = new Process('ls -lsa');
58+
$process->start();
59+
60+
foreach ($process as $type => $data) {
61+
if ($process::OUT === $type) {
62+
echo "\nRead from stdout: ".$data;
63+
} else { // $process::ERR === $type
64+
echo "\nRead from stderr: ".$data;
65+
}
66+
}
67+
5368
The ``mustRun()`` method is identical to ``run()``, except that it will throw
5469
a :class:`Symfony\\Component\\Process\\Exception\\ProcessFailedException`
5570
if the process couldn't be executed successfully (i.e. the process exited
@@ -68,6 +83,10 @@ with a non-zero code)::
6883
echo $e->getMessage();
6984
}
7085

86+
.. versionadded:: 3.1
87+
Streaming the input or the output of a process using iterators
88+
were added in Symfony 3.1
89+
7190
Getting real-time Process Output
7291
--------------------------------
7392

@@ -128,6 +147,46 @@ are done doing other stuff::
128147
which means that your code will halt at this line until the external
129148
process is completed.
130149

150+
Streaming to the standard input of a Process
151+
--------------------------------------------
152+
153+
Before a process is started, you can specify its standard input using either the
154+
:method:`Symfony\\Component\\Process\\Process::setInput` method or the 4th argument
155+
of the constructor. The provided input can be a string, a stream resource or a
156+
Traversable object::
157+
158+
$process = new Process('cat');
159+
$process->setInput('foobar');
160+
$process->run();
161+
162+
When this input is fully written to the subprocess standard input, the corresponding
163+
pipe is closed.
164+
165+
In order to write to a subprocess standard input while it is running, the component
166+
provides the :class:`Symfony\\Component\\Process\\InputStream` class::
167+
168+
$input = new InputStream();
169+
$input->write('foo');
170+
171+
$process = new Process('cat');
172+
$process->setInput($input);
173+
$process->start();
174+
175+
// ... read process output or do other things
176+
177+
$input->write('bar');
178+
$input->close();
179+
180+
$process->wait();
181+
182+
// will echo: foobar
183+
echo $process->getOutput();
184+
185+
The :method:`Symfony\\Component\\Process\\InputStream::write` method accepts scalars,
186+
stream resources or Traversable objects as argument. As shown in the above example,
187+
you need to explicitly call the :method:`Symfony\\Component\\Process\\InputStream::close`
188+
method when you are done writing to the standard input of the subprocess.
189+
131190
Stopping a Process
132191
------------------
133192

0 commit comments

Comments
 (0)