2013-06-27

Co.Labs

Why PHP Has No Place On Our Experiments Server

We’re trying to build an open-source, language-agnostic super easy-to-use experiments server. Call it an internal Heroku. The only language we’re struggling with is PHP.



Tell me if you’ve heard this one before: We have a problem with PHP. We’re trying to build a language-agnostic experiments server that anyone who works for Fast Company--from members of the development team who want to play with non-site features to interns working on projects to reporters who want to learn to code--can use with little configuration overhead and simple deployment. Think of it as our own internal Heroku. But getting our little environment to play nice with PHP has been a nightmare--even Heroku doesn’t officially support the language, and its default buildpack doesn’t even support concurrency, making optimizing it difficult.

Before you run down to the comment box to start yet another programming language war, let me say this: I have a soft spot in my heart for PHP. Like many developers, I learned how to program with PHP, first by tinkering with PHP-Nuke and PostNuke, and later with WordPress. But after I moved on to languages like Python and Ruby, I started to appreciate all of the conveniences of these more recent languages, like real command line interfaces and interactive shells, simple development servers, package managers and, most of all, lightweight application servers.

These easy-to-setup application servers are the backbone of our experiments environment. We started out using nginx for routing, but found the overhead of editing conf files with specific instructions for every different app server too time-consuming and difficult for users who just want to deploy and be done. To address this problem, our CTO Matt Mankins is building a router he calls “Chassis” using NodeJS and Express with a simple command line interface for app creation and deployment written mostly in Perl. We’re hoping to release Chassis as an open-source project soon.

The idea behind Chassis is simple. By default, it should handle static files in Express, but once a user sets up a project, Chassis should reverse proxy requests to their app and then get out of the way, letting middleware and application servers do all of the work. For most languages, this works beautifully. Ruby has Rack and Mongrel/Thin/Unicorn, Python has WSGI and any number of application servers like CherryPy or GUnicorn and JavaScript has, well, Express (technically, Express Connect and Express).

Then the other day Co.Labs editor Chris Dannen handed me a simple app built in PHP that automates freelancer invoicing, and we had a problem. The standard way to serve PHP is, of course, to use Apache with mod_php. But using Apache in a reverse-proxy environment requires editing a conf file to setup virtual hosts listening on specific ports, exactly what we’re trying to avoid. It also makes it very difficult (although not impossible) to restart individual hosts without re-starting the entire httpd service.

After talking to friends and searching the web, it appears that the alternatives are few and far between. FastCGI suffers from the same configuration problems that Apache does. Formerly popular lightweight servers like lighthttpd, nanoweb and PHP-FPM seem to be out of active development. Photon looks promising, but isn't very mature yet and requires a complex build to get running. Zend Server is monstrously overweight and not fully open-source. HipHop VM, which is not exactly easy to compile, is actually the best option I’ve found, but it doesn’t support eval(), which the invoice app relies on heavily because it uses dompdf. Other compiled PHP solutions like Quercus, which runs PHP on Java, are similarly difficult to build and deploy, and rely on the developer understanding multiple languages.

None of this is to say that Apache with mod_php is bad for most solutions or that PHP hasn’t come a long way in catching up to languages like Ruby and Python in the last few years. PHP 5.4 introduced a simple development server along with other much-needed features. After spending most of its existence without a real dependency manager (admit it, Pear is terrible), the community finally seems to have coalesced around Composer. Laravel appears to be taking on the mantle of “PHP’s Ruby on Rails,” with frameworks like Slim and CodeIgniter filling in the more lightweight role that Sinatra and Padrino play in the Ruby ecosystem. WordPress, of course, is still unmatched in any language when it comes to purpose-built CMS software.

Despite all of these improvements, I can’t find anything like Thin, Mongrel, Unicorn, CherryPy, or Express for PHP. Yes, I know that part of the reason is that PHP wasn’t originally built to run efficiently on middleware like Rack and WSGI. But that middleware, combined with lightweight application servers, are what make developing and deploying with other languages such a joy compared to PHP and often more efficient in production. They’re a big reason why developers increasingly choose these languages for their apps, despite PHP’s recent improvements. For PHP to truly catch up to these other languages, it needs a robust application server.

I’m happy to be proven wrong if you know of a way to run PHP web apps in a lightweight, standalone context. Until then, we’re going to have to recommend that developers on our experimental server choose other languages. That’s a shame, because despite all of the negative attention it gets, PHP remains a great first language. I’ll always have a soft spot for it in my heart, just not on my server.

[Image: Flickr user Nina Matthews]