Refactoring legacy PHP

by Enrico Zimuel
Principal Software Engineer @ Elastic

PUG Torino, Feb. 19, 2020

About me

Refactoring legacy applications


Refactoring is the process of changing the structure of code without changing its behavior

Legacy code

Legacy code is source code that relates to a no-longer supported or manufactured operating system or other computer technology
Code that developers are afraid to change


Unit test

Never refactor a production code that does not have unit tests

Tool: PHPUnit


For example, using the following class:

class Foo
    public function __construct(BarInterface $bar)
        $this->bar = $bar;

    public function baz()
        return $this->bar->doSomething(/* ... */);

Mock (2)

use PHPUnit\Framework\TestCase;

class StubTest extends TestCase
    public function testStub()
        $stub = $this->getMockBuilder(BarInterface::class)


        $foo = new Foo($stub);
        $this->assertSame('foo', $foo->baz());


Method Stubs

class Book {}

interface BookRepository {
    function find($id): Book;
    function findAll(): array;
    function add(Book $book): void;
$double = Mockery::mock(BookRepository::class);

$double->allows()->find(123)->andReturns(new Book());
$book = $double->find(123);

Call Expectations

class Temperature
    private $service;

    public function __construct($service)
        $this->service = $service;
    public function average()
        $total = 0;
        for ($i=0; $i<3; $i++) {
            $total += $this->service->readTemp();
        return $total/3;

Call Expectations (2)

class TemperatureTest extends \PHPUnit\Framework\TestCase
    public function tearDown()
    public function testGetsAvgTemperatureFrom3ServiceReadings()
        $service = Mockery::mock('service');
            ->andReturn(10, 12, 14);

        $temperature = new Temperature($service);
        $this->assertEquals(12, $temperature->average());

Test Spies

$spy = \Mockery::spy('MyDependency');
$sut = new MyClass($spy);

// act

// assert

Code coverage

Feature of PHPUnit to measure how much code is covered by the unit test



Many options for legacy code (not PSR-4)

* deprecated, but still useful

Classmap example

    "autoload": {
        "classmap": ["src/", "lib/", "Something.php"]

Tools for refactoring

Some tools

  • PHPCPD, Copy & Paste detector
  • PHPLOC, measuring and analyzing PHP project
  • Rector, reconstructor tool, it does instant upgrades and instant refactoring of your code
  • PHPStan, static analysis tool
  • Phan, static analyzer for PHP
  • Exakat, automated code reviewing engine for PHP



Follow me: @ezimuel

Creative Commons License
This work is licensed under a
Creative Commons Attribution-ShareAlike 3.0 Unported License.
I used reveal.js to make this presentation.