PHP is a complex machine written using the C language (C99). Nowadays, the basic PHP distribution (including default extensions) consists of about 700,000 lines of C and 30,000 lines of PHP for testing. Yes, PHP is a tested program of which tests are written themselves in PHP!
As with any program, it has been sliced into several distinct parts which each have individual responsibilities and talk to each other. PHP is an open source project, so everybody is free to download its source code and study it, which I have been doing for a few years ago now. It’s a very interesting and challenging project that is driven by its user community and a number of contributors around the world. You may study its code by looking at the GitHub mirror.
This overview outlines how PHP is organized internally, so that you may have better understanding of how things work. While reading, you should keep in mind that PHP has been designed to optimise memory consumption and execution speed, and to be web oriented, scalable and easy to learn. Sometimes you may notice the consequences of those decisions while reading the source code or while trying to understand some concepts that, on the surface, may appear strange or even downright silly.
Finally, don’t worry – we’re not about to dive deep into cumbersome C code. Instead, relax and enjoy this guided tour through the beating heart of PHP.
PHP is primarily composed of four large blocks:
- PHP Core
- Zend Engine
These four blocks can each themselves be divided into smaller parts, which we’ll study later. First, however, we’ll start with SAPI.
The Server Application Programming Interface is the entry point for reaching PHP and its organs, and is often considered to be a fuzzy feature. You may already know about several different SAPIs.
One is the Command line interface (CLI) SAPI, which contains the main() C function and allows anyone to reach PHP from the command line. It parses arguments passed into the CLI, and can read from its Stdin and write to its StdOut/StdErr like any shell-based Unix program. Try it by using the command
php -h and see what you can do with it. You can have a read of its source code on GitHub.
Next, we have the CGI, or Common Gateway Interface protocol implementation for PHP (if you’re not aware of CGI already, look it up). CGI is not very far from the CLI implementation, the main differences being that the CGI SAPI can interpret the Common Gateway Interface protocol and answers using HTTP and HTML keys. Note that the CGI SAPI can also serve as a FastCGI implementation.
The Fast Process Manager (FPM) is a design of the FastCGI protocol. FPM first appeared in PHP5.3 and is meant to replace the FCGI SAPI, which is outdated and lacking in features. FPM provides many more options than the old FCGI SAPI, such as static or dynamic pools, per-pool ini settings, per-poll environment and status control page.
Apxs2: Apache Extension 2, this is the „PHP module“ for Apache2 that binds PHP engine to Apache2 one, talking to each other. It allows embedding PHP into Apache2 server.
Many more SAPI modules exist (you can find the complete list here), these are simply the best-known examples. Of course, PHP’s worldwide spread is mainly down to its widespread integration into a large number of web servers and architectures.
With the SAPI providing an entry point, some of its goals are to:
- manage headers for the incoming request
- manage incoming request data, such as POST or COOKIE
- write on the output layer, should it be an Apache buffer, a Unix process stdout, or something else
- start and stop the other components, ZendEngine and PHPCore
The Zend Engine
Though its border with PHP Core is tight, the Zend Engine actually uses a different open-source license to the PHP licence (though the two are compatible), and can be thought as a complete project in itself. In fact, it is – some big companies have managed to separate PHP from its engine (for example IBM and Facebook). While no trivial task, it’s actually not that hard to do, as the Zend Engine has been thought of as being somehow decoupled from PHP.