Save Time Instantiating Mezzio Handlers With the Reflection-based Abstract Factory

Save Time Instantiating Mezzio Handlers With the Reflection-based Abstract Factory

If you’re creating handlers in a Mezzio application and don’t want to spend time building and maintaining custom factories to instantiate them (or other classes), you need to know about the Reflection Factory.

Recently, as you may know, I’ve been building a small user authentication module for an upcoming tutorial for a European magazine. As part of developing the application, I followed my standard approach of using Mezzio’s Command Line Tooling to quickly bootstrap handlers and middleware, such as by running the following command.

composer mezzio mezzio:handler:create "App\Handler\ForgotPasswordHandler"

If you’re not familiar with Mezzio’s command line tooling, the above command generates a PSR-15 Handler class and a factory to instantiate it, registers the handler with the application’s DI Container, and creates a view template for it.

Using the command greatly simplifies Handler creation, as it avoids a large number of potential mistakes and bugs that may creep in when creating them manually. Moreover, you know that the files will be created in a consistent manner. However, while the command brings a lot of efficiency to Handler creation, depending on your use case, it may create more work than necessary.

This might seem like a strange thing to say, given my support for the command, but hear me out. Perhaps you’re creating a Handler, and it’s rapidly evolving as the needs themselves evolve. For example, you might be building a Handler that performs user authentication, retrieves content from a social media service such as LinkedIn or Twitter, or provides some other service that requires an ever-growing number of constructor parameters.

In this case, as you iteratively refactor the Handler class you also have to iterate on the Handler’s factory. Otherwise, an exception will be thrown when attempting to retrieve the service from the DI container or when attempting to use it. Yes, it’d be great to have requirements mapped out clearly and concretely ahead of time. But that’s not always practical nor possible.

So, what about iteratively refactoring the handler as the needs of the project evolve without needing to keep refactoring the handler’s factory class? Better yet, why not skip creating a custom factory altogether?

At first blush, this might seem like a ludicrous thing to say, no? After all, if there’s no factory for the handler, how can it be instantiated? Fair point.

However, if you revisit what I said, I only said skip creating a custom factory. You still need a factory to retrieve the constructor parameters so that the class can be instantiated. But that doesn’t mean that you have to create said factory yourself.

If your Mezzio application is using laminas-servicemanager as it’s DI Container, you’re in luck. Enter the Reflection-based Abstract Factory (or Reflection Factory). This class uses PHP’s Reflection API to introspect which constructor parameters are required and, where possible, retrieve them from the DI Container (if they’ve been registered).

Worried about performance?

Given that the class uses reflection, you may have concerns about application performance, as the Reflection API does have a performance overhead. It’s a fair concern for a production application, but during development, I’d suggest not.

Remember, the recommendation to use the Reflection-based Abstract Factory is only during initial development. That way your energies can stay on the Handler’s logic not instantiating it.

Then, after the Handler’s state becomes stable enough, you can use a more performant factory, such as a custom one or perhaps the Config Abstract Factory.

Some things to bear in mind about the Reflection Factory

That said, there are a few things to bear in mind when using it:

  • If a class' constructor has a parameter named $config type-hinted as an array, it will receive the application’s "config" service (i.e., the merged configuration).

  • An empty array will be injected for parameters type-hinted as an array but not named $config.

  • Scalar parameters will result in the factory raising an exception, unless a default value is present. If it is, however, that value will be used.

  • If a service cannot be found for a given typehint, the factory will raise an exception detailing this.

How do you use it?

Using the Reflection-based Abstract Factory instead of a custom factory requires two steps:

  1. Add the factory in the DI Container’s list of abstract factories.

  2. When registering the handler with the DI container, use the Reflection Factory to instantiate the handler.

Here’s an example of how to do so. In the relevant module’s ConfigProvider.php file, add the following configuration to the array returned from the getDependencies() method, as below.

'abstract_factories' => [

Then, add your Handler in the factories element in the array returned from the getDependencies() method, and set the ReflectionBasedAbstractFactory to instantiate it, as below.

'factories'  => [
    Handler\ForgotPasswordHandler::class => ReflectionBasedAbstractFactory::class,

That’s how to save time instantiating Mezzio Handlers by using the Reflection-based Abstract Factory

If you’re rapidly prototyping application, I highly recommend using the Reflection-based Abstract Factory so that you can concentrate on the Handler’s logic and not worry about instantiation, until the code’s semi-stable.

I’d love to know what you think in the comments.

mezzio essentials banner small

You might also be interested in...

Want more tutorials like this?

If so, enter your email address in the field below and click subscribe.

You can unsubscribe at any time by clicking the link in the footer of the emails you'll receive. Here's my privacy policy, if you'd like to know more. I use Mailchimp to send emails. You can learn more about their privacy practices here.

Join the discussion

comments powered by Disqus