If you inject a container into your class, you are using Service Locator, not Dependency Injection

A while ago I tweeted

ContainerAware is the new Singleton.

While many people agreed by retweeting and faving. I feel the need to elaborate some more on this statement and safe the explaination for the future.

TL;DR: No class of your application (except for factories) should know about the Dependency Injection Container (DIC).

The ContainerAware interface (actually ContainerAwareInterface, ContainerAware is a basic implementation of it) is part of the Symfony2 API, but a similar concept is known from many other frameworks and many applications rely on it. It defines only the one method setContainer(), which allows to inject the DIC into into an object so that it can directly retrieve services from it.

I wouldn’t call it “the new Singleton”, I’d call it “Service Location.” If you use a dependency injection container inside your class to bring dependencies into the object, you are using Service Locator, not Dependency Injection. Solar used SL, but when we started Aura (a collection of truly decoupled library packages, each with no dependencies) we switched over to DI proper. Real DI has been a huge win.

Via ContainerAware Considered Harmful – Qafoo GmbH – passion for software quality.

Aura for PHP 5.3+, aka Solar 2.0

Measuring from the first Subversion commit, Solar was 6 years old on 14 Feb 2011. The project has come a long way since then, and has evolved from a collection of library classes with some content domain models, to a general purpose framework.

Moore’s Law tells us computer power doubles about every 18 months; it’s how we measure generations for computers. 6 years is 4 generations, which makes Solar the equivalent of an 80 to 100 year old person. Just like with a mature person, there is a great deal of knowledge and craft embedded in Solar, but it also still shows its roots and carries the weight of decisions from early in its life.

With all that in mind, it’s time to start working on Solar version two, using the formal namespaces and other features of PHP 5.3. There are some other very significant changes on the way as well.

The first change is the name of the project. Even though Solar (the PHP 5 framework) came first, the name is too easy to confuse with Apache Solr (the search system). So, after some discussion with others, Solar v2 will be called Aura.

The second change is in the fundamental organization of the project. Solar became a full-stack framework very quickly, with all classes descending from a base class, and using and a service locator to manage dependencies. By comparison, Aura is a collection of independent library packages; it uses no base classes, and is oriented toward a dependency injection container proper to manage dependencies. Aura also has an additional “system” package that assembles those libraries into a cohesive framework (the way Solar is now). That way, those who want to use only one or two Aura packages can do so, and developers who want a full framework can also get what they need.

There are lots of other significant changes, and I expect I’ll write about those in the future. Until then, if the project sounds interesting, you can find the Github repos at https://github.com/auraphp. Aura also has a mailing list at https://groups.google.com/group/auraphp, and you can join the IRC room on Freenode at #auraphp.

Meanwhile, Solar will keep getting as much love and attention as it has over the past year or so. But I do expect, eventually, that we will be able to extract all the best Solar behaviors to Aura. Solar won’t ever really go away (software projects almost never do), but I expect it will be eclipsed by Aura at some point in the future.

You can see what Aura looks like by examining the various Aura packages already in place:

  • Aura.Autoload, an autoloader package
  • Aura.Di, a dependency injection container,
  • Aura.Router, a web routing system,
  • Aura.Signal, a signal slots / event handler implementation,
  • Aura.Cli, a collection of command-line tools, and
  • the system package that provides a framework around the libraries

Take a look around; I hope PHP 5.3+ developers who want independent library packages will like what they see.

Solar 1.1.1 Stable Released

On Thursday, I released version 1.1.0 of the Solar Framework for PHP. Due to a small but critical bug in the PostgreSQL adapter, I released version 1.1.1 with the necessary fix earlier today. Change notes are here for 1.1.0, and here for 1.1.1.

The single biggest new feature in this release of Solar is a Markdown plugin set for DocBook, along with a new make-docbook command to convertAPI documentation to DocBook files. Previously, the Solar API documentation was wiki-like; now, we take the Markdown-based comments in the codebase and convert them to DocBook, and render the DocBook files in to HTML using PhD. (Incidentally, I tried rendering with xsltproc; after three hours, the processing was less than one-third complete. With PhD, rendering takes under five minutes for the entire API documentation set.)

Also, the make-model command now recognizes a star at the end of the model name, indicating it should make one model class set for each table in the database. For example, this will make one model class from the table "foo_bar" …

./script/solar make-model Vendor_Model_FooBar

… but this will make a Vendor_Model class for each table in the database:

./script/solar make-model Vendor_Model_*

That kind of thing is helpful when getting started with an existing set of tables, or when you’re updating your models after schema changes.

Other highlights include a series of small fixes, better CLI output in non-TTY environments, improved automation of CSRF form elements.

Finally, we’ve added a new manual chapter on user authentication, roles, and access control. Find out how, with some config settings, you can instantiate a single object and let it automatically handle user login/logout, role discovery, and access permissions for you! And if you want more direct control over the process, browse on over to these blog entries from CoolGoose:

If you haven’t tried Solar yet, maybe now is the time: run through the Getting Started documentation and see how you like it!

(Cross-posted from the Solar blog.)

Solar 1.0.1 Stable Released

I just released version 1.0.1 (stable) of the Solar Framework for PHP 5. You can get it from the usual places. The change notes are here.

The most significant change is a bugfix to eager fetches in the model system. When eager conditions are present, and no join type is specified, eager fetches will use an ‘inner’ join by default. This means that the eager conditions now have the proper effect when using count_pages.

(Cross-posted from the Solar blog.)

Solar 1.0.0 Stable Released

Yesterday, I announced the release of the 1.0.0 stable version of the Solar Framework for PHP on our mailing list. (I tagged the release four days ago on Monday, but wanted to time the announcement to go along with my Solar presentation at ConFoo.)

You can see the change notes here. The highlights are:

  • Added automatic cross-site request forgery (CSRF) protections in various layers of the system.
  • Added support for named actions (aka "named routes") in the front-controller rewrite logic; this is the "bi-directional" routing that some have asked for.
  • Optimized queries for Model::countPages() and the native-by select strategy, so that unnecessary joins against related models are not used when counting the number of pages for the native model results.

The next major steps are to revise and extend the narrative documentation, and of course fix bugs and add features as needed.

Slashdot appears to have gotten to the mailing list announcement before I blogged the release. (The commenters there show the usual range of insight, depth, wisdom, and experience. 😉 The Solar site itself, deployed on a 512M SliceHost VPS instance, appears to be handling the load. However, my WordPress blog on a separate 512M instance is getting … a bit … … slow. Guess it’s time to add wp-super-cache.

This stable release is the culmination of about five years of development effort, with important contributions from several others in the PHP community. My many thanks to everyone who helped make this release, and all the previous releases, better than I could have made it on my own.

(Cross-posted from the Solar blog.)

Solar 1.0.0beta5 Released

This past Friday, I released verion 1.0.0beta5 of the Solar Framework for PHP. You can read the change notes here.

Overall, most of the work was related to the form helpers and making them even more flexible than they were previously. We’ve also added a new manual chapter on working with models and forms.

It is super-easy to build forms out of model records in Solar. In the controller, once you have a record object, call its newForm() method to get a Solar_Form object. In the view, pass that form object to the form view helper and add a submit-process button:

echo $this->form()

Those four lines of code will build a complete form for you based on the model record, including top-level feedback and individual element invaldation messages.

The form helper is smart enough to recognize the column types and validation filters on the model record, and will use the appropriate input types accordingly. For example, booleans get checkboxes, date fields get a series of month/day/year options, and columns using validateInList or validateInKeys become selects.

You can also further customize the form presentation using the fieldset and grouping methods on the form helper. Alternatively, you can the individual form element helpers to build forms by hand.

These features have been present in Solar for years.

Finally, and I’m not making promises, but I think this is the last or next-to-last beta release. I have some tickets about query optimization from the models that I want to complete. Once those are done, I expect to make Solar’s first official stable release.

(Cross-posted from the Solar blog at http://solarphp.com/blog/read/63-solar-100beta5-released.)

Running The Symfony 2 Benchmarks

Fabien Potencier released Symfony 2.0.0alpha1 last week, along with some benchmarks showing its performance. I am glad to see that Fabien used my benchmarking system and methodology, and am happy to see that he is paying attention to the performance of his framework. I take this as an acceptance on his part that my methodology is legitimate and valid, and that it has value when comparing framework responsiveness.

However, in attempting to reproduce the published Symfony 2 benchmarking results, I found Fabien’s reporting to be inaccurate (or at least incomplete). Read on for a very, very long post detailing my attempt to replicate his results for the “hello world” basic framework overhead comparison, and my conclusions.

For the impatient, here are my conclusions in advance:

  1. Fabien’s benchmark report, as shown at http://symfony-reloaded.org/fast, is inaccurate for the setup he describes. Lithium and Flow3 do not work in Fabien’s benchmark codebase at Github. Also, Symfony 2 is faster than Solar beta 3 by 5%, not 20%, on a “c1.xlarge” instance; to get a relative difference like Fabien describes, one has to use an “m1.large” instance. (It is entirely possible that the process Fabien used for benchmarking is incompletely described, and that the codebase is not fully updated, thus contributing to this disparity in results.)

  2. We should use Siege 2.69, not 2.66, for more accurate benchmarking of baseline responsiveness. If we notice that HTML is slower than PHP, it’s a sign that something is wrong.

  3. Symfony 2 preloads its foundation and application classes, something no other framework does in the benchmarked code. When we treat Solar and Symfony 2 the same way, by preloading the foundation classes for each, we find that Solar is roughly 28% faster than Symfony 2.

Continue reading