Migrating from legacy code

VilniusPHP 0x3F

I'll be talking about...

  • The reason to migrate
  • Refactor or rewrite?
  • Failure story about rewrite
  • Success story about refactoring (with a demo)
  • Rewrite reconsidered

Marius Balčytis

Short history of Paysera

  • 2004: company was opened
  • 2006: www.mokejimai.lt launched
  • 2012: started to open e-money accounts
  • 2018: this is current year (duh)

Throwback Thursday!

2004

2004

2006

PHP ecosystem

  • 2004: PHP 5.0
  • 2006: Zend 1
  • 2009: PHP 5.3
  • 2011: Symfony 2
  • 2012: Composer

... in other words

we've migrated stuff

A Few reasons why

to migrate from legacy code

Reason No 1: You don't understand the code

  • Rewrite the code
  • (let's hope) you'll understand it by then
  • ...
  • Profit?
  • (time passes)
  • Go to step No 1

Reason No 2: Because it's "legacy"

Define: what is legacy?

Reason No 2.1: No tests, hard to introduce

Reason No 2.2: No (decent) framework

Reason No 2.3: No dependency management

Reason No 2.4: Code style is not preferred anymore

  • Lots of functions
  • Plain PHP files
  • Includes and requires
  • Unclear dependencies between code parts

Reason No 2.5: Some parts are outdated and hard to maintain

  • Templating engine
  • Basic flow of application
  • Data management
  • etc

Basically - adding features or fixing bugs takes lots of time and effort

Define your reasons why

  • What's really needed?
  • What's the easiest way to get that?
  • Define conventions beforehand to avoid the same situation

To rewrite or to refactor?

Failure with a rewrite

About 2010

First of all - I'm not the only one

What was the plan?

Rewrite some features, make new ones, rewrite the rest of the features and switch

What are the problems?

  • Lots of features
  • No clear requirements, just legacy code
  • Takes more time than expected
  • Old system keeps evolving
  • New system does not get the traffic for testing
  • Really hard to migrate when (if) it's ready

What happened?

  • Old system kept evolving
  • New system did not catch up
  • Switch never came
  • The "new" system became the legacy one

Main lessons learned

  • Have detailed migration plan in mind
  • Do not use same DB from different code bases
  • Feature freeze is needed for a long time to rewrite
  • Never ever name something "new"

Success with refactoring

Main idea: "eat" legacy code from inside out

Imagine situation

We have:
Lots of entry points, no autoloader, mostly plain php files and functions (Wordpress)

We want:
Fully functional framework to easily add new functionality (Symfony)

The plan

  • Introduce composer and autoloader
  • Integrate components (like DI)
  • Integrate testing framework
  • Install framework (Symfony)
  • Merge dependency injection containers
  • Merge bootstrapping code
  • Reuse base layouts
  • Move front controllers inside framework
  • Define rules to maintain dependencies

Demo!

https://github.com/mariusbalcytis/wordpress-symfony-migration-demo

Let's reconsider rewrite approach!

Situation

  • We want to enroll new features
  • It's not required to have all existing features at once

Possible strategy

  • Introduce as an alternative solution
  • Let users choose what they want
  • When (if) rewritten system has enough features - migrate users one by one
  • Turn off the legacy system

Let's summarize!

  • Have a migration plan
  • Avoid full rewrites if possible
  • Introduce small good things as it's quite easy
  • Try to improve or release gradually

February 10-11th - free workshop!