PHP needs to die. What will replace it?

posted 11 August 2011

It's time for PHP to die. And I say this as a die-hard PHP developer currently converting an existing Ruby on Rails codebase to PHP.

History repeating

The reason I know PHP has to die is because I've seen this before. Roughly a decade ago, PHP killed Perl. Not completely, of course; it still clings on in some environments, it has a sizable legion of die-hard fans, and legacy apps will need to be maintained in it for decades to come. But as a language for newcomers, and especially for web developers, it was already dying in 1999 and was mostly dead by sometime around 2005.

As a newcomer to web development around then, it was clear both that this would happen and why: Perl was ill-suited for the new application environment. Pages of tedious boilerplate CGI were required in Perl to achieve PHP's basic, default behaviour. The language was full of anachronistic features -- pointers (update: sorry, references), inconvenient hash structures, and a dozen other little language quirks -- that made web development tedious, insecure, or inconvenient. There was no reason you couldn't write a perfect web app in Perl, but in PHP you'd do it faster and easier, despite the flaws in PHP itself which were, even then, already obvious.

The arguments for Perl over PHP in 1999 were many: it was a lot faster, it had far more libraries and driver support, and CPAN was a wonderland of pre-written code that would get you 80% of the way in almost any task. It sounds funny to say it now, but "PHP doesn't scale" was actually an argument back then. But PHP won anyway, because those things are not intrinsic advantages to the language. Interpreters can get faster, libraries always get written, and PEAR and PECL are gigantic these days*, without considering the myriad less-formal libraries available from every vendor who wants people to use their APIs. PHP is the de facto standard language of web development.

Time to move on

Ten years later, I can feel the tide turning again. Developers' expectations of languages have moved on. If the critical thing Perl was lacking was PHP's wonderfully flexible "associative arrays" (aka smart hashes), then what PHP is lacking is lambdas and method chaining. While PHP used to be the language where you could write a web page in twenty lines of code, nowadays it doesn't feel like you're doing it properly unless you've laid down at least a basic MVC framework of some kind. That boilerplate code is the tell: the language now requires modification by a framework to do what you need.

Back then, I felt the die-hards clinging to Perl for web development were silly. Now, with ten years of PHP experience under my belt, I'm in the same position. I can knock out a good website in an hour in PHP, and an excellent one in a day or two. Its performance characteristics are well-known and understood, so I can make it scale pretty much indefinitely. Every developer we'd want to hire knows it, and every system we'd integrate with has a wrapper library written in it. I am trapped by the convenience of PHP in a language that is losing its suitability for the task.

Forward Ruby on Rails

The most obvious potential successor to PHP is Ruby on Rails**. Ruby is a newer, cleaner language, with modern features and a sparse, elegant syntax (much like Python). Rails takes the common tasks and boilerplate of a best-of-breed web app away and turns what are three or four-line idioms in PHP into first-class language constructs. This sounds exactly like what I need to replace PHP and accelerate my development once again.

But seven months into using Rails every day, hacking on a Rails app constructed by experienced Rails experts who love the framework and the language, I just can't say it's the right choice, for reasons that I find hard to pin down. The purpose of this essay is to try and discover them.

My chief gripe, it must be said, is performance. I've just finished saying this should not be considered a fatal flaw in a language, but rather a temporary problem in its implementation. So I cannot really take it as an argument, though I should note the performance is the primary reason I am porting my current app back to PHP. I can make Rails run just as fast as PHP, but I need between 2 and 4 times as much hardware to do so. In five years time this is unlikely to be true, and in five years time maybe I wouldn't be switching to PHP. But right now, it's not cutting it.

Second, I hate Active Record. Active Record is a pattern, not intrinsic to Ruby, and optional in recent versions of Rails, but its use and its patterns are deep in the DNA of Rails. I have previously gone into why I think ORM on RDBMS is a bad idea, so I won't repeat myself except to summarize that the efficiency gain of not having to write CRUD is more than outweighed by the efficiency lost by ActiveRecord doing silly things and spending time working out what those are, and bending the rules of the framework to prevent it doing so.

Thirdly, I am deeply suspicious of code generation. Code that writes your boilerplate for you is helpful and all, but if your language requires a pile of boilerplate to get anything done, then something is already wrong. Code generation encourages "magical thinking", where the coder is not sure whether a particular convenient feature comes from code that was written for them or intrinsically as part of the language environment. Magical thinking is dangerous.

Code generation brings me to what is probably the fundamental problem with Ruby on Rails, which is that it is not a language. Ruby is the language. And Ruby, while solving some of PHP's fundamental problems, does not solve the core problem, which is that modern web applications have an elevated set of expectations: features like routing, model/view separation and drop-in functionality are now par for the course. Rails adds these, but it is the same bandage that MVC frameworks like Zend, Symfony and Code Igniter add to PHP.

So what's missing?

The language that takes the reigns from PHP has to be as much better than PHP as PHP was better than Perl. It has to make assumptions about the primary shape of web applications in the same way that PHP assumed that your code's primary function was always going to be spitting out a web page -- a radical assumption that makes it slightly awkward to do other things, like shell scripts. I want a language that assumes everything I will be building is an MVC web app, and builds that right into the core language, not just a library.

The problem is, there's no such language. For a while it looked like maybe server-side JavaScript would be the next big thing, unifying language on the front-end and the back-end of web applications. But the great minds of JavaScript have wandered off on the tangent that is nodejs: the evented pattern is a radical and powerful way of making high-performance applications that make best use of modern hardware, but it is a way of making server-side applications, not web pages. And there are still an awful lot of web pages that need to be written. Other CommonJS efforts like ejScript begin to attempt replacing PHP but do not resolve the framework problem.

Still waiting

I'm forced to conclude that PHP's replacement is just not here yet. Ruby on Rails is good, but not that much better than a similar MVC framework on top of PHP, and certainly not better enough to justify the performance hit brought on by the double-whammy of inefficiency of Ruby itself and ActiveRecord's ORM shenanigans. Python appears uninterested in being the next web language, and JavaScript's server-side revolution is only just getting started.

I await the Next Big Thing. I want to switch away from PHP, I really do. I don't want to be the Perl dinosaur. But whatever it is, it doesn't seem to be here yet. Am I wrong?

* Another advantage that I strongly feel contributed to PHP's success was its amazing documentation, which was complete, accurate, and full of real-world example code. Many early PHP apps -- mine included -- were written by just surfing the documentation and pasting together the relevant snippets. However, this is not an intrinsic advantage of PHP so I'm going to leave it out of consideration. A final advantage was that PHP runs well and installs easily on Windows; 95% of all computers on earth are still running Windows, so your language needs to run there if you expect widespread adoption by teenaged newbie developers who don't get to pick their own hardware.

** Why not Python? I just feel if Python were going to break out as a web language it would have done so by now. That's not to say nobody is writing web apps in python -- many people I highly respect do so -- but it's hardly a revolution in progress. Python is a wonderful language: clean, elegant, easy to learn and maintain. But while it is excellent at the Internet and networking in general it has no particular love for the web. Django is capable but not really what developers expect from MVC, and other MVC frameworks for Python have much less traction. Python is not going to take over the web, I think primarily because not even its fans want it to.