When one program runs another program, the execution of
the second program is actually a two-step procedure. First, the calling process
forks and makes a duplicate of itself, and then immediately does an exec call
to replace the executable code and memory with that of the new program.
If you just want to run a program and read the output or write to it, there are
easier ways of doing it, such as popen(). But, if you must be able to both read
and write to the program, you need to manually fork and exec from PHP, or
use the proc_open() function.
Following is an example that forks and execs an ls command:
<?php
$child_pid = pcntl_fork();
if ($child_pid == 0) {
// replace php with “ls” command in child
pcntl_exec(”/bin/ls”, array(”-la”));
} elseif ($child_pid != -1) {
// wait for the “ls” process to exit
pcntl_waitpid($child_pid, $status, 0);
}
?>
First, a child process is created. Then, in the process where $child_pid
was returned as 0 (the child process), the ls command is executed. The output
from ls will go to standard output. The parent process waits for the child to
exit before it continues.
Here is another example. PHP detaches itself from the terminal and con-
tinues running in the background (a technique known as daemonizing):
<?php
$pid = pcntl_fork();
if ($pid) {
exit(0);
}
// create new session, detach from shell’s process group
posix_setsid();
// XXX if STD{IN,OUT,ERR} constants become available, these have
// to be closed here.
while (true) {
error_log(”heartbeat\n”, 3, “/tmp/test.log”);
sleep(10);
}
?>
First, this script forks and creates a second PHP process. The parent pro-
cess then exits, and the child continues. Then, the child disconnects from the
controlling terminal and creates its own session and process group with
posix_setsid(). This makes sure that signals sent to the shell are not passed
along to the child PHP process.
