Complete Guide to Refactoring Old Code (Part 2): Migrated An Aging PHP Application | Code&Care

How to Refactor The Legacy Code In Practical Steps

STEP 1: Identifying A Flow And Splitting Monolith Code

STEP 2: Extracting A Reusable Component

STEP 3: Choosing An Architectural Structure For The Flow

STEP 4: Repeat The Cycle

Legacy to Laravel: How to Migrate an Aging PHP App

Step 1: Install a New Laravel App

Step 2: Move the New Laravel App Into the Legacy App

Step 3: Testing the Home Page

public function testExample()
{
// the entry point to the legacy app
$response = $this->get(‘/’);// replace ‘welcome’ with a string on the home page
$response->assertStatus(200)
->assertSee(‘Welcome’);
}

Step 4: PHP Superglobals

Step 5: CSRF Tokens

// within $middlewareGroups below ‘web’
‘legacy’ => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],

// routes/legacy.php
use App\Http\Controllers\LegacyController;Route::any(‘{path}’, LegacyController::class)->where(‘path’, ‘.*’);Lastly, you need to register the legacy route file by editing
app/Providers/RouteServiceProvider.php as follows:// Add the following to the end of the boot() method
Route::middleware(‘legacy’)
->namespace($this->namespace)
->group(base_path(‘routes/legacy.php’));

Step 6: Refactoring the Shim Code

// ItemShim
public static function getFutureItems()
{
// database query
}

// ItemShim
public static function getFutureItems()
{
return Item::future()->get();
}

Step 7: Stopping Execution Early

namespace App\Exceptions; use Exception;

class LegacyExitScript extends Exception
{

}

public function index()
{
try {
ob_start();
require public_path() . ‘/legacy.php’;
$output = ob_get_clean();
} catch (LegacyExitScript $e) {
$output = ob_get_clean();
}return new Response($output);
}

Step 8: Laravel Views

namespace App\Exceptions;use Exception;
use Illuminate\View\View;class LegacyView extends Exception
{
protected $view;public function __construct(View $view)
{
$this->view = $view;
}public function getView()
{
return $this->view;
}
}

public function index()
{
try {
ob_start();
require public_path() . ‘/legacy.php’;
$output = ob_get_clean();
} catch (LegacyExitScript $e) {
$output = ob_get_clean();
} catch (LegacyView $e) {
return $e->getView();
}return new Response($output);
}

function legacy_view($view = null, $data = [], $mergeData = [])
{
throw new App\Http\LegacyView(
view($view, $data, $mergeData)
);
}

Step 9: Generating Database Migrations

Step 10: Helper Method

// Add this to the “autoload” property below “classmap”
“files”: [
“app/helpers/legacy.php”
]

Step 11: Legacy Path Helper

function legacy_path($path = null)
{
return base_path(‘legacy/’ . $path);
}

Step 12: Search and Replace

// find: \$_SESSION\[(.+)] = (.+);
// replace: session([$1 => $2]);// before
$_SESSION[‘foo’] = ‘bar’;// after
session([‘foo’ => ‘bar’]);

The Bottom Line

--

--

Andrew Gromenko is software industry executive with 7years experience in web, mobile, blockchain, and data-driven development in early stage and public company

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store