How to Migrate from Zend Expressive Version 1 to 2 with Command-Line Tooling Support

How to Migrate from Zend Expressive Version 1 to 2 with Command-Line Tooling Support

If you need to migrate Zend Expressive applications from version one to two, don’t do everything by hand! Save yourself time, and make use of Zend Expressive Tooling.

This was originally published on Master Zend Framework, but has been migrated here.

How to Migrate from Zend Expressive Version 1 to 2 with Command-Line Tooling Support

In part one of this series, we started learning about the tooling support available for Zend Expressive, provided by Zend Expressive Tooling There, we learned how we could use the package to create, register, and deregister middleware, and scaffold new modules. However, that’s only half of what the package can do.

Here, in part two, let’s learn about the other half, which removes some of the heavy lifting required when migrating Zend Expressive applications from version one to two.

What are the Differences Between Version One and Two?

Zend Expressive 2.0 was back in March of this year, and there’s a number of changes between it and version one of Zend Expressive. These include:

  • Support for PSR-11
  • http-interop/http-middleware support
  • Programmatic pipelines
  • Simplified, improved error handling
  • Modular applications
  • Extensible routing and dispatch middleware
  • More development tooling

Collectively, these changes represent a way of creating more mature — and more straightforward — applications when developing with Zend Expressive.

The core contributors are confident that you shouldn’t experience many if any, problems when upgrading. However, it’s still best to refer to the migration documentation if you’re unsure of what the changes are, and what to expect.

Migration Support

The migration functionality includes the following three commands:

  • migrate:error-middleware-scanner Scan for legacy error middleware or error middleware invocation.
  • migrate:original-messages Migrate getOriginal*() calls to request attributes.
  • migrate:pipeline Generate a programmatic pipeline and routes from configuration.

These three, while not doing everything, do help with a lot of the fiddly work of migrating an existing application. Let’s start with migrate:pipeline.

Migrating to Programmatic Pipelines

This one I used recently during the development of the application behind my upcoming Zend Expressive Essentials book and course.

To set the scene, in the early part of the book, I step through creating an Expressive application by hand, one that uses configuration-driven pipelines and routes. I do this for several reasons;

  1. I’m more familiar with that development style
  2. I wanted to show the flexibility and versatility of the framework

However, in the latter part of the book, I step through using the Skeleton Installer to re-build the application, which, by default, creates applications using programmatic pipelines. Given the difference in style of the two applications, I didn’t want to refactor the routes manually and decided to make use of the command to do it for me. After I was done, all I then had to do was to copy over the relevant configuration.

Let’s see how to do so. Assuming that you worked through the previous tutorial, from the terminal in the root of your project, run the command:

./vendor/bin/expressive migrate:pipeline

This results in the following output:

Generating a programmatic pipeline for an existing Expressive application...
- Created /config/autoload/, enabling programmatic pipelines
- Created /config/pipeline.php, defining the pipeline
- Created /config/routes.php, defining the routes
- Updated /public/index.php to include /config/pipeline.php and /config/routes.php before running the application

From looking through the files listed in the command’s output, you can see that it:

  • Generates a configuration to register the required services (or dependencies) in the DI container (/config/autoload/
  • Enables the required programmatic-pipeline middleware (/config/pipeline.php)
  • Creates a programmatic pipeline representation of your existing configuration driven setup (/config/routes.php)
  • Enables the new functionality (/public/index.php)

With that done, you can remove your existing, configuration-driven pipeline configuration.

Scanning for Deprecated Error Middleware

Next, let’s scan for deprecated error middleware, using the command:

./vendor/bin/expressive migrate:error-middleware-scanner

By default, this scans src/ for classes that either implement Zend\Stratigility\ErrorMiddlewareInterface, or which implement __invoke() using that signature. Any that are discovered are reported to the console. From there, you’re able to begin the migration by hand. If you want to scan another directory, then you can use the -d or --dir switches to specify the directory to scan.

The reason why Zend\Stratigility\ErrorMiddlewareInterface needs to be removed is that Expressive 2.0 is based on Stratigility 2.0. And in Stratigility 2.0 the error handling functionality changed quite markedly.

Scanning for Legacy Request and Response Methods

Finally, let’s scan for legacy request and response methods, using the command:

./vendor/bin/expressive migrate:original-messages

This command helps migrate an Expressive 1.0 application by removing any calls to legacy request and response methods. To do this, it scans, by default, all PHP files under the src/ directory for any calls to:

  • getOriginalRequest()
  • getOriginalUri()
  • getOriginalResponse()

Calls to getOriginalResponse(), are refactored to getAttribute('originalRequest', {requestVariable}). Calls to getOriginalUri() are refactored to getAttribute('originalUri', {requestVariable}->getUri()). And if any getOriginalResponse() calls are detected, the script shows a warning which indicates the file(s) and details how to correct these manually.

If you want to scan another directory, then you can use the -s or --src switches to specify the directory to scan.

Note: To step through the migration process if either error-middleware-scanner or original-messages finds any results, check out the official migration documentation, which provides excellent coverage of the process.

In Conclusion

In this tutorial, we’ve seen how to use the other half of the functionality which Zend Expressive Tooling provides, helping manage some of the heavy lifting involved in migrating applications from version one to two.

While the commands don’t do all the work for us, it does do a good amount of it; it also identifies the areas where refactoring needs to be performed by hand because it can’t be done automatically.

If you’re anticipating having to migrate your existing application(s), or are in the middle of doing so, definitely give the commands a try and see where they can save you effort and time.

If you’re already using them, what’s your experience been? I’d love it if you shared it with the community in the comments.

You might also be interested in these tutorials too...

Wed, May 31, 2017

Create Modules and Middleware with Command-Line Tooling Support

For the longest time, Zend Framework hasn’t had the strongest support for command-line tooling and scaffolding. However, in recent times, that’s all changed. Come find out how to use Expressive’s new tooling support to create modules and middleware rapidly.

Tue, Jun 26, 2018

What Are Delegator Factories and Why You Should Use Them

Ever wanted to dynamically expand the functionality of an object which you retrieve from your dependency injection container, based on different needs, yet without creating messy, hard to maintain configurations? Then you’re going to want to know about a powerful new technique - called Delegator Factories.

Tue, Aug 9, 2016

The 3-Step Guide to Downloading Files in Zend Expressive

A common requirement of web-based applications is to upload and download files. But, out of the box, there’s no simple way to download them in Zend Expressive. This tutorial shows you how - step-by-step.

Tue, Jul 25, 2017

How to Create a Zend Expressive Module

Ever thought of creating a Zend Expressive module, one that either scratches an itch or allows you to use a set of related functionality across multiple Zend Expressive projects? I created one recently and share how I did it with you in this three-part series.

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