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

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 can use the package to create, register, and deregister middleware, and scaffold new modules. But 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's 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 simpler — 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 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 will present a warning indicating the file(s) and detail 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 like? I'd love it if you would share it with the community in the comments.

About Matthew

Matthew Setter Matthew Setter is a PHP & Zend Framework specialist. If you're in need of a custom software application, need to migrate an existing legacy application, or want to know your current application's GPA - get in touch.