Migration von 1.17 auf 2.0

1. Einleitung

Die Version 2.0 des Adventure PHP Framework bringt in einigen Bereichen umfassende Neuerungen mit. Die größte Änderung ist ein vollkommen überarbeitetes Modell zum Laden von Klassen gemäß PHP-Standard PSR-0. Damit wurde die Kompatibiliät und Interoperabilität mit anderen Produkten deutlich verbessert und das APF unterstützt nun die native Verwendung von PHP-Namespaces.

Um Ihre Applikation auf Basis der neuen Version betreiben zu können, sind weitreichende Anpassungen am Quellcode notwendig. Damit der Umsteig leichter fällt, liefert die neue Version eine automatisierte Migration aus und ein Werkzeug zur Trennung von Applikations- und Framework-Code.

Die folgenden Kapitel zeigen Ihnen, wie der Umsteig auf das APF 2.0 funktioniert und welche Änderungen vorgenommen werden müssen um Ihre bestehende(n) Applikation(en) auf dieser zu betreiben.

Bitte beachten Sie, dass nicht alle Teile der Anwendung automatisiert migriert werden können. Lesen Sie daher unbedingt Kapitel 2.3 und Kapitel 3!

2. Automatisierte Migration

Um die umfangreichen Änderungen an Ihre bestehenden Applikationen einfach und schnell vornehmen zu können, stellt das Release 2.0 eine automatisierte Migration von Version 1.17 auf das aktuelle Release bereit.

Bitte stellen Sie sicher, dass Sie vor der Migration alle unter Migration von 1.16 auf 1.17 beschriebenen Schritte durchgeführt haben. Setzen Sie eine noch ältere Version ein, migrieren Sie bitte zuerst vollständig auf die Version 1.17. Hinweise zur jeweiligen Migration finden Sie auf der Seite Artikel.

Zur Anpassung Ihrer Quell-Dateien finden Sie das Shell-Script migrate.sh im Ordner migration. Dieses führt mehrere PHP-Skripten aus und bringt ihre Applikation auf den neuesten Stand.

Sofern Sie auf Windows entwickeln, installieren Sie bitte eine aktuelle Version von cygwin (Download unter cygwin.com). Eine Migration auf Basis eines Windows-Batch-Script wird nicht angeboten.

Die folgenden Kapitel führen Sie Schritt für Schritt durch die Migration.

2.1. Vorbereitung

Die Migration läuft weitestgehend automatisiert ab, es wird jedoch trotzdem empfohlen, die im folgenden beschriebenen Schritte vorzunehmen um ein besseres Ergebnis zur erhalten. Das Migrations-Skript deckt in der Regel etwa 90-95% der Anpassungen ab, kann jedoch nicht alle Besonderheiten Ihres Projekt-Setups kennen.

Bitte beachten Sie, dass das APF-Team keine Verantwortung für Schäden am Quellcode übernehmen kann. Sichern Sie daher bitte zunächst Ihr Projekt vollständig und an einem unabhängigen Speicher-Ort um gegebenfalls entstandene Schäden durch das Einspielen einer Sicherung rückgängig machen zu können.

Die Migrations-Skripten wurden ausgiebig an Hand von unterschiedlichen Projekten getestet, es kann jedoch nicht ausgeschlossen werden, dass spezielle Konstrukte nicht erkannt und damit ggf. unbrauchbar gemacht werden.

Um ein besseres Ergebnis zu erziehlen werden folgende Vorarbeiten empfohlen:

  • Ersetzen Sie vorhandene @namespace-Annotationen in Dokumentations-Blöcken durch @package.
  • Pfüfen Sie Ihr Projekt auf Ordner-Namen, die nicht kompatibel mit PHP-Namespaces sind und benennen diese gegebenenfalls um (Hilfe unter php.net). Beispiel: befindet sich in Ihrem Projekt ein Ordner mit dem Namen foo-bar so benennen Sie diesen und alle Stellen, an denen er verwendet wird in beispielsweise foobar um.
  • Entfernen Sie dynamische import()-Aufrufen innerhalb von Funktionen oder Klassen-Methoden. Diese führen nach der Migration sonst zu Komilierungsfehlern.
  • Nutzt Ihr Projekt bereits teilweise PHP-Namespaces, so werden folgende Anpassungen empfohlen:
    • Entfernen von bisher verwendeten use-Statements. Dies vermeidet doppelte use-Statements nach der Migration.
    • Entfernen von bisher vorhandenen namespace-Deklarationen, dies hilft falsche Zuordnung von Namespaces zu vermeiden. Die Migration geht davon aus, dass alle Projekt-Namespaces ebenfalls mit APF als Hersteller beginnen. Eine Trennung des Applikations-Codes kann anschließend wie in Kapitel 6 beschrieben durchgeführt werden.
  • Reformattieren Sie bitte Ihren PHP-Quellcode. Dies verbessert die Erkennung von Code- und Annotations-Elementen. Beispiel: entfernen Sie im Statement
    PHP-Code
    /* @var  \FooClass */
    das unnötige Leerzeichen.

2.2. Ausführen der Migration

Die Migration umfasst drei Schritt: Ersetzen bzw. aktualisieren der bisherigen APF-Version, Ausführen des Migrations-Skripts und erledigen der Nacharbeiten.

2.2.1. Aktualisierung der APF-Dateien

Wechseln Sie bitte in den Projekt-Ordner und dort wiederum in den apps-Ordner, in dem Ihre Applikations-Dateien befinden. Dort finden Sie nun die APF-Ordner core, extensions, modules und tools sowie die von Ihnen erstellten Dateien.

Löschen Sie nun die APF-Ordner core, extensions, modules und tools und laden ein apf-codepack-apf-codepack-2.0-php5-*-Paket unter Downloads herunter. Entpacken Sie das Release anschließend im apps-Ordner.

Zusätzlich zu den bisher bekannten APF-Ordnern finden Sie nun auch einen migration-Ordner. Beispiel:

Code
Christian@chrislap /cygdrive/c/***/apps $ ll insgesamt 28K drwx------+ 1 Christian None 0 4. Jul 2013 config/ drwx------+ 1 Christian None 0 3. Jul 2013 core/ drwx------+ 1 Christian None 0 3. Jul 2013 extensions/ drwx------+ 1 Christian None 0 16. Jan 13:01 migration/ drwx------+ 1 Christian None 0 3. Jul 2013 modules/ drwx------+ 1 Christian None 0 4. Jul 2013 sites/ drwx------+ 1 Christian None 0 4. Jul 2013 thirdparty/ drwx------+ 1 Christian None 0 3. Jul 2013 tools/
2.2.2. Ausführen des Skripts

Im Verzeichnis migration befinden sich mehrere PHP-Dateien und das Skript migrate.sh, das die Migration durchführt. Dieses erwartet ein PHP-Executable als erstes und einziges Argument. Ist dieses nicht vorhanden, erhalten Sie folgende Fehlermeldung:

Code
Christian@chrislap /cygdrive/c/***/apps $ migration/migrate.sh ###################################### # APF 2.0 automatic migration # ###################################### Checking directory ... [OK] Checking PHP executable available ... [ERROR] PHP not found in your PATH-scope. Provide path to php as second parameter. Aborting!

Zum Start der Migration nutzen Sie bitte folgenden Shell-Aufruf im apps-Ordner:

Code
Christian@chrislap /cygdrive/c/***/apps $ ./migration/migrate.sh /cygdrive/c/xampp/php/php

Die Migration wir nun gestartet und Sie sehen folgende Ausgabe:

Code
Christian@chrislap /cygdrive/c/***/apps $ migration/migrate.sh /cygdrive/c/xampp/php/php ###################################### # APF 2.0 automatic migration # ###################################### Checking directory ... [OK] Checking PHP executable available ... [OK] Using given php executable at /cygdrive/c/xampp/php/php. PHP Version: 5.4.16. ###################################### Starting migration ... * Prepare addtaglib declarations for migration ... * Introduced namespace declarations ... * Switched from import() to use ... * Migrated PHPDoc comments ... * Migrated declaration and usage of tags ... * Migrated service calls and di-service configuration ... * Migrated registry calls ... * Migrated session(manager) calls ... * Add missing use statements ... * Clean up unnecessary use statements ... * Migrated Singleton/SessionSingleton calls ... * Migrated CookieManager to Cookie class ... * Migrated PostHandler to RequestHandler class ... * Migrate LinkGenerator calls for action urls ... * Migrated configuration files: * Config calls * Database configuration * Cache configuration * Front controller configuration * GORM configuration * Pager configuration * UMGT module configuration * Contact module configuration ###################################### Migration done! Please check your code and follow instructions within migration documentation!

Im Anschluss an die Migration sind noch einige Nacharbeiten notwendig. Diese entnehmen Sie bitte Kapitel 2.3.

Mehrfaches Ausführen ohne Wiederherstellen des ursprünglichen Standes kann zu unerwünschten bzw. unvorhersehbaren Ergebnissen führen (z.B. doppelte Angabe von use-Statements). Setzen Sie die Quell-Dateien zunächst auf den ursprünglichen Stand zurück und führen die Migration erneut aus.
Weitere Hinweise zur automatisierten Migration sind unter Migration und Änderungen in 2.0 beschrieben.

2.3. Nacharbeiten

Nach der Migration des Applikations-Codes sind noch einige Nacharbeiten zu erledigen. Diese betreffen vor Allem die Bootstrap-Datei Ihrer Anwendung (index.php) und gegebenenfalls das Auflösen von nicht von der Migration erfassten Teile des Codes.

2.3.1. Aktualisieren der Bootstrap-Datei

Die index.php ihrer Anwendung kann nicht automatisiert migriert werden, da sich diese für unterschiedliche Anwendungen zu sehr unterscheidet. Die folgenden Schritte zeigen Ihnen, wie Sie eine bestehende Bootstrap-Datei anpassen:

  1. Das APF besitzt seit der Version 2.0 eine eigene, interne Bootstrap-Datei, die den internen Zustand des Frameworks konfiguriert. Tauschen Sie daher
    PHP-Code
    include('***/core/pagecontroller/pagecontroller.php')
    gegen
    PHP-Code
    include('***/core/bootstrap.php');
    aus. Bitte passen Sie den Pfad jeweils auf die Gegebenheiten Ihrer Applikation an.
  2. Führen Sie jeweils ein use-Statement für die in der index.php verwendeten Klassen ein. Für die Verwendung der Klasse Singleton lautet dieses
    PHP-Code
    use APF\core\singleton\Singleton;
  3. Entfernen Sie alle Aufrufe der Funktion import(). Diese wurde im APF 2.0 durch das native Schlüsselwort use ersetzt.
  4. Durch die Einführung von PHP-Namespaces für Klassen, Templates und Konfigurations-Dateien ist es erforderlich alle Klassen-Referenzen auf absolute Adressierung umzustellen. Dies betrifft in der index.php vor allem die Nutzung der Klasse Singleton. Ersetzen Sie daher bitte alle Aufrufe der Form
    PHP-Code
    Singleton::getInstance('Frontcontroller')
    gegen
    PHP-Code
    Singleton::getInstance('APF\core\frontcontroller\Frontcontroller')
  5. Die Umstellung auf die PHP-Namespace-Notation betrifft auch die zur Adressierung von Registry-Einträgen genutzten Namespaces. Entfernen Sie daher alle "::"-Vorkommen durch "\". Registry-Einträge der Form
    PHP-Code
    Registry::retrieve('apf::core', 'InternalLogTarget')
    werden in der Version 2.0 wie folgt ausgelesen:
    PHP-Code
    Registry::retrieve('APF\core', 'InternalLogTarget'
  6. Die Umstellung auf die PHP-Namespace-Notation findet ebenfalls bei der Definition von Konfigurations-Einträgen Anwendung. Überführen Sie daher Front-Controller-Action-Deklarationen der Form
    PHP-Code
    $fC->registerAction('cms::core::biz::setmodel', 'setModel')
    in
    PHP-Code
    $fC->registerAction('APF\cms\core\biz\setmodel', 'setModel')
  7. Wie in der Einleitung erwähnt werden neben PHP-Klassen auch Templates über Namespaces referenziert. Stellen Sie aus diesem Grund die Referenz auf das initiale Template von beispielsweise
    PHP-Code
    $fC->start('***::pres::templates', 'site')
    auf
    PHP-Code
    echo $fC->start('APF\***\pres\templates', 'site');
    um.
2.3.2. Korrektur der Code-Dateien

Wie in der Einleitung angesprochen werden etwa 90-95% der Tätigkeiten durch die automatisierte Migration erfasst. Leider können nicht alle Projekt-spezifischen Anwendungsfälle berücksichtigt werden. Aus diesem Grund werden Sie vermutlich einige Anpassungen am Quellcode vornehmen müssen um die fehlerfreie Funktion Ihrer Applikation zu garantieren.

Die folgende Liste zeigt in den Tests notwendige Anpassungen. Bitte beachten Sie, dass für Ihr Projekt gegebenfalls weitere oder andere Schritte notwendig sind.

  • Um Fehler in der Applikation zu vermeiden, bietet es sich an, einen Code-Inspektor zu nutzen um potentielle Probleme automatisiert zu suchen. Hierzu empfiehlt das APF-Team den Code Inspector von PHPStorm. Dieser zeigt Ihnen Fehler im Code in den Bereichen Unused -> Classes, Unused -> Functions und Undefined an. Diese können Sie mit PHPStorm auch automatisert beheben.
  • Die automatisierte Migration erfasst nicht alle Namespace-Konstrukte Ihrer Applikation. Dazu zählen beispielsweise Session-Namespace oder solche in eigenen Tags. Durchsuchen Sie daher Ihr Projekt nach dem Vorkommen von "::" in Zeichenketten und schreiben die Vorkommen um. Beispiel:
    PHP-Code
    // Alte Schreibweise $session = new Session('foo::bar'); // Neue Schreibweise $session = new Session('VENDOR\foo\bar');

3. Manuelle Migration

Leider lassen sich nicht alle Bestandteile der Applikation automatisiert migrieren. In diesem Kapitel sind daher Komponenten oder Module aufgeführt, die manuell auf die Version 2.0 umgestellt werden müssen.

  1. Die Signatur des <fcon:importdesign />-Tags wurde in Version 2.0 grundlegend geändert. Grund dafür ist die Zusammenfassung von modelnamespace, modelfile und modelclass zu einem Attribut, das den voll-qualifizierten Klassen-Namen des Models enthält. Stellen Sie daher die Signatur des Tags von
    APF-Template
    <fcon:importdesign templatenamespace="" modelnamespace="" modelfile="" modelclass="" modelparam="" [sessionsingleton=""] />
    auf
    APF-Template
    <fcon:importdesign template-namespace="" template-param="" model="" [sessionsingleton=""] />
    um.

4. FAQs

Während der Test-Phase der Migrations-Skripten sind auch uns verschiedene Fehler begegnet. Diese - zusammen mit den entstrechenden Lösungen - sind in diesem Kapitel zusammengefasst.

4.1. preg_replace_callback()

Fehler
Code
preg_replace_callback(): Requires argument 2, 'ChainedGenericOutputFilter::replaceLink', to be a valid callback
Lösung

Die Klasse ChainedGenericOutputFilter wurde ohne Namespace verwendet. Um den Fehler zu beheben, muss diese innerhalb der Funktion preg_replace_callback inklusive Namespace angegeben werden. Beispiel:

PHP-Code
preg_replace_callback( '/<a (.*?)href="(.*?)"(.*?)>(.*?)<\/a>/ims', array('APF\core\filter\ChainedGenericOutputFilter', 'replaceLink'), $input );

4.2. ConfigurationException

Fehler
Code
Class loader root path for namespace "sites\apf\biz" cannot be determined. Please double-check your configuration!
Lösung

Der angegebene Namespace besitzt keinen Hersteller (erster Abschnitt des Namespaces). Ändern Sie den Namespace daher z.B. in DOCS\biz. APF ist der Standard-Hersteller, der in der bootstrap.php registriert wird. Details dazu finden Sie unter Laden von Klassen.

4.3. Class not found

Fehler
Code
Class 'APF\xyz\pres\documentcontroller\Controller' not found...
Lösung

Möglicherweise fehlt die Angabe eines Namespace in der Datei APF/xyz/pres/documentcontroller/Controller.php. Fügen Sie dazu bitte direkt in der zweiten Zeile nach <?php ein

PHP-Code
namespace APF\xyz\pres\documentcontroller;

ein.

Fehler
Code
Fatal error: Class 'Logger' not found in ***\APF\core\singleton\Singleton.php on line 88
Lösung

Nutzen Sie bitte bei allen Aufrufen von Singleton::getInstance() oder SessionSingleton::getInstance() sowie $this->getServiceObject() den voll-qualifizierten Klassen-Namen - hier: APF\core\logging\Logger.

4.4. Fatal Error

Fehler
Code
Fatal error: Interface 'APF\core\service\APFDIService' not found in ***\APF\core\pagecontroller\pagecontroller.php on line 320
Lösung

In der Bootstrap-Datei wurde noch nicht von

PHP-Code
include('./APF/core/pagecontroller/pagecontroller.php');

auf

PHP-Code
include('./APF/core/bootstrap.php');

umgestellt. Holen Sie dies wie in Kapitel 2.3.1 beschrieben nach.

Fehler
Code
Fatal error: Call to undefined function import() in ***\index.php on line 21
Lösung

Bitte entfernen Sie alle Stellen, an denen im Code die Funktion import() aufgerufen wird. Diese wird in der neuen Version des APF nicht mehr benötigt.

4.5. ClassLoader Exception

Fehler
Code
Class loader root path for namespace "foo::bar::blah" cannot be determined. Please double-check your configuration!
Lösung

Bitte verwenden Sie bei allen Namespace-Angaben zukünftig die voll-qualifizierte Schreibweise - hier: APF\foo\bar\blah. Dieser Fehler tritt häufig nach der Migration bei der Registrierung von Front-Controller-Actions oder dem Laden von initialen Templates in der Bootstrap-Datei auf.

5. Umbenannte Klassen und Methoden

Wie bereits in bisherigen Releases erfolgt wurden auch in diesem Release einige Klassen- und Methoden-Namen verändert um Konsistenz und intuitive Benutzung sicher zu stellen. Die folgenden Tabellen zeigen Ihnen die Änderungen im Überblick.

Die folgenden Klassen wurden gegenüber Version 1.17 umbenannt:

Bisheriger Klassen-Name Neuer Klassen-Name
ChainedGenericInputFilter ChainedStandardInputFilter
ChainedGenericOutputFilter ChainedUrlRewritingOutputFilter
SessionManager Session
CookieManager Cookie

Die nachfolgende dargestellte Tabelle zeigt Ihnen die Methoden, die gegenüber Version 1.17 umbenannt wurden:

Bisheriger Methoden-Name Neuer Methoden-Name
Session::destroySession() Session::destroy()
Session::loadSessionData() Session::load()
Session::loadAllSessionData() Session::loadAll()
Session::getEntryDataKeys() Session::getEntryKeys()
Session::saveSessionData() Session::save()
Session::deleteSessionData() Session::delete()
CookieManager::createCookie() Cookie::setValue()
CookieManager::updateCookie() Cookie::setValue()
CookieManager::readCookie() Cookie::getValue()
CookieManager::deleteCookie() Cookie::delete()
Die hier aufgeführten Klassen und Methoden sind lediglich zu Dokumentations-Zwecken dokumentiert. Die Umstellung auf die neuen Schreibweisen wird durch die in Kapitel 2 automatisierte Migration bereits für Sie erledigt.

6. Trennung des Applikations-Codes

Ab Version 2.0 des Adventure PHP Framework ist es möglich, Applikations-Code und -Konfiguration von der Code-Basis und der Konfiguration des Frameworks bzw. der Framework-Komponenten zu trennen. Unter Laden von Klassen und im Tutorial Erstellen einer Webseite sind die Grundlagen dazu beschrieben.

Beabsichtigen Sie Ihren Applikations-Code und die zugehörige Konfiguration auszulagern, können Sie das im migration-Ordner mitgelieferte Skript relocate.sh nutzen. Dieses nimmt eine Quell- und einen Ziel-Namespace entgegen. Es kopiert die unterhalb des Namespace befindlichen Dateien an den neuen Bestimmungsort und schreibt alle Namespace-Nutzungen um.

Das Skript unterstützt dabei mehrere Arten der Namespace-Umschreibung:

  • Namespace: Wurde Ihre Applikation beispielsweise unter APF\sites\foo abgelegt, so können Sie diese in einen anderen Namespace desselben Herstellers (in diesem Fall APF) verschieben (z.B. APF\pages\foo).
  • Hersteller: Der Haupt-Anwendungsfall im Rahmen der Migration auf die Version 2.0 ist die Auslagerung von bestehenden Namespaces des Herstellers APF in einen eigen, neuen Hersteller-Bereich (z.B. DOCS). Das Skript beherrscht dabei das Verschieben eines Namespaces eines Herstellers in einen Teil-Bereich eines anderen (z.B. APF\sites\foo --> APPLICATION\foo), sowie die Auslagerung eines Teil-Bereichs in den Haupt-Bereich eines neuen Herstellers (z.B. APF\sites\foo --> FOO).

Das folgende Beispiel zeigt die Extraktion des Hersteller-Bereichs DOCS in einen neu definierten Hersteller-Bereich DOCS:

Code
Christian@chrislap /cygdrive/c/***/apps $ migration/relocate.sh /cygdrive/c/xampp/php/php "DOCS" "DOCS" ###################################### # APF 2.0 automatic migration # ###################################### Checking directory ... [OK] Checking PHP executable available ... [OK] Using given php executable at /cygdrive/c/xampp/php/php. PHP Version: 5.4.16. Checking necessary parameters available ... [OK] ###################################### Starting relocation ... Source namespace: DOCS Target namespace: DOCS * Copy files to target structure ... * Re-mapping namespace on target ... ###################################### NOTE: Please note, that relocate.sh does not handle relocation of configuration files. Thus, please revise folder "/cygdrive/c/***/apps/config" and extract configuration files for vendor "APF" to new vendor "DOCS" as desired! ###################################### NOTE: Please be sure to add a new class loader configuration for new vendor "DOCS" within your bootstrap file (index.php). You may want to use the following as a start: use APF\core\loader\RootClassLoader; use APF\core\loader\StandardClassLoader; RootClassLoader::addLoader(new StandardClassLoader('DOCS', '/cygdrive/c/***/DOCS')); ###################################### Relocation done! Please check your code and follow instructions within migration documentation!
Bitte beachten Sie, dass relocate.sh die relevanten Dateien des Quell-Namespaces in den neuen Bereich kopiert. Die ursprünglichen Dateien bleiben zur Sicherheit weiterhin erhalten.

Zur Verwendung der verschobenen Dateien ist eine Anpassung der Bootstrap-Datei Ihrer Applikation notwendig. Als Basis lässt sich hierzu die vom Skript erzeugte Ausgabe nutzen (siehe RootClassLoader::addLoader()).

Da die Struktur der Konfigurations-Dateien Ihres Projekts sehr spezifisch sind - z.B. nicht konsequenterweise unter dem Namespace der Applikation abgelegt ist - können diese nicht automatisiert verschoben werden. Hierzu ist Ihr Eingriff notwendig (z.B. Umbenennen und/oder Umschreiben von Namespaces, Verschieben von Dateien).

Zur endgültigen Migration entfernen Sie bitte die ursprünglich vorhandenen Dateien.

Kommentare

Möchten Sie den Artikel eine Anmerkung hinzufügen, oder haben Sie ergänzende Hinweise? Dann können Sie diese hier einfügen. Die bereits verfassten Anmerkungen und Kommentare finden Sie in der untenstehenden Liste.
Für diesen Artikel liegen aktuell keine Kommentare vor.