A Drupal Developer in Symfony Land
Last week in San Francisco, around 200 PHP developers, myself included, gathered for the Sensio Labs Symfony Live conference. For the uninitiated, Symfony is a full-stack PHP framework made up of a collection of 23 individual components designed to solve common web development problems.
So why are we talking about Symfony on a Drupal company blog? The Drupal community has recently been letting go of "not invented here" and looking elsewhere for code that might share common goals. Drupal 8 is currently in rapid development and many components of the Symfony framework have already been incorporated into Drupal core. Including this much external code at the infrastructure level of Drupal marks a major paradigm shift for the project — and hopefully the beginning of a shift in the wider PHP open-source world as well. The Drupal community has tried this before, with mixed results. Drupal's early adoption of jQuery is seen almost universally as a smart move and probably helped contribute to the widespread success of jQuery. Simpletest, on the other hand, had to be heavily modified for Drupal's needs, and still needs to be maintained by the Drupal community as a separate project. Meanwhile, back in 2012... Fabien Protencier, the creator of the Symfony framework, opened Thursday morning with his keynote. First up? A discussion about release cycles: a topic that only an open-source developer or a Microsoft project manager can truly get excited about. One thing for Drupal to note is the beginning of long-term support (LTS) releases for Symfony. This means we can incorporate Symfony components with the assurance that upstream bug fixes will continue for three years (which happens to be just about the average lifetime of a major version of Drupal).
One risk for any open-source project (or any project, period) incorporating outside code is the possibility of having to maintain that code over the long term. In this case, the Drupal community is assured that the efforts of the 500 Symfony contributors who helped with the latest release of Symfony will continue to benefit Drupal, and that we can make concrete plans on when and how to incorporate future changes into Drupal.
Symfony's policy on backwards compatibility is another keynote tidbit that may affect Drupal's own releases. Symfony will maintain backwards compatability for all 2.x releases, leaving any breaking changes for 3.0.
After lunch on Thursday, Drupal's own Larry Garfield took the stage to let the Symfony world know what Drupal's doing with their code. In short, Symfony now owns Drupal's requests. From initialization on down Drupal's 1,000 possible routes, every Drupal request will now be touched by a Symfony component.
"Drupal is an 11-year-old, PHP4-based extensible Slashdot clone built by a Belgian college kid."
At DrupalCon San Francisco in 2010, there were discussions around enabling Drupal to deliver content to the plethora of devices that'll soon explode onto the web development landscape. These discussions spawned the WSCCI initiative.Initially planned as a re-envisioning of Drupal's own request handling, the WSCCI initiative eventually looked outside of Drupal for inspiration in handling this problem. Symfony's Lukas Smith and Fabien Potencier joined in on one discussion of HTTP libraries; their engagement helped establish the HTTP Foundation Component as a viable drop-in replacement. Once HTTP Foundation was committed to Drupal core, the floodgates opened and many other parts of the Symfony framework quickly followed.
Curious about Drupal's new accomplices? Here's a quick overview of some of the major Symfony components already in Drupal 8:
- The HTTP Foundation Component is at the core of any framework built on Symfony. This is where request and responses happen. A request object is created containing information similar to what you find PHP's $_SERVER superglobal. In return, a response object spits out content.
- The HTTP Kernel Component is responsible for what happens between the request and the response. It essentially finds a controller and executes it. It defines the pattern of translating a request to a response.
- The Event Dispatcher Component implements the observer pattern, enabling the system to attach code to specific events. Imagine Rules and Hooks on steroids.
- The Routing Component gets passed a URL and returns an array of info about the route. If it finds a good controller match, it gets executed. Drupal has around 1,000 possible routes, so Drupal's implementation won't be quite this simple. (For Drupal's needs, this has also been extended with a new standalone mime-type negotiation library.)
Drupal isn't just using Symfony's libraries: the integration has resulted in many fixes and new functionality for Symfony in return. The more we see different and disparate projects using these components in unique ways, the more powerful and robust they'll become. The reaction from the Symfony community? Well, we'll let them speak for themselves:
Drupal 8's trajectory of a first class REST server built on Symfony is very admirable. If they pull it off might even use it #symfony_live— Code In A Box (@codeinabox)
@crell's talk makes me want to hug Drupal. Amazing how deeply they've embraced outside libs. An example for the rest of us #symfony_live— Ryan Weaver (@weaverryan)
not afraid to admit I didn't have much love for Drupal... having said that, Drupal & Symfony looks like a great leap forward #symfony_live— Chris Rickard (@chrisrickard)
On Day Two of Symfony Live, we heard from Ryan Weaver about Composer and how it's becoming so much easier to include libraries from other PHP projects in your own. Fans of other languages have seen similar tools in Node's NPM and Ruby's gem bundler. Composer gives you all the power of a tool like Drush make, combined with the dependency management of the libraries module in an easy-to-use tool with its own great CLI interface. Composer is designed to work within a wide variety of PHP frameworks and to bridge between these libraries. You can try Composer with handy Drush integration in Drupal 8 using the composer module. Efforts are also underway to include Composer in Drupal 8 as an autoloader and library management tool.The other sessions from the conference were more Symfony-specific, and surfaced many examples of other community-developed components. After hearing about Composer, it didn't feel like I was digesting information I'd never use: instead, I left with the feeling that I would be able to use many of these components in my own Drupal 8 site. As an open-source developer, you've already come to the conclusion that code reuse is a good thing — but often all that great code is tied up in another project with a lot of dependencies that aren't easily refactored away. Much respect is due to Symfony's developers for designing their framework in such a cleanly reusable way. This, combined with the hard work and advocacy of Larry Garfield and others, is what brings us the awesome change we're seeing with Symfony in Drupal 8. The lesson for us mere mortals is to write our code as generically as possible for the current situation; to think in terms of reusable libraries and modules rather than one-time fixes. The next time you're sitting down to write a custom module, don't stop your search for inspiration at Drupal.org. There are thousands of lines of open-source PHP code you can use today. Search through components and libraries for examples that might inform your own decisions, or libraries that get you 90% of the way to your solution. A sign of maturity in any developer (or open-source project, for that matter) is recognizing that other people are also capable of writing great code. At some point, every developer realizes repetitive problems are already solved, leaving time that can be spent building features and pushing the bounds of what's possible rather than reinventing the wheel. This approach may take longer than the more common "hack it until I have to touch it again" approach. But whether it's for Drupal, your own project, or a client's project, you end up in the best position to develop new functionality if your existing codebase is solid and developed collaboratively. After all, there's a good chance that the bug someone else found yesterday will be the bug you find tomorrow.