ReactPHP Child Process Component enables an access to Operating System functionalities by running any system command inside a child process. We have access to that child process input stream and can listen to its output stream. For example, we can pass arguments to the command or pipe its output to another command as its input.
First of all, let’s create an instance of the
React\ChildProcess\Process class. Our first command is going to ping Google:
There are two basic operations you can perform on a process: you can start or terminate it. To start a process we need an instance of the event loop to pass it to the
As it was said earlier ReactPHP takes care of the process input and output streams. So even if we run this example from the command line there will be no output of the
ping command in the terminal.
We need to setup the process input and output streams ourselves. Let’s start with some basic stuff and simply echo the process output to the console. An instance of the
Process class has three public properties for managing the basic I/O of the process:
Each of this properties is an instance of the
React\Stream\Stream so we can use them as ReactPHP streams. For
stdout we can listen for
data event and
Now it is a working example of a child process implemented with ReactPHP. We have a running
ping command and its output is being placed to the terminal via PHP:
The process can also receive data from the parent. We can use
stdin property and
write() some data directly to the child process input stream. This is a simple Hello world example where we start PHP interactive shell and then type a code string which is immediately executed:
Notice that these I/O properties will be populated with
React\Stream\Streamobjects only after calling
Here is a bit of the
Process class source code:
So, if you try to access these properties before calling
start() you will get an error:
The code above will cause a fatal error:
Uncaught Error: Call to a member function on() on null. Keep this in mind when working with a child process I/O.
Since a child process
stdin property is a writable stream and
stdout property is a readable one we can
pipe() input/output of multiple processes on each other. We use one command’s output as an input for another command.
In the example above, the child process executes
ls command which lists all files and folders in the current directory. Then we pipe it’s output into another child process
wc -l command which counts a number of lines. When executed this code prints a total number of files and folders in the current directory.
Since PHP uses the shell wrapper for all commands we can use the shell syntax to execute the command. So the previous example can be rewritten like this:
ping command is going to execute until we stop it. To stop a child process from its parent we call
terminate() method. To demonstrate it we use a simple timer like this:
An instance of the
Process class implements
EventEmitter interface. This means that we can register handlers for events on this object. When a process is terminated it emits
exit event. In the next example we execute
ping command during 3 seconds, then when the child process is being finished, the event loop stops and the parent script exits:
The handler for the
exit event gives us the
$exitCode for the child process and the
$termSignal variable is
null when the child process exits normally.
Often when we deal with child processes it is useful to know their PID (process identifier).
Process class has
getPid() method, which can be used for sending signals to it. For example, one more way to terminate a process - is to send a
kill signal to it:
In this example, we again start
ping 220.127.116.11 process. Then we attach a timer which retrieves a child process PID and creates a new child process to
kill the first one. We have also registered a handler for the
exit event to check if the process has actually received the signal:
Other ReactPHP articles: