What is the Dependency Injection Container (DIC)?

If you’re coding for the web, you almost certainly have encountered frameworks that make use of the Dependency Injection Container. Incredibly useful – but what is it?

In the most simplistic way – it’s just a great big bag of stuff. That’s it. There’s nothing magical about the container, it’s simply an object that stores references to other objects. Combined with a liberal use of Interfaces, this allows for a high level of abstraction and therefore also aids in unit testing smaller code parts.

For example, if you’re injecting the entire DIC into a component, you are metaphorically handing that component a great big bag of stuff and saying “here’s what we have to work with. Ask for it by name.” The component may then access the container and all configured dependencies.

You may well now be saying “well that sounds a bit like code soup” – and you’d be right. Normally, you’d only inject the dependencies that a component requires (and not the whole bag). The major frameworks (e.g. Laravel, Symfony, Zend) feature Dependency Injection Containers and an associated service locator and dependency manager. These are no longer simply “great big bags of stuff“, but true DI systems that allow for a high level of abstraction.

For a super simple Dependency Injection Container, see Pimple (by Sensio Labs). This is a great place to get started with understanding how a system will utilise a DIC. It is super simple, and forces you to understand how things are bootstrapped and provided for your system.

For more detailed information on dependency injection, see these links:

Features image (with modifications):
Coffee Bag W” by DaveBleasdale. Licensed under CC BY 2.0

Pink Ribbon Breakfast

I don’t normally plug work that I do in my daily grind, but this one is for super-great cause. Instead of our usual advertising selves, we’re using our powers for good and completely upgrading the National Breast Cancer Foundation‘s Pink Ribbon Breakfast site. Their goal is to have 0 deaths by 2030, which is a pretty nice goal all-round.

We built the site using Zend Framework, CSS3, and a healthy dose of jQuery-inspired Javascript.

Jump over to the site and check out our relatively-quiet first phase launch while we get ready for the donation-crazy second phase. And be sure to visit the donate link if you know someone with breasts.

Using a single controller in Zend Framework

Are you using Zend? Do you have only a core controller and don’t need extraneous URL parameters? Try this.

Most of the time, I am using Zend Framework to its (mostly) full capacity. Models, Controllers, View Helpers – the whole box-and-dice. However, there has been several occasions where I’ve only needed a single controller serving up mostly static pages, or pages leveraging an external service.

The biggest problem that arises in this case when using the default Zend Router, is that action names are treated as controller names. I don’t know about you, but I personally hate seeing http://example.com/index/my-action when what I actually want to see is http://example.com/my-action.

Here’s a nice way to completely tidy up all your actions, serving them from a single controller. (I use a Bootstrap file to initialise my application):

This basically says that my first parameter is always going to be an action name, and everything else is to be parsed as normal. I set request defaults in the array. In this case, the default controller is “index”. This allows everything to be passed straight through to my IndexController.

Addtionally, if you are using modules and want to retain routing for these also (for example, a one-controller site with an admin module), you can add this route rule to your system:

This says that anything starting with “admin” needs to be routed to the admin module, and the rest of the URL is to be parsed as normal.

That’s it! This will allow you to route all requests to a single controller for the front-end, and still maintain a complete module for the administration on the back-end.

Hopefully this cleared up some things for others, as I found the Zend Framework documentation to be quite dismal.

Using memcache and Zend_Cache

Probably one of the more useful things you can do with memcache is drop it into Zend Framework. Here’s how I did that.

Following on from the previous post, here is an example of how you can set up memcache to serve as a cache for your Zend project.

I like to use the method style of bootstrapping my application, so here’s the function that builds the cache for me.

Originally, I was getting the “Memcache::addServer function expects at most 6 parameters, 8 given” warning. To force Zend to play nice with memcache (and send the right parameter count), you need to make sure you have the compatibility option set to true in the backend options array.

Here’s an example on how to use:

Hope this helps in getting started with Zend_Cache (even on a technology as old as memcache).

Return JSON data with Zend Framework

Getting Zend to return JSON data can be tricky at times. The JSON helper likes to send the ‘official’ JSON header (application/json), and most browsers are treating that as a download link, resulting in no data to the client and an unfortunate download box.

To bypass this default behaviour, you’ll need to tell the controller how to serve your JSON data:

The key part of this stub is the exit; line. It prevents the view renderer from sending anything, keeping your JSON data intact. Note: json_encode and json_decode only works from PHP version 5.2.1

To output all of your view’s variables in this way, replace $some_var; with:

Hopefully this saved someone a headache or two when dealing with Zend’s puzzling JSON implementation.

Quick Zend Cache Setup

Here’s a quick solution to get a cache running on your Zend Framework install. It’s very simple and should provide a good solution for most small-scale sites.

You can put this code inside of your bootstrap file. I like to use the method style for invoking the bootstrapper.

What this snippet does is initialise two related caches – a core cache, and a page cache. The core cache (in this instance) is attached to our database table abstract class, which allows results to be stored as serialized strings. The page cache is invoked whenever template output is due to occur, and saves pre-rendered HTML for immediate output.

You can find all the documentation for tweaking your cache settings in the Zend_Cache documention.

Zend, SSL, and mod_rewrite

I had a Zend project in which we had to use the Apache module mod_rewrite to “toggle” our secure connection depending on what pages the user landed on. The requirements were something like:

  • User visits any administration or account pages, and SSL is off, switch it on
  • User visits a page that is not an administration or account page, and SSL is on switch it off

As it was a Zend MVC project, we also had a rewrite rule that routed everything to /index.php in the document root.

This is Zend’s recommended .htaccess rule for routing:

For the uninitiated, the block says: If the request is a valid file that exists, or it is a directory, don’t rewrite the URL, otherwise, rewrite the whole string to read “index.php.” The framework will generally just read the query string server variable and go from there.

So on to my additions for toggling SSL.

The above code checks the secure protocol, and then checks the requested path (in this case, /admin or /account). In finding that, it toggles the SSL accordingly.

Here’s the problem: because the two toggling rules only work if triggered as a redirect, the server’s request URL is rewritten twice, meaning that any “toggling” will result in a flat redirect to /index.php, breaking the application.

After hours of testing, rewriting, and Google-fu, I came up with this fix:

becomes:

This means that the request is reattached to the end of the query all the time. This is hidden from the user (i.e. no ugly index.php/admin/login/ or what-have-you), and is successfully passed onto Zend to trigger the appropriate dispatcher. This works for any number of redirects.

Hope this saves someone else hours of trial-and-error.