Life Cycles
Each PHP instance, whether started from an init script, or from the command line, follows a series of events involving both the Request/Module Init/Shutdown events covered previously, and the actual execution of scripts themselves. How many times, and how frequently each startup and shutdown phase is executed, depends on the SAPI in use. The four most common SAPI configurations are CLI/CGI, Multiprocess Module, Multithreaded Module, and Embedded.
CLI Life Cycle
The CLI (and CGI) SAPI is fairly unique in its single-request life cycle; however, the Module versus Requests steps are still cycles in discrete loops. Figure 1.1 shows the progression of the PHP interpreter when called from the command line for the script test.php.
Figure 1.1. Requests cycles versus engine life cycle.
The Multiprocess Life Cycle
The most common configuration of PHP embedded into a web server is using PHP built as an APXS module for Apache 1, or Apache 2 using the Pre-fork MPM. Many other web server configurations fit into this same category, which will be referred to as the multiprocess model through the rest of this book.
It's called the multiprocess model because when Apache starts up, it immediately forks several child processes, each of which has its own process space and functions independently from each another. Within a given child, the life cycle of that PHP instance looks immediately familiar as shown in Figure 1.2. The only variation here is that multiple requests are sandwiched between a single MINIT/MSHUTDOWN pair.
Figure 1.2. Individual process life cycle.
This model does not allow any one child to be aware of data owned by another child, although it does allow children to die and be replaced at will without compromising the stability of any other child. Figure 1.3 shows multiple children of a single Apache invocation and the calls to each of their MINIT, RINIT, RSHUTDOWN, and MSHUTDOWN methods.
Figure 1.3. Multiprocess life cycles.
The Multithreaded Life Cycle
Increasingly, PHP is being seen in a number of multithreaded web server configurations such as the ISAPI interface to IIS and the Apache 2 Worker MPM. Under a multithreaded web server only one process runs at any given time, but multiple threads execute within that process space simultaneously. This allows several bits of overhead, including the repeated calls to MINIT/MSHUTDOWN to be avoided, true global data to be allocated and initialized only once, and potentially opens the door for multiple requests to deterministically share information. Figure 1.4 shows the parallel process flow that occurs within PHP when run from a multithreaded web server such as Apache 2.
Figure 1.4. Multithreaded life cycles.
The Embed Life Cycle
Recalling that the Embed SAPI is just another SAPI implementation following the same rules as the CLI, APXS, or ISAPI interfaces, it's easy to imagine that the life cycle of a request will follow the same basic path: Module Init => Request Init => Request => Request Shutdown => Module Shutdown. Indeed, the Embed SAPI follows each of these steps in perfect time with its siblings.
What makes the Embed SAPI appear unique is that the request may be fed in multiple script segments that function as part of a single whole request. Control will also pass back and forth between PHP and the calling application multiple times under most configurations.
Although an Embed request may consist of one or more code elements, embed applications are subject to the same request isolation requirements as web servers. In order to process two or more simultaneous embed environments, your application will either need to fork like Apache1 or thread like Apache2. Attempting to process two separate request environments within a single non-threaded process space will lead to unexpected, and certainly undesired, results.