Migration to Laminas

Migration to Laminas

Laminas and its subprojects are an open source continuation of Zend Framework and its subprojects, and are the official fork of the project now that it has been archived and abandoned.

For purposes of this document, when we refer to "Zend Framework", we mean any package originally provided by the Zend Framework project or its subprojects, including those provided by Apigility or Expressive.

You can migrate:

  • Individual projects or applications that depend on Zend Framework, or have dependencies on components that depend on Zend Framework, where the release is in the version 2 or version 3 series.
  • Individual projects or applications built on Apigility, all stable versions.
  • Individual projects or applications built on Expressive or using Expressive components, all stable versions.
  • Libraries that depend on Zend Framework components, versions 2 and later, or created after Zend Framework 2.0.0 was originally released.

1. Preparation

Ensure you have an up-to-date Composer

Due to features of Composer our dependency plugin uses, we require Composer 1.7.0 and up. If you're unsure what version you are on, run composer --version. If you are on an older version, run composer self-update.

(We assume you use Composer to install Zend Framework, as it is the only supported mechanism currently.)

Make sure your code is under version control

The migration tool changes source code, updates templates, modifies your composer.json and removes your composer.lock and vendor/ subdirectory, among other things. If you want to be able to roll back in the case of a problem, please make certain your code is under version control!

We recommend Git. If your application is not currently under version control, install git, and then:

$ cd path/to/your/application
$ git init .
$ echo "vendor/" > .gitignore
$ git add .
$ git commit -m 'Initial import'

You will then be able to see what changes you introduce.

2. Install laminas-migration

There are two ways to install the tool:

  1. Via a global composer requirement (recommended)
  2. Via cloning

Do NOT install locally!

While the laminas/laminas-migration package is a Composer package, it cannot be used as a local requirement in your application. Part of its operation is to remove the vendor/ subdirectory, which means it removes itself during operation. As classes are loaded dynamically, as needed, this can cause the code to error during later operations when classes are unavailable, leading to a failed migration.

Via a global composer requirement

Composer allows you to require packages in a global context as well. If you choose this option, you will run:

$ composer global require laminas/laminas-migration

It is up to you to ensure that the vendor/bin/ subdirectory of your global Composer installation is in your environment $PATH. You can locate the global context directory using:

$ composer global config home

Adding to the PATH

The mechanism for adding to your environment $PATH variable depends on your operating system.

For Linux, Mac, and other *nix variants, you can do so by adding a line like the following at the end of your profile configuration file (e.g., $HOME/.bashrc, $HOME/.zshrc, $HOME/.profile, etc.):

    export PATH={path to add}:$PATH

For Windows, the situation is a bit more involved; this HOWTO provides a good tutorial on the subject.

Via cloning

Clone the repository somewhere:

$ git clone https://github.com/laminas/laminas-migration.git

Install dependencies:

$ cd laminas-migration
$ composer install

From there, either add the bin/ directory to your $PATH (see the note on adding to the PATH, above), symlink the bin/laminas-migration script to a directory in your $PATH, or create an alias to the bin/laminas-migration script using your shell:

# Adding to PATH:
$ export PATH=/path/to/laminas-migration/bin:$PATH
# Symlinking to a directory in your PATH:
$ cd $HOME/bin && ln -s /path/to/laminas-migration/bin/laminas-migration .
# creating an alias:
$ alias laminas-migration=/path/to/laminas-migration/bin/laminas-migration

3. Run the migration command

Once you have installed the laminas-migration tooling, enter a project you wish to migrate, and run the following:

$ laminas-migration migrate

You may want to use the --exclude or -e option one or more times for directories to exclude from the rewrite, or the --filter or -f option one or more times to provide regular expressions of which files to include in the rewrite.
This is especially useful if you have folders with large amounts of files (e.g. images or static assets). Excluding such directories can drastically improve the execution time.

As an example, to exclude the data/ and public/images subdirectories, you could run:

$ laminas-migration migrate -e data -e public/images

Migrating the conservative way

In case that you have strict upgrade paths and dont want to upgrade any package to its latest version, you might want to use --keep-locked-versions which ensures that any package from composer.lock will be added with the currently installed version to your composer.json.

We encourage you to migrate the non-conservative way to avoid unexpected issues with older versions of the migrated laminas packages.

If you are experiencing issues after the migration with this flag, we cannot offer support as we highly encourage you to upgrade to the latest packages.

$ laminas-migration migrate -e data --keep-locked-versions

For more information on available options, use the command's help function:

$ laminas-migration help migrate

4. Verify changes (optional)

At this point, you can verify that the changes look correct. As an example, if you use git, you could run the following command to determine what has changed:

$ git diff

Things you might want to look for:

  • Renaming of files or classes in your own code that reference ZF components. As an example My\Models\ZendMailTransport might get renamed to My\Models\LaminasMailTransport. Such renames are typically okay, and any references to those classes will be rewritten as well. However, if external code may depend on them, you should verify.
  • Changes to configuration keys. Most of these are made to match changes in the Laminas libraries themselves, but you should check to see if they are specific to your own code.

5. Install dependencies

Once migration is done and you've performed any verification steps you need, install dependencies:

$ composer install

6. Test

Run your unit tests, do end-to-end tests, whatever — but exercise the application in some way.

If anything does not work, determine the specifics, and report either:

  • In the repository of the specific component where you are observing problems.
  • The #laminas-issues channel of the Laminas Slack.

Post migration (optional)

In case the --keep-locked-versions flag was used, you definitely want to diff the composer.json and restore the old package constraints and remove the packages which were not required on project level before migration. After cleaning up the composer.json, you have to update the composer.lock by using the following command:

$ composer update --lock


To summarize the steps to migrate:

$ composer global require laminas/laminas-migration
$ cd some/project
$ laminas-migration migrate # maybe with -e data or -e data/cache
$ composer install