Blog: Propel2: What, Why, When?

The Propel Team – 09 July 2012

A few weeks ago, I talked about Propel2 for the first time at Symfony Live 2012. That was the first official announcement, and this blog post will sum up what I said.

Basically, Propel2 is a huge refactoring of Propel 1.6. We didn't change the main design pattern (ActiveRecord), we didn't change Propel's philosophy. So people who already know Propel 1.6 will be able to use Propel2 without any problems. No need to learn a new tool. Propel2 is still easy to use, extensible and powerful.

As you may know, Propel is more than 7 years old, is well documented, and has a large community. That's important because you should always consider documentation, and community when you have to make a choice between different technologies.

During my talk, I asked attendees whether Propel was an ActiveRecord implementation, or not. They all said "yes", but it's wrong. Propel implements two main design patterns: Data Table Gateway, and Data Row Gateway. It's really important because that means we have two different APIs that address two different concerns.

The first API is called ActiveRecord API. I know, it's a bit confusing because I said Propel was not an ActiveRecord implementation. But, the Data Row Gateway pattern becomes ActiveRecord if you add business logic. This API is your model object. It's a smart object that owns data, and knows how to persist its own state.

The second API is called ActiveQuery API. This is a fully object oriented API so that you don't write SQL. This API is really fluent, and intuitive. An ORM abstracts your database layer. So don't expect PHP methods like select(), from(), where(). They don't make sense in an object oriented world. Propel provides filters, and termination methods.

If you don't know Propel yet, you're probably wondering how to get these APIs. Propel relies on code generation. You start by describing your model layer in XML, and then ask Propel to generate SQL, and PHP classes with optimized code. This is not a dumb generation, and you can hook into this process. The best example is the use of behaviors.

A behavior addresses a need. It's a reusable extension for your model objects. Propel has a lot of built-in behaviors, and thanks to third-party contributions, there are tons of useful behaviors you can use to enhance your model in a snap.

Last but not least thing, Propel is blazingly fast, and doesn't require any caching layer. Thanks to an optimized DBAL at runtime, and extreme code generation, Propel is fast by design. Propel is able to generate some SQL statements at buildtime so that it skips this step at runtime - that's what I call "extreme code generation".

All of these features are in Propel2 because we didn't rewrite the whole project. We just improved it, and gave it some love. Propel2 now requires PHP 5.3.2 (and maybe 5.3.3 soon). That allows us to use interesting features whitout "hacks".

Propel2 is also a voting member project in the Framework Interoperability Group. That's why we decided to adopt PSR-0 (Propel2 is fully namespaced), PSR-1, and PSR-2. The whole codebase has been reviewed, and improved a lot. Thanks to static analysis, we removed a lot of dead code, and reduced possible issues. In the same time, we added more tests, and we made the test suite compatible with different database vendors.

All of these changes allowed us to do more. We adopted five Symfony2 components: Console, Filesystem, Finder, Validator, and Yaml. That was probably the best decision we made. We removed the strong Phing dependency which was a pain to maintain. The Phing "console" was not really user friendly, and we are now happy to play with the Symfony2 Console. All of the Symfony2 components are heavily unit tested, so we started building Propel2 on strong foundations. We did the same for the logging. Propel2 relies on Monolog for that part.

To manage all these new components, we trusted Composer since the beginning. That was the right decision because Composer is more and more adopted by the PHP community. Propel2 comes with a Service Container as well, but unlike Symfony2, we don't use configuration files. It's a pre-compiled container.

Another huge change is the new adapter layer. An adapter interacts with the database at runtime. In Propel 1.6, adapters are tied to PDO which, at first glance, is not a bad idea, but in reality, it's not really flexible. Propel2 comes with a new abstraction layer which is fully extensible (you can write a oci8 adapter if you want), and a default PDO implementation.

The last great improvement in Propel2 is the support of traits. Propel2 will be able to generate traits, to get rid of the classic inheritance and the base class, so that you will be able to use POPO (or domain objects) with Propel2!

Regarding the roadmap, we still have to remove the PEER classes. Once it's done, a first alpha version will be released, probably in August, or September.

That's all folks, and thanks to all Propel contributors!