Earlier today, Dries committed a patch that adds two Symfony2 Components to Drupal: ClassLoader and HttpFoundation.
On its face it's a fairly simple patch; the new code in it is maybe a dozen lines. But it's an important part of a larger shift within Drupal to better embrace the modern web, on the server as well as the client.
The new face of PHP
The PHP development community has long been highly fractured. Everyone had their own CMS, their own framework, and their own applications. Even when developers started rallying around a few market leaders (Drupal included), there was no real interoperability. Attempts at a common framework either suffered from the standards problem, morphed into all-or-northing frameworks, or ran into naming collisions with everyone else, making them almost useless.
That has changed in recent years thanks to three key developments.
- First, Object-Oriented architecture has firmly taken hold in the PHP world. While not the solution to every problem, OOP does support library mix-and-match design much more easily than procedural code.
- Second, PHP 5.3 introduced code-level namespaces, allowing different libraries to co-exist without clobbering each other on a class or function name.
- Third, some of the leading PHP projects collectively agreed on how to leverage namespaces. That convention, dubbed PSR-0 (for PHP Standard Reference #1, because computer people always start counting at 0), specifies a common pattern for naming and organizing namespaced classes. The result is that it's now possible to leverage PHP's autoload capabilities across a range of projects in a consistent and predictable manner.
And all of those changes passed Drupal by. Drupal 7 shipped as a mostly procedural, non-namespaced framework with a somewhat fragile custom autoload system, the Registry. And, as a result, very little ability to benefit from the changes happening in the wider PHP community.
That's actually rather sad for me personally, given that Drupal was a leading project in the last great PHP collaborative effort, GoPHP5. Sadly we never kept that momentum going.
Pushing Drupal forward
The Web Services and Context Core Initiative for Drupal 8 is working on major changes to Drupal, refactoring it from a page-oriented CMS to a request/response-oriented REST server. That's no small task, and one that could benefit from a leg up from the wider open source community.
For that reason, several people began recommending that Drupal start to embrace the changes happening in the wider development community, first with a PHP 5.3 base and now with PSR-0 classes. By adopting the existing standard for classes, making our autoloading simpler and less error prone, and open the door to considerable performance improvements. By converting our core code over to easily-lazy-loaded classes, we can greatly reduce Drupal's memory footprint by not bootstrapping code we don't need. That makes response time faster, which is critical for any form of web service.
Much to my surprise, there was very little resistance.
That also means that we could now leverage existing code like HttpFoundation that we don't need to write ourselves, saving time and effort. That too met with little resistance.
Drupal is back in the PHP game.
The PHP library world has been changing rapidly in recent years. Once upon a time, there was only one really popular component library, PEAR, which had quasi-official status but was still a pain to install on many shared hosts. More recently, a number of popular frameworks have grown up, including Zend Framework, CodeIgnighter, and others, specifically casting off the PHP 4 legacy of earlier years. The Symfony framework, a Rails-y pseudo-MVC application framework, decided to go that route as well and completely reinvented itself for version 2. That included spinning off many low-level systems as free-standing components.
Zend and Symfony were both parties to the original PSR-0 standard, making it possible for (properly-written) code to be mixed and matched between the two.
When Drupal was looking for a 3rd party HTTP library to adopt rather than writing our own, we looked at two that seemed to have the best market share behind them: Zend 2 and Symfony2. We knew that whichever one we adopted we stood a very good chance of adopting more components from, so it was perhaps a more important decision than those involved realized at the time. After a comparison, we settled on Symfony for a number of reasons.
- Symfony's component libraries, or at least HttpFoundation, appeared to be richer and more self-contained, allowing us to pick and choose what we use.
- Zend Framework has a Contributor License Agreement, which Symfony does not. While I fully understand the reasons why Zend has a CLA, and I've even toyed with the idea of one for Drupal in the past, it raises the barrier to entry for Drupal developers to contribute back upstream. We wanted to ensure that we didn't just grab-and-go, but formed a partnership with whatever project we decided to leverage.
- Speaking of partnerships, the quick feedback and cooperation from Symfony's project lead, Fabien Potencier, and Lukas Smith carried a great deal of weight.
Even since then, Fabien and Lukas have made themselves available for help, insight, and other advise. Drupal folks have even started to submit code back to Symfony, too, for minor cleanup as well as feature fixes. That's exactly what I was hoping to see happen.
Now that we have the ClassLoader and HttpFoundation in core, there's a lot of work yet to do.
- The HTTP handler for the Context API is not quite finished, but hopefully will be soon. That lets us leverage the HttpFoundation in a consistent, clean, and powerful way to help control how Drupal responds to page request.
- HttpFoundation includes a session-handling system, but leveraging it requires better decoupling our user and session systems. Which is something we should be doing anyway.
- There's an open discussion of where else we could leverage Symfony2 components. There are actually a number of viable possibilities.
- Now that we have adopted PSR-0 for core, we need to start refactoring the /includes directory to leverage it. That means cleaning up and converting core subsystems to object-oriented designs that we can then lazy-load without effort. That should help performance and code clarity.
- So far, we're just using PSR-0 for core classes. What about modules? That's actually a much harder question, but it's one we will need to figure out sooner rather than later.
- And oh yeah, we should update our coding standards documentation. That's on my list.
We have a lot of work ahead of us, but this is the beginning of Drupal no longer being an isolated island in the PHP world. If you want to help Drupal remain the dominant PHP CMS, let's roll up our sleeves and get to work.
I'll see you in the issue queues.