En simpel definisjon på legacy applikasjon er en applikasjon du som utvikler har arvet fra andre. Den ble skrevet før din tid.

Sekundære betydninger:

  • Dårlig organisert
  • Vanskelig å forstå
  • Vanskelig å vedlikeholde
  • Vanskelig å endre
  • Fravær av tester
  • Utestbar

Legacy applikasjoner er ofte include-basert. Det vil si at include() brukes for logikkflyt og lasting av klassedefinisjoner:

Her er et eksempel på kode som inkluderer klasser manuelt:

<?php

require 'classes/Page.php';
require 'classes/User.php';
require 'classes/Html.php';            
require 'classes/http/Cookie.php';
require 'classes/helpers/Utils.php';

$page = new Page('show_users');

print $page->render();

En total omskriving er fristende for utviklere men vanligvis uaktuelt. Et godt alternativ er gradvis refaktorering (modernisering).

Forberedelser

Før du går igang må du stappe applikasjonen inn i et versjoneringssystem (git) hvis den ikke allerede er under versjoneringskontroll.

Deretter må du verifisere at du er kapabel til å installere applikasjonen i produksjon.

Sannsynligvis har du behov for et utviklingsmiljø med php 5. Docker passer ypperlig til dette formålet.

Implementer en autolaster

Det første moderniseringssteget er å sette opp automatisk lasting av klasser. Når dette er satt opp trenger du ikke lenger å inkludere en klasse manuelt før du bruker den. I moderne PHP kan vi nå registrere en autolaster som automatisk inkluderer klasser når de brukes. Det fins mange autolastingstrategier men PSR-0 er den mest egnede.

PSR-0 er en bransjeanbefaling for hvordan klasser skal lagres i filer.

I denne standarden blir namespace-separatoren erstattet mappeseparator og understreker i klassenavnet blir også erstattet med mappeseparator. Resultatet blir prefikset med en basemappe og suffikset med .php.

Eksempler på mappinger mellom klassenavn og dens lokasjon:

Page                => src/Page.php
My_Page             => src/My/Page.php
Vikan\Cookie        => src/Vikan/Cookie.php
Vikan\Blog\My_Page  => src/Vikan/Blog/My/Page.php

PSR-0 tillater klasser uten namespaces. De to første eksemplene er klasser som ikke lever i et namespace. Namespaces kom i PHP 5.3 (2009). Eldre kode brukte understrek som konvensjon for å signalisere namespace.

Her er PHP FIG sin eksempel implementasjon:

<?php

function autoload($className)
{
    $className = ltrim($className, '\\');
    $fileName  = '';
    $namespace = '';
    if ($lastNsPos = strrpos($className, '\\')) {
        $namespace = substr($className, 0, $lastNsPos);
        $className = substr($className, $lastNsPos + 1);
        $fileName  = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
    }
    $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';

    require $fileName;
}

PSR-4

PSR-4 er en nyere bransjestandard som deprecater PSR-0.

De to største forskjellene i forhold til PSR-0:

  • Ikke støtte for PEAR-style pseudo-namespaces: Foo_Bar_Baz
  • Forenklet mappestruktur som forkorter mappestrukturene

Med PSR-0/PSR-4 standard der namespacet Vendor\\Application\\ er koblet til src blir de respektive mappestrukturene slik:

Vendor\Application\Cookie: src/Vendor/Application/Cookie.php # PSR-0
Vendor\Application\Cookie: src/Cookie.php # PSR-4

Også PSR-4 fungerer med klasser som ikke er namespacet.

Composer

Composer er en dependency manager som støtter de fleste autolasting strategier.

composer.json:

{
    "autoload": {
        "classmap": ["classes"],
  
        "psr-0": {
            "Vendor\\Application\\": "classes"
        },
  
        "psr-4": {
            "Vendor\\Application\\": "classes"
        },

        "files": ["src/MyLibrary/functions.php"]
    }
}

For å generere autolasteren:

$ composer dump-autoload

Funksjoner uten namespace kan ikke autolastes men må inkluderes.

Hvis din kodebase ikke er namespacet gjør du f.eks. slik:

{
    "autoload": {
        "psr-0": {
            "": "classes"
        }
    }
}

Oppsummering

I en kodebase som ikke bruker namespaces lager du en mappe classes/ eller src/ og samler alle klasser der. Bruk PSR-0 autolasting.