In many languages, you build web frameworks from the ground up (i.e. from unix sockets) and layer on abstractions. If I want to build a web framework from scratch in OCaml or C, I first build a socket server that listens on port 80.
It just came to me that PHP – like any other higher-level language – probably wraps unix sockets somehow. Now I know it is the case that this was never how PHP was designed. However, I don’t see why it has never been used in this way. Along these same lines, the PHP interpreter is never used in this way like the Python interpreter is.
For instance, when I build a Python web server from scratch and deploy it, I do the following: attacg a unix socket on some port (say 8000), daemonize my script like
python server.py 8000, and have nginx reverse proxy on port 80 and forward to my internal, local server on port 8000. I have NEVER seen this done in PHP, even though it is possible.
I will admit that you have other options in Python other than using the interpreter standalone (i.e. tornado, uwsgi, etc). However it is done both ways.
My question is, what are the aspects of PHP the language, interpreter, or community that have prevented PHP web frameworks being built from the ground up from unix socket calls, daemonized on a local port, and being reverse proxied instead of using a cgi/fastcgi wrapper?
In a word, history. This is a very abbreviated summary of 15+ years of history (you can find out more on the Internet, if you are really interested):
First, while PHP has all the features of a programming language, this wasn’t always so. It started out as a “hypertext preprocessor” whose purpose was to be embedded in HTML pages and parsed by a CGI program or the web server itself. It was meant to be run by an existing web server, not to be a web server. In its early iterations it was a very simple language (and some would say it still is).
PHP dates back to the late 1990s, and the only way for a web server to run dynamic content back then was through CGI. CGI’s big problem, though, was that it was rather slow, because it forked a new process for every request. Not a big deal in the early days, but when the dot-com boom hit, it became something of an issue. PHP became popular enough that it was embedded into Apache as a loadable module, which gave better performance than CGI and offered some other benefits.
For the longest time, PHP was only runnable in one of those two ways, but since it had become the language with the vast majority of market share, nobody really cared much. Though eventually some people wanted to use servers other than Apache, and for a while CGI was the only way to do that, until a FastCGI server API known as php-fpm (FastCGI Process Manager) was eventually contributed into PHP. Unlike CGI, FastCGI keeps a pool of processes always running and ready to serve incoming requests.
In the 2000s came other languages, which do things differently. For instance, in Ruby application libraries are shipped in what are called gems, and a program can easily be created simply by gluing together some existing gems with business logic. Rack is a Ruby gem which provides a Ruby API for building web servers, and servers such as mongrel, unicorn, thin, etc., and frameworks such as Rails and Sinatra, are built on top of it.
Other languages such as Python and Java have similar web servers and web server frameworks. As you can see this is a completely different approach from the one taken by PHP, which generally doesn’t use HTTP at all to serve requests.
However, recent versions of PHP now have a “built in web server“, but it is relatively new and can only handle one connection at a time, making it unsuitable for production use. It’s explicitly designed for developer use.
Ultimately it comes down to this: PHP was designed to work in the context of an existing HTML document, while other languages such as Python, Ruby, Java, etc., are general-purpose. The only other web language I know of which works like PHP in this respect is Microsoft’s “classic” ASP, which has a similar design.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.