SlideShare ist ein Scribd-Unternehmen logo
Ralf Eggert | Travello GmbH
Migration vom ZF1 zum ZF2
von einfach bis fies
Über Ralf Eggert
• Dipl. Wirtschaftsinformatiker (FH)
• Jahrgang 1972
• GF Travello GmbH
• Buchautor zum ZF1 & ZF2 (AW / Galileo)
• Kolumnist PHP-Magazin
• ZF seit 2006
• Contributor
• https://profiles.google.com/eggert.ralf
Und Sie?
• Erfahrungen ZF1?
• Erfahrungen ZF2?
• Projekte schon migriert?
• Falls nein, warum nicht?
• Falls ja, Ihre Erfahrungen?
Überblick
• Einführung
• ZF1 Projekt vorbereiten
• ZF2 Skeleton integrieren
• Startseite nach ZF2 migrieren
• MVC-Layer für Blog Modul migrieren
• Authentifizierung & Autorisierung migrieren
• Model-Layer für Blog Modul migrieren
Einführung
Ausreden Gründe gegen Migration
• Technische Gründe
– PHP 5.3
• Betriebswirtschaftliche Gründe
– Kunde scheut den Aufwand
• Fachliche Gründe
– Know-how fehlt
• Organisatorische Gründe
– Keine Zeit
Gründe für Migration
• Zend Framework 1
– Keine Weiterentwicklung
– Support durch Zend wird 2014 eingestellt
• Zend Framework 2
– Stetige Weiterentwicklung
– Support durch Zend bis mindestens 2016
• Zend Framework 3
– Kommt in 2014
– Migration von ZF2 nach ZF3 deutlich einfacher
Probleme bei Migration
• Kein Tool für automatische Migration
• Kein Migration Layer (war mal versprochen)
• Migration-Guide in der ZF2 Dokumentation
fehlte lange und ist jetzt noch unvollständig
• ZF1 bietet viele Freiheiten & verlangt keine
100% feste Struktur wie andere Frameworks
• Allgemeingültige Schritt-für-Schritt-Anleitung
für alle Anwendungen schwer umsetzbar
Unterschiede ZF1 und ZF2 I
• Genutzte PHP Features
– Namespaces
– Closures
– Late Static Binding
• Git / GitHub
• Neue Konzepte
– »Echte« Modularität
– Dependency Injection / Service-Locator
– Event-Driven Architecture
Unterschiede ZF1 und ZF2 II
• ZF1: Convention over Configuration
• ZF2: Configuration over Convention
• Kein ZendRegistry im ZF2
• Kein ZendApplication im ZF2
• Zend_Controller → ZendMvc
• ZendForm: keine Dekorierer (ach menno ;-))
• ZendPdf und ZendService nicht im Core
• Viele Internationalisierungskomponenten
entfallen wegen Nutzung von ext/intl
Unterschiede ZF1 und ZF2 III
• Überarbeitete Komponenten
– ZendAuthentication, ZendDb, ZendForm,
ZendInputFilter, ZendMvc,
ZendPermissions, ZendView...
• Neue Komponenten
– ZendEventManager, ZendModuleManager,
ZendServiceManager, ZendDi, ZendStdlib...
• Ausgelagerte und entfallene Komponenten
– ZendDate, ZendDojo, ZendGdata, ZendLocale,
ZendPdf, ZendRegistry, ZendService...
»Einfache« Migration
• Zend Framework 1.11 oder 1.12 im Einsatz
• Empfohlene Projektstruktur wird eingehalten
• Anwendung in mehrere Module unterteilt
• Wenige eigene Framework-Erweiterungen
• View-Skripte verwenden PHP
• CSS und JS Frameworks beibehalten
• Thin Controllers / Fat Models
• Zend_Db_Table nur als Datenquelle verwendet
Komplexe Migration
• Zend Framework 1.8 bis 1.10 im Einsatz
• Projektstruktur teilweise eingehalten
• Anwendung unvollständig in Module unterteilt
• Einige wesentliche Framework-Erweiterungen
• View-Skripte mit gängiger Template-Engine
• CSS und JS Frameworks austauschen
• Medium Controllers / Medium Models
• Zend_Db_Table stark mit Methoden erweitert
Fiese Umsetzung
• Zend Framework 1.0 bis 1.7 im Einsatz
• Empfohlene Projektstruktur ignoriert
• Module gar nicht verwendet (Struktur)
• Sehr viele Framework-Erweiterungen
• View-Skripte setzen HTML_Template_IT ein
• Weder CSS noch JS Frameworks vorhanden
• Fat Controllers / No Models
• Zend_Db_Table wird nicht eingesetzt
Lösungsansätze
• ZF1 Anwendung in Namensräume portieren
– https://github.com/zendframework/Namespacer
– Viel manuelle Arbeit erforderlich
• ZF1 Library in ZF2 Applikation oder
ZF2 Library in ZF1 Applikation verwenden
– https://zf2.readthedocs.org/en/latest/
migration/zf1_zf2_parallel.html
• ZF1 Anwendung und ZF2 Anwendung
parallel laufen lassen
Vorgehensweise
• ZF1 Projekt vorbereiten
– »Default« Modul einrichten
– Verzeichnisse umbenennen
• ZF2 Projekt integrieren
– .htaccess Weiche für ZF1 und ZF2
• Routing beachten
• Startseite migrieren
• Nacheinander Module umziehen
Beispiel ZF1 Anwendung
• Setzt folgende Komponenten ein
– Zend_Acl, Zend_Auth, Zend_Cache, Zend_Db,
Zend_Navigation, Zend_Filter, Zend_Form,
Zend_Locale, Zend_Translate,
Zend_Validate, ...
• Verwendet
– Twitter Bootstrap
– jQuery
– CKEditor
– HTMLPurifier
Screenshot ZF1 Anwendung
Stufe 1
ZF1 Projekt vorbereiten
Erste Vorbereitungen
• Backup des ZF1 Projektes (!)
• Start mit Kopie des gesamten Projektes
• Versionsverwaltung verwenden
– Fehlerhafte Schritte sind zurück nehmbar
– Branches für verschiedene Schritte denkbar
• Neue Datenbank oder Kopie erstellen
• Neuen Virtual Host einrichten
• PHP Upgrade auf mindestens PHP 5.3.3
• Projekt in IDE der Wahl einrichten
Modul »Default« einrichten
• Pfad /application/modules/default
• Klasse Default_Bootstrap erweitert
Zend_Application_Module_Bootstrap in
Datei Bootstrap.php
• Unter /application bleiben Verzeichnis
/modules und Datei Bootstrap.php übrig
• Alles andere ins »Default« Modul
• index.php anpassen für application.ini
im »Default« Modul
Neue Projektstruktur
Konfiguration in application.ini
• Nicht mehr notwendig
– resources.frontController.controllerDirectory
• Pfade ggf. für »Default« Modul anpassen
– resources.layout.layoutPath
– resources.view.basePath
– resources.translate.content
• Aufnehmen, falls nicht vorhanden
– resources.modules[] = ""
• Einstellungen für Staging development,
production, usw. überprüfen
Verzeichnisse umbenennen
• Verzeichnisse umbenennen
– /application => /application.zf1
– /data => /data.zf1
– /library => /library.zf1
– /tests => /tests.zf1
• Konfiguration für Verzeichnisse anpassen
– APPLICATION_PATH in /public/index.php
– include_path in /public/index.php
– Pfade in application.ini
ZF1 Front-Controller-Datei
• Datei umbenennen in /public
– index.php => index.zf1.php
• Konfiguration in .htaccess anpassen
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.zf1.php
Anwendung prüfen!
• Läuft die Anwendung noch?
• Sind alle Module aufrufbar?
• Sind alle Seiten des »Default« Moduls
aufrufbar (Homepage, usw.)?
• Werden alle Seitenbereiche angezeigt?
• Was ist mit Übersetzungen?
• Macht PHP 5.3 Probleme?
• Erst wenn alles läuft, Migration fortsetzen!
Stufe 2
ZF2 Skeleton integrieren
Skeleton Application downloaden
• Als ZIP herunterladen und entpacken
– https://github.com/zendframework/
ZendSkeletonApplication
• Alle Dateien und Verzeichnisse ins ZF1
Projekt kopieren außer
– /public
• ZF2 installieren
– php composer.phar selfupdate
– php composer.phar install
ZF2 Front-Controller-Datei
• Aus SkeletonApplication ins ZF1 Projekt
– index.php => index.zf2.php
• PROJECT_PATH, APPLICATION_PATH und
APPLICATION_ENV definieren
• Konfiguration in .htaccess anpassen
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^application(.*)$ index.zf2.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.zf1.php
ZF2 Assets
• Asset Verzeichnisse ins ZF1 Projekt kopieren
– /public/css
– /public/img
– /public/js
• Ggf. auf Dateiüberschreibungen achten
– Verschiedene Twitter Bootstrap Versionen?
– Verschiedene jQuery Versionen?
– Grafiken wie favicon.ico
• style.css aus SkeletonApplication ignorieren
Anwendung prüfen!
• Prüfen, ob alle Seiten aus der alten ZF1
Anwendung korrekt angezeigt werden!
• Was passiert beim Aufruf der neuen URL
/application?
• Wird Twitter Bootstrap, jQuery geladen?
• Wenn alles klappt, wird ZF2 Skeleton
Application angezeigt
• => ZF1 und ZF2 laufen parallel
Vorteile dieses Ansatzes
• Das alte ZF1 Projekt kann parallel zu neuen
ZF2 Features betrieben werden
• Features können schrittweise von ZF1 nach
ZF2 portiert werden
• Wenn alle alten ZF1 Features portiert sind,
können .zf1 Verzeichnisse entfernt werden
Nachteile dieses Ansatzes
• Layouts sind unabhängig
– Lösung: Layouts duplizieren
• Konfigurierbare Kombination einer Navigation
aus ZF1 und ZF2 nur schwer möglich
– Lösung: Navigation duplizieren
• Ist Nutzer in ZF1 angemeldet, ist geschützter
Zugriff auf ZF2 Module erschwert
– Lösung: Sessions in Datenbank speichern
Routing
• Überschneidungen beim Routing vermeiden!
• Neue ZF2 Features bekommen neue Routen
• Vorhandene ZF1 Routen wiederverwenden,
wenn ZF2 Modul ein altes ZF1 Modul ersetzt
• Im ZF2 keine »globalen« Routen verwenden
• Starter für neue ZF2 Routen müssen in
der .htaccess notiert werden
Stufe 3
Startseite nach ZF2
migrieren
.htaccess anpassen
• Anfragen für Homepage auf index.zf2.php
umleiten
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^$|^en$ index.zf2.php
RewriteRule ^application(.*)$ index.zf2.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* start.zf1.php
• Testen!
Layout migrieren
• Aus dem ZF1 ins ZF2 kopieren
• Veränderte View-Helper anpassen
• Fehlende View-Helper auskommentieren
• Layout hierarchisch?
– Header, Footer, Sidebar
– Umsetzung z.B. mit ApplicationListener
• SkeletonApplication Assets entfernen
– CSS Datei style.css & Grafik zfs-logo.png
• Testen!
Navigation migrieren
• ZF1 Navigation
– /application.zf1/modules/default/configs/
application.ini
• ZF2 Navigation konfigurieren
– /module/Application/config/module.config.php
– Service nicht vergessen!
• Links zur ZF1 Anwendung als URI definieren
– Nach Migration der Module ändern
• Partial für Ausgabe im Twitter Bootstrap Style
• Testen!
Translator migrieren I
• Dateien der SkeletonApplication löschen
– /module/Application/language/*
• Übersetzungsdateien kopieren
– Von /modules/default/locales/*.php
– Nach /module/Application/language/
• Konfiguration in module.config.php ändern
• Testen!
Translator migrieren II
• Fehlende Module unter /module anlegen
– /module/ModulName/config/
module.config.php => translator
– /module/ModulName/language/
– /module/ModulName/Module.php : getConfig()
• Übersetzungsdateien kopieren
– Für jedes Modul
• Module aktivieren
– /config/application.config.php
• Testen!
Autoloading für ZF1 Dateien I
• ClassMap für ZF1 Module erstellen
– in /application.zf1/modules
• Konfiguration im Application Modul
– Module::getAutoloaderConfig()
• Wahlweise
– include_path in /public/index.php ergänzen
mit PROJECT_ROOT . '/library.zf1'
– Alle require_once Statements aus den ZF1
Library Dateien entfernen
Autoloading für ZF1 Dateien II
namespace Application;
class Module
{
public function getAutoloaderConfig()
{
return array(
'ZendLoaderClassMapAutoloader' => array(
'zf1' => PROJECT_ROOT
. '/application.zf1/modules/autoload_classmap.php',
),
'ZendLoaderStandardAutoloader' => array(
'autoregister_zf' => true,
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
'prefixes' => array(
'Zend' => PROJECT_ROOT . '/library.zf1/Zend',
'Company' => PROJECT_ROOT . '/library.zf1/Company',
),
),
);
}
}
ZF1 Model-Service in ZF2 nutzen
• IndexController in Application Modul
greift auf Blog_Service_Article zu
• Klasse sollte gefunden werden
• Konfigurationsprobleme
– cache nicht in Zend_Registry vorhanden
– Kein Default Adapter für Zend_Db_Table gesetzt
• Lösung:
– CompatibilityListener einrichten, um
Konfigurationsprobleme zu lösen
CompatibilityListener (Auszug)
namespace ApplicationListener;
class CompatibilityListener implements ListenerAggregateInterface
{
[...]
public function setupZF1Compatibility(EventInterface $e)
{
$config = new Zend_Config_Ini(
PROJECT_PATH . '/application.zf1/modules/default/configs/application.ini',
APPLICATION_ENV
);
$cacheOptions = $config->resources->cachemanager->database->toArray();
$cache = Zend_Cache::factory(
$cacheOptions['frontend']['name' ],
$cacheOptions['backend' ]['name' ],
$cacheOptions['frontend']['options'],
$cacheOptions['backend' ]['options']
);
Zend_Registry::set('cache', $cache);
$dbOptions = $config->resources->db->toArray();
$db = Zend_Db::factory($dbOptions['adapter'], $dbOptions['params']);
Zend_Db_Table::setDefaultAdapter($db);
}
}
Startseiten View-Skript migrieren I
• View-Skript kopieren
– Von /application.zf1/modules/default/
views/scripts/index/index.phtml
– Nach /module/Application/view/
application/index/index.phtml
• Probleme mit View-Helpern
– URL View-Helper fehlen Routen
– URL View-Helper andere Parameter-Reihenfolge
– View-Helper Date und Time fehlen
Startseiten View-Skript migrieren II
• Eigenen Date View-Helper einrichten
– Zur Ausgabe von Datumswerte
– Konfiguration für Service-Manager
• Alternative
– DateFormat View-Helper
• Testen!
Offene Punkte
• Navigation zeigt alle Menüpunkte, da noch
keine ACL eingerichtet ist
• User Widget fehlt noch in der Seitenleiste
• Modul User migrieren
• Modul Blog migrieren
Screenshot ZF2 Anwendung
Zusammenfassung
• ZF2 Anwendung kann ZF1 Klassen
verwenden
• Layout, Navigation, Translator und View-
Skript wurden migriert
• CompatibilityListener für Migration von
Konfigurationseinstellungen
• ZF1 Module wurden zum Teil in ZF2
Anwendung eingerichtet
• Startseite nutzt Blog_Service_Article
Stufe 4
MVC-Layer für
Blog Modul migrieren
Routing migrieren I
• Anfragen für Blog Modul in .htaccess
umleiten
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^$|^en$ index.zf2.php
RewriteRule ^application(.*)$ index.zf2.php
RewriteRule ^(de|en)/blog|beitrag|kategorie
|nutzer(.*)$ index.zf2.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* start.zf1.php
Routing migrieren II
• Jedes ZF2 Modul sollte immer mindestens
eine eigene Route haben
– Nicht auf eine globale Route verlassen!
• Es werden vier Routen benötigt
– Generelle Route für Blog Modul
– Spezielle Route für Blogbeiträge
– Spezielle Route für Beiträge einer Blogkategorie
– Spezielle Route für Beiträge eines Nutzers
Navigation migrieren
• Navigation-Konfiguration aus Application
Modul ins Blog Modul verschieben
• Seitentyp von uri auf mvc wechseln
• Reihenfolge der Menüpunkte durch
Parameter order festlegen
Controller migrieren I
• Controller in module.config.php
konfigurieren und mit Routen matchen
• Verzeichnis anlegen
– /module/Blog/src/Blog/Controller
• Controller mit benötigten Methoden anlegen
– IndexController mit indexAction(),
showAction(), categoryAction(), usw.
– AdminController
– CategoryController
– usw.
Controller migrieren II
• Code der Aktionsmethoden aus ZF1 Modul
übernehmen und anpassen
– Parameter holen mit params() Controller-Plugin
– Umleitungen für redirect() Plugin anpassen
– URL-Generierung für url() Plugin anpassen
– Templatevariablen an ViewModel übergeben
• Verwendung der ZF1 Model-Services kann
vorerst beibehalten werden
View-Skripte migrieren
• View-Manager konfigurieren, damit View-
Skripte gefunden werden können
• Verzeichnisse anlegen
– /module/Blog/view/blog/index/
– /module/Blog/view/blog/admin/
– /module/Blog/view/blog/category/
• Code der View-Skripte aus ZF1 Modul
übernehmen und anpassen
– Einsatz der Standard View-Helper überprüfen
– Eigene View-Helper migrieren
View-Helper migrieren
• View-Helper im Modul Blog konfigurieren,
damit sie gefunden werden
• Im View-Helper darauf achten:
– Statt $this->view wie im ZF1 muss im ZF2
$this->getView() verwendet werden
– Auf Parameter der Standard View-Helper achten
• Url, Translate, usw.
• Anwendung testen!
Model-Layer & Forms übernehmen
• Im Administrationsbereich werden vorerst
folgende ZF1 Klassen weiterverwendet
– Model-Layer mit Entities, Datenquellen, Mapper
und Model-Service
– Formulare mit Filtern und Validatoren
• Im CompatibilityListener konfigurieren
– Zend_Controller_Front benötigt ggf. Instanzen
vom Request und Response Objekt
– Zend_Translate zur Verwendung mit Zend_Form
– Namensräume für eigene Filter und Validatoren
CompatibilityListener (Auszug) I
namespace ApplicationListener;
class CompatibilityListener implements ListenerAggregateInterface
{
public function setupZF1Compatibility(EventInterface $e)
{
Zend_Controller_Front::getInstance()
->setRequest(new Zend_Controller_Request_Http())
->setResponse(new Zend_Controller_Response_Http())
->setDispatcher(new Zend_Controller_Dispatcher_Standard());
$translations = array();
$applicationConfig = $e->getApplication()->getServiceManager()
->get('ApplicationConfig');
foreach ($applicationConfig['modules'] as $module) {
$localesFile = PROJECT_PATH . '/module/' . $module . '/language/'
. $e->getRouteMatch()->getParam('lang') . '.php';
if (file_exists($localesFile)) {
$translations = array_merge($translations, include $localesFile);
ksort($translations);
}
}
[...]
CompatibilityListener (Auszug) II
[...]
$translator = new Zend_Translate(array(
'adapter' => 'Array',
'content' => $localesFile,
'locale' => $e->getRouteMatch()->getParam('lang'),
));
$translator->addTranslation(
$translations, $e->getRouteMatch()->getParam('lang')
);
Zend_Form::setDefaultTranslator($translator);
Zend_Filter::addDefaultNamespaces('Company_Filter');
Zend_Validate::addDefaultNamespaces('Company_Validate');
}
}
Weitere Migrationen
• AdminController zum Pflegen der
Blogbeiträge inkl. der View-Skripts
• CategoryController zum Pflegen der
Blogkategorien inkl. der View-Skripts
• ZF1 Formulare benötigen für Ausgabe eine
Zend_View Instanz!
• Testen!
Zusammenfassung
• Blog Modul läuft auf ZF2 mit einigen
Einschränkungen
– Verwendet noch ZF1 Model-Layer
– Verwendet noch ZF1 Formulare
– Verwendet noch ZF1 Filter und Validatoren
– Ist abhängig vom CompatibilityListener
Stufe 5
Authentifizierung &
Autorisierung migrieren
User-Widget migrieren
• View-Helper migrieren
• Anfragen zum Einloggen auf ZF1 User Modul
umleiten
• View-Helper konfigurieren
• UserWidget in Seitenleiste ausgeben
Authentifizierung
• CompatibilityListener konfiguriert
Zend_Session für ZF1 Authentifizierung
– Konfiguration aus application.ini holen
– SaveHandler einrichten
– Session konfigurieren
– Zend_Auth Instanz im Service-Manager als
Service »UserAuthentication« speichern
CompatibilityListener (Auszug)
namespace ApplicationListener;
class CompatibilityListener implements ListenerAggregateInterface
{
public function setupZF1Compatibility(EventInterface $e)
{
[...]
$sessionOptions = $config->resources->session->toArray();
$saveHandlerClass = $sessionOptions['saveHandler']['class'];
$saveHandler = new $saveHandlerClass(
$sessionOptions['saveHandler']['options']
);
unset($sessionOptions['saveHandler']);
Zend_Session::setOptions($sessionOptions);
Zend_Session::setSaveHandler($saveHandler);
$e->getApplication()->getServiceManager()
->setService('UserAuthentication', Zend_Auth::getInstance());
}
}
Autorisierung
• Konfiguration der Benutzerrechte in den
module.config.php Dateien der Module
• Erstellung von UserAclAcl, die ZendAcl
erweitert und ACL-Konfiguration verarbeitet
• Factory für UserAclAcl
• AuthorizationListener zum Prüfen der
Benutzerrechte mit ACL und der Rolle
– Bei fehlenden Rechten Umleitung auf forbidden
Seite des ZF1 User Moduls
ACL mit Navigation kombinieren
• Konfiguration der Navigation mit Parametern
resource und privilege erweitern
• Navigation-Konfiguration auf MVC Seiten
umstellen
• Navigation für User Modul ins Modul
• Erweiterung vom AuthorizationListener
zur Übergabe der aktuellen Zend_Auth Rolle
sowie ACL an Navigation View-Helper
Zusammenfassung
• ZF2 der Anwendung nutzt Authentifizierung
des ZF1 User Moduls
• ZF2 der Anwendung stellt Autorisierung
selber bereit (wegen ZendNavigation)
• User-Widget leitet entsprechend auf ZF1
User Modul um
• Später kann gesamtes User Modul migriert
werden
Stufe 6
Model-Layer für
Blog Modul migrieren
Model-Entities
• Model-Entities nahezu 1:1 migrierbar
• Umschreibung auf Namensräume sinnvoll
• ZendStdlibArraySerializableInterface
– Implementation sinnvoll
– Für Einsatz mit Hydratoren
• Instanzierung über Service-Manager
Table-Gateways
• ZendDbTableGatewayTableGateway als
Datenquelle implementieren
• Einsatz eines ResultSets mit Hydratoren,
um Instanzen der Model-Entities zu erhalten
• Abfragen von Daten als Methoden mithilfe
von ZendDbSqlSql implementieren
• Ansonsten nicht zu viel Logik implementieren
• Instanzierung über Service-Manager
Mapper und Hydratoren I
• Aufgaben des Mappers
– Übergabe Arraydaten an Objekt und umgekehrt
– Aufbereitung Daten zum Schreiben in Datenbank
– Methoden zum Lesen der Daten
• Mapper auflösen
– Aufbereitung der Daten zum Schreiben
→ Model-Service
– Methoden zum Lesen der Daten
→ TableGateway
Mapper und Hydratoren II
• Hydrator kann Eigenschaften eines Objektes
mit Arraydaten befüllen und umgekehrt
– Datenbank → Objekt
– Objekt → Datenbank
– Formulardaten → Objekt
• Beispiele für Hydratoren
– ZendStdlibHydratorArraySerializable
– ZendStdlibHydratorClassMethods
– ZendStdlibHydratorReflection ...
• Einsatz des Hydrator-Service-Managers
Model-Services
• Model-Services nahezu 1:1 migrierbar
– Verknüpfung zum Mapper nicht notwendig
– Stattdessen Abfragen direkt an TableGateway
– Methoden create(), update() und delete()
bereiten Daten für TableGateway vor
– Ggf. Einsatz von ZendPaginator sinnvoll, da mit
Model-Entities kombinierbar
• Ging im ZF1 nicht ohne weiteres
• Instanzierung über Service-Manager
Formulare
• Große Unterschiede zwischen ZF1 und ZF2
– Keine Dekoratoren (schade!)
– Ausgabe per View-Helper
– Kombination mit Input-Filtern, Hydratoren und
Model-Entities möglich
• Alle Formulare von Grund auf neu aufbauen!
• Dazu Input-Filter erstellen, die auch
unabhängig vom Formular verwendbar sind
• Instanzierung über Service-Manager
Fazit
• Selbst für eine gut vorbereitete ZF1
Anwendung ist Migration zum ZF2 aufwändig
• Bei komplexeren Anwendungen ist ein
Schritt-für-Schritt Neubau meist sinnvoll
• Tipp:
– Nicht als erstes ZF2 Projekt ein ZF1 migrieren
– Stattdessen ein neues ZF2 Projekt aufbauen, um
sich einzuarbeiten
Vielen Dank für
Ihre Aufmerksamkeit!
Ralf Eggert
https://profiles.google.com/eggert.ralf

Weitere ähnliche Inhalte

Was ist angesagt?

fn project serverless computing
fn project serverless computingfn project serverless computing
fn project serverless computing
Wolfgang Weigend
 
Dnug35 ak-dev.071111-cookbook
Dnug35 ak-dev.071111-cookbookDnug35 ak-dev.071111-cookbook
Dnug35 ak-dev.071111-cookbook
Ulrich Krause
 
Ant Maven
Ant MavenAnt Maven
Ant Maven
Fabian Lange
 
Automatischer Build mit Maven
Automatischer Build mit MavenAutomatischer Build mit Maven
Automatischer Build mit Maven
Stefan Scheidt
 
EntwicklerCamp 2014 - DOTS reloaded
EntwicklerCamp 2014 - DOTS reloadedEntwicklerCamp 2014 - DOTS reloaded
EntwicklerCamp 2014 - DOTS reloaded
René Winkelmeyer
 
Our way to 19c - DOAG 2020
Our way to 19c - DOAG 2020Our way to 19c - DOAG 2020
Our way to 19c - DOAG 2020
Torsten Kleiber
 
Introduction to Apache Maven 3 (German)
Introduction to Apache Maven 3 (German)Introduction to Apache Maven 3 (German)
Introduction to Apache Maven 3 (German)
Chris Michael Klinger
 
Activiti goes enterprise: Die Evolution der BPM Suite aus Sicht des Alfresco ...
Activiti goes enterprise: Die Evolution der BPM Suite aus Sicht des Alfresco ...Activiti goes enterprise: Die Evolution der BPM Suite aus Sicht des Alfresco ...
Activiti goes enterprise: Die Evolution der BPM Suite aus Sicht des Alfresco ...
Nicole Szigeti
 
Tipps & Tricks für Erweiterungsentwickler - JoomlaDay Deutschland 2014 - Köln
Tipps & Tricks für Erweiterungsentwickler - JoomlaDay Deutschland 2014 - KölnTipps & Tricks für Erweiterungsentwickler - JoomlaDay Deutschland 2014 - Köln
Tipps & Tricks für Erweiterungsentwickler - JoomlaDay Deutschland 2014 - Köln
Viktor Vogel
 
Bob the Builder - Build & Deploy von ADF Enterprise Anwendungen
Bob the Builder - Build & Deploy von ADF Enterprise AnwendungenBob the Builder - Build & Deploy von ADF Enterprise Anwendungen
Bob the Builder - Build & Deploy von ADF Enterprise Anwendungen
Torsten Kleiber
 
Agile Oracle database modeling and development - APEX Connect 2020
Agile Oracle database modeling and development - APEX Connect 2020Agile Oracle database modeling and development - APEX Connect 2020
Agile Oracle database modeling and development - APEX Connect 2020
Torsten Kleiber
 
May the forge be with you
May the forge be with youMay the forge be with you
May the forge be with you
Sandro Sonntag
 

Was ist angesagt? (12)

fn project serverless computing
fn project serverless computingfn project serverless computing
fn project serverless computing
 
Dnug35 ak-dev.071111-cookbook
Dnug35 ak-dev.071111-cookbookDnug35 ak-dev.071111-cookbook
Dnug35 ak-dev.071111-cookbook
 
Ant Maven
Ant MavenAnt Maven
Ant Maven
 
Automatischer Build mit Maven
Automatischer Build mit MavenAutomatischer Build mit Maven
Automatischer Build mit Maven
 
EntwicklerCamp 2014 - DOTS reloaded
EntwicklerCamp 2014 - DOTS reloadedEntwicklerCamp 2014 - DOTS reloaded
EntwicklerCamp 2014 - DOTS reloaded
 
Our way to 19c - DOAG 2020
Our way to 19c - DOAG 2020Our way to 19c - DOAG 2020
Our way to 19c - DOAG 2020
 
Introduction to Apache Maven 3 (German)
Introduction to Apache Maven 3 (German)Introduction to Apache Maven 3 (German)
Introduction to Apache Maven 3 (German)
 
Activiti goes enterprise: Die Evolution der BPM Suite aus Sicht des Alfresco ...
Activiti goes enterprise: Die Evolution der BPM Suite aus Sicht des Alfresco ...Activiti goes enterprise: Die Evolution der BPM Suite aus Sicht des Alfresco ...
Activiti goes enterprise: Die Evolution der BPM Suite aus Sicht des Alfresco ...
 
Tipps & Tricks für Erweiterungsentwickler - JoomlaDay Deutschland 2014 - Köln
Tipps & Tricks für Erweiterungsentwickler - JoomlaDay Deutschland 2014 - KölnTipps & Tricks für Erweiterungsentwickler - JoomlaDay Deutschland 2014 - Köln
Tipps & Tricks für Erweiterungsentwickler - JoomlaDay Deutschland 2014 - Köln
 
Bob the Builder - Build & Deploy von ADF Enterprise Anwendungen
Bob the Builder - Build & Deploy von ADF Enterprise AnwendungenBob the Builder - Build & Deploy von ADF Enterprise Anwendungen
Bob the Builder - Build & Deploy von ADF Enterprise Anwendungen
 
Agile Oracle database modeling and development - APEX Connect 2020
Agile Oracle database modeling and development - APEX Connect 2020Agile Oracle database modeling and development - APEX Connect 2020
Agile Oracle database modeling and development - APEX Connect 2020
 
May the forge be with you
May the forge be with youMay the forge be with you
May the forge be with you
 

Ähnlich wie Migration vom ZF1 zum ZF2 von einfach bis fies (IPC Spring 2013, Berlin)

Zend Framework 2 feat. MongoDB
Zend Framework 2 feat. MongoDBZend Framework 2 feat. MongoDB
Zend Framework 2 feat. MongoDB
Ralf Eggert
 
#PinkDB DataVault
#PinkDB DataVault#PinkDB DataVault
#PinkDB DataVault
Torsten Glunde
 
Ruby und Rails für .NET Entwickler
Ruby und Rails für .NET EntwicklerRuby und Rails für .NET Entwickler
Ruby und Rails für .NET Entwickler
NETUserGroupBern
 
Grails im Überblick und in der Praxis
Grails im Überblick und in der PraxisGrails im Überblick und in der Praxis
Grails im Überblick und in der Praxis
Tobias Kraft
 
WordPress Professional – SEO Campixx
WordPress Professional – SEO CampixxWordPress Professional – SEO Campixx
WordPress Professional – SEO Campixx
Sebastian Blum
 
Ringvorlesung: FIO Systems AG stellt Projektziel zum Thema Software Design Pa...
Ringvorlesung: FIO Systems AG stellt Projektziel zum Thema Software Design Pa...Ringvorlesung: FIO Systems AG stellt Projektziel zum Thema Software Design Pa...
Ringvorlesung: FIO Systems AG stellt Projektziel zum Thema Software Design Pa...
Community ITmitte.de
 
ColdFusion im Enterprise Umfeld - Deep Dive
ColdFusion im Enterprise Umfeld - Deep DiveColdFusion im Enterprise Umfeld - Deep Dive
ColdFusion im Enterprise Umfeld - Deep Dive
Bokowsky + Laymann GmbH
 
Moderner Webentwicklungs-Workflow
Moderner Webentwicklungs-WorkflowModerner Webentwicklungs-Workflow
Moderner Webentwicklungs-Workflow
PLUSPOL interactive GbR
 
Zend Framework 2 kommt bald - und jetzt?
Zend Framework 2 kommt bald - und jetzt?Zend Framework 2 kommt bald - und jetzt?
Zend Framework 2 kommt bald - und jetzt?
Ralf Eggert
 
Zend Framework 2.0
Zend Framework 2.0Zend Framework 2.0
Zend Framework 2.0
Ralf Eggert
 
Zend Framework
Zend FrameworkZend Framework
Zend Framework
luckec
 
Drupal 7 - Domain-Access
Drupal 7 - Domain-AccessDrupal 7 - Domain-Access
Drupal 7 - Domain-Access
Steffen Rühlmann
 
Die Neuerungen in SDL WorldServer 10.4
Die Neuerungen in SDL WorldServer 10.4Die Neuerungen in SDL WorldServer 10.4
Die Neuerungen in SDL WorldServer 10.4
SDL Language Technologies
 
Übersetze mich
Übersetze michÜbersetze mich
Übersetze mich
Dominik
 
Drupal Multisite und Subversion
Drupal Multisite und SubversionDrupal Multisite und Subversion
Drupal Multisite und Subversion
Drupalist
 
PHP5 und Oracle
PHP5 und OraclePHP5 und Oracle
PHP5 und Oracle
Mayflower GmbH
 
IPC2017SE - Zend\Expressive Workshop
IPC2017SE - Zend\Expressive WorkshopIPC2017SE - Zend\Expressive Workshop
IPC2017SE - Zend\Expressive Workshop
Ralf Eggert
 
PrintTalk 2.0, XJDF & WebToPrint
PrintTalk 2.0, XJDF & WebToPrintPrintTalk 2.0, XJDF & WebToPrint
PrintTalk 2.0, XJDF & WebToPrint
Stefan Meissner
 
Unit Testing einer Zend-Framework 2 Anwendung
Unit Testing einer Zend-Framework 2 AnwendungUnit Testing einer Zend-Framework 2 Anwendung
Unit Testing einer Zend-Framework 2 Anwendung
Ralf Eggert
 
BASTA Spring 2016 - Moderne Versionsverwaltung mit Git, und der neue Build-Se...
BASTA Spring 2016 - Moderne Versionsverwaltung mit Git, und der neue Build-Se...BASTA Spring 2016 - Moderne Versionsverwaltung mit Git, und der neue Build-Se...
BASTA Spring 2016 - Moderne Versionsverwaltung mit Git, und der neue Build-Se...
Marc Müller
 

Ähnlich wie Migration vom ZF1 zum ZF2 von einfach bis fies (IPC Spring 2013, Berlin) (20)

Zend Framework 2 feat. MongoDB
Zend Framework 2 feat. MongoDBZend Framework 2 feat. MongoDB
Zend Framework 2 feat. MongoDB
 
#PinkDB DataVault
#PinkDB DataVault#PinkDB DataVault
#PinkDB DataVault
 
Ruby und Rails für .NET Entwickler
Ruby und Rails für .NET EntwicklerRuby und Rails für .NET Entwickler
Ruby und Rails für .NET Entwickler
 
Grails im Überblick und in der Praxis
Grails im Überblick und in der PraxisGrails im Überblick und in der Praxis
Grails im Überblick und in der Praxis
 
WordPress Professional – SEO Campixx
WordPress Professional – SEO CampixxWordPress Professional – SEO Campixx
WordPress Professional – SEO Campixx
 
Ringvorlesung: FIO Systems AG stellt Projektziel zum Thema Software Design Pa...
Ringvorlesung: FIO Systems AG stellt Projektziel zum Thema Software Design Pa...Ringvorlesung: FIO Systems AG stellt Projektziel zum Thema Software Design Pa...
Ringvorlesung: FIO Systems AG stellt Projektziel zum Thema Software Design Pa...
 
ColdFusion im Enterprise Umfeld - Deep Dive
ColdFusion im Enterprise Umfeld - Deep DiveColdFusion im Enterprise Umfeld - Deep Dive
ColdFusion im Enterprise Umfeld - Deep Dive
 
Moderner Webentwicklungs-Workflow
Moderner Webentwicklungs-WorkflowModerner Webentwicklungs-Workflow
Moderner Webentwicklungs-Workflow
 
Zend Framework 2 kommt bald - und jetzt?
Zend Framework 2 kommt bald - und jetzt?Zend Framework 2 kommt bald - und jetzt?
Zend Framework 2 kommt bald - und jetzt?
 
Zend Framework 2.0
Zend Framework 2.0Zend Framework 2.0
Zend Framework 2.0
 
Zend Framework
Zend FrameworkZend Framework
Zend Framework
 
Drupal 7 - Domain-Access
Drupal 7 - Domain-AccessDrupal 7 - Domain-Access
Drupal 7 - Domain-Access
 
Die Neuerungen in SDL WorldServer 10.4
Die Neuerungen in SDL WorldServer 10.4Die Neuerungen in SDL WorldServer 10.4
Die Neuerungen in SDL WorldServer 10.4
 
Übersetze mich
Übersetze michÜbersetze mich
Übersetze mich
 
Drupal Multisite und Subversion
Drupal Multisite und SubversionDrupal Multisite und Subversion
Drupal Multisite und Subversion
 
PHP5 und Oracle
PHP5 und OraclePHP5 und Oracle
PHP5 und Oracle
 
IPC2017SE - Zend\Expressive Workshop
IPC2017SE - Zend\Expressive WorkshopIPC2017SE - Zend\Expressive Workshop
IPC2017SE - Zend\Expressive Workshop
 
PrintTalk 2.0, XJDF & WebToPrint
PrintTalk 2.0, XJDF & WebToPrintPrintTalk 2.0, XJDF & WebToPrint
PrintTalk 2.0, XJDF & WebToPrint
 
Unit Testing einer Zend-Framework 2 Anwendung
Unit Testing einer Zend-Framework 2 AnwendungUnit Testing einer Zend-Framework 2 Anwendung
Unit Testing einer Zend-Framework 2 Anwendung
 
BASTA Spring 2016 - Moderne Versionsverwaltung mit Git, und der neue Build-Se...
BASTA Spring 2016 - Moderne Versionsverwaltung mit Git, und der neue Build-Se...BASTA Spring 2016 - Moderne Versionsverwaltung mit Git, und der neue Build-Se...
BASTA Spring 2016 - Moderne Versionsverwaltung mit Git, und der neue Build-Se...
 

Mehr von Ralf Eggert

PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
PHP Rewrite: Do the right thing (IPC Berlin 2024)
PHP Rewrite: Do the right thing (IPC Berlin 2024)PHP Rewrite: Do the right thing (IPC Berlin 2024)
PHP Rewrite: Do the right thing (IPC Berlin 2024)
Ralf Eggert
 
ChatGPT: unser täglich' Bot gib uns heute
ChatGPT: unser täglich' Bot gib uns heuteChatGPT: unser täglich' Bot gib uns heute
ChatGPT: unser täglich' Bot gib uns heute
Ralf Eggert
 
Der ultimative PHP Framework Vergleich 2023 Edition
Der ultimative PHP Framework Vergleich 2023 EditionDer ultimative PHP Framework Vergleich 2023 Edition
Der ultimative PHP Framework Vergleich 2023 Edition
Ralf Eggert
 
PHP Module als Rundum-Sorglos-Pakete entwickeln
PHP Module als Rundum-Sorglos-Pakete entwickelnPHP Module als Rundum-Sorglos-Pakete entwickeln
PHP Module als Rundum-Sorglos-Pakete entwickeln
Ralf Eggert
 
Alexa, what's next?
Alexa, what's next?Alexa, what's next?
Alexa, what's next?
Ralf Eggert
 
Alexa, wohin geht die Reise
Alexa, wohin geht die ReiseAlexa, wohin geht die Reise
Alexa, wohin geht die Reise
Ralf Eggert
 
8. Hamburg Voice Interface Meetup
8. Hamburg Voice Interface Meetup8. Hamburg Voice Interface Meetup
8. Hamburg Voice Interface Meetup
Ralf Eggert
 
Welcome Bixby
Welcome BixbyWelcome Bixby
Welcome Bixby
Ralf Eggert
 
Alexa Skill Maintenance
Alexa Skill MaintenanceAlexa Skill Maintenance
Alexa Skill Maintenance
Ralf Eggert
 
Vom Zend Framework zu Laminas
Vom Zend Framework zu LaminasVom Zend Framework zu Laminas
Vom Zend Framework zu Laminas
Ralf Eggert
 
Alexa Skills und PHP? Passt das zusammen?
Alexa Skills und PHP? Passt das zusammen?Alexa Skills und PHP? Passt das zusammen?
Alexa Skills und PHP? Passt das zusammen?
Ralf Eggert
 
Mit Jovo von 0 auf 100
Mit Jovo von 0 auf 100Mit Jovo von 0 auf 100
Mit Jovo von 0 auf 100
Ralf Eggert
 
Vom Zend Framework zu Laminas
Vom Zend Framework zu LaminasVom Zend Framework zu Laminas
Vom Zend Framework zu Laminas
Ralf Eggert
 
Alexa for Hospitality
Alexa for HospitalityAlexa for Hospitality
Alexa for Hospitality
Ralf Eggert
 
Alexa, lass uns Geld verdienen – fünf Geschäftsmodelle, die wirklich funktion...
Alexa, lass uns Geld verdienen – fünf Geschäftsmodelle, die wirklich funktion...Alexa, lass uns Geld verdienen – fünf Geschäftsmodelle, die wirklich funktion...
Alexa, lass uns Geld verdienen – fünf Geschäftsmodelle, die wirklich funktion...
Ralf Eggert
 
Fortgeschrittene Techniken für erfolgreiche Sprachanwendungen
Fortgeschrittene Techniken für erfolgreiche SprachanwendungenFortgeschrittene Techniken für erfolgreiche Sprachanwendungen
Fortgeschrittene Techniken für erfolgreiche Sprachanwendungen
Ralf Eggert
 
Die sieben Projektphasen für Voice Projekte
Die sieben Projektphasen für Voice ProjekteDie sieben Projektphasen für Voice Projekte
Die sieben Projektphasen für Voice Projekte
Ralf Eggert
 
Künstliche Intelligenz – Traum und Wirklichkeit
Künstliche Intelligenz – Traum und WirklichkeitKünstliche Intelligenz – Traum und Wirklichkeit
Künstliche Intelligenz – Traum und Wirklichkeit
Ralf Eggert
 
Multi-Modal Voice Development with Amazon Alexa
Multi-Modal Voice Development with Amazon AlexaMulti-Modal Voice Development with Amazon Alexa
Multi-Modal Voice Development with Amazon Alexa
Ralf Eggert
 

Mehr von Ralf Eggert (20)

PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
PHP Rewrite: Do the right thing (IPC Berlin 2024)
PHP Rewrite: Do the right thing (IPC Berlin 2024)PHP Rewrite: Do the right thing (IPC Berlin 2024)
PHP Rewrite: Do the right thing (IPC Berlin 2024)
 
ChatGPT: unser täglich' Bot gib uns heute
ChatGPT: unser täglich' Bot gib uns heuteChatGPT: unser täglich' Bot gib uns heute
ChatGPT: unser täglich' Bot gib uns heute
 
Der ultimative PHP Framework Vergleich 2023 Edition
Der ultimative PHP Framework Vergleich 2023 EditionDer ultimative PHP Framework Vergleich 2023 Edition
Der ultimative PHP Framework Vergleich 2023 Edition
 
PHP Module als Rundum-Sorglos-Pakete entwickeln
PHP Module als Rundum-Sorglos-Pakete entwickelnPHP Module als Rundum-Sorglos-Pakete entwickeln
PHP Module als Rundum-Sorglos-Pakete entwickeln
 
Alexa, what's next?
Alexa, what's next?Alexa, what's next?
Alexa, what's next?
 
Alexa, wohin geht die Reise
Alexa, wohin geht die ReiseAlexa, wohin geht die Reise
Alexa, wohin geht die Reise
 
8. Hamburg Voice Interface Meetup
8. Hamburg Voice Interface Meetup8. Hamburg Voice Interface Meetup
8. Hamburg Voice Interface Meetup
 
Welcome Bixby
Welcome BixbyWelcome Bixby
Welcome Bixby
 
Alexa Skill Maintenance
Alexa Skill MaintenanceAlexa Skill Maintenance
Alexa Skill Maintenance
 
Vom Zend Framework zu Laminas
Vom Zend Framework zu LaminasVom Zend Framework zu Laminas
Vom Zend Framework zu Laminas
 
Alexa Skills und PHP? Passt das zusammen?
Alexa Skills und PHP? Passt das zusammen?Alexa Skills und PHP? Passt das zusammen?
Alexa Skills und PHP? Passt das zusammen?
 
Mit Jovo von 0 auf 100
Mit Jovo von 0 auf 100Mit Jovo von 0 auf 100
Mit Jovo von 0 auf 100
 
Vom Zend Framework zu Laminas
Vom Zend Framework zu LaminasVom Zend Framework zu Laminas
Vom Zend Framework zu Laminas
 
Alexa for Hospitality
Alexa for HospitalityAlexa for Hospitality
Alexa for Hospitality
 
Alexa, lass uns Geld verdienen – fünf Geschäftsmodelle, die wirklich funktion...
Alexa, lass uns Geld verdienen – fünf Geschäftsmodelle, die wirklich funktion...Alexa, lass uns Geld verdienen – fünf Geschäftsmodelle, die wirklich funktion...
Alexa, lass uns Geld verdienen – fünf Geschäftsmodelle, die wirklich funktion...
 
Fortgeschrittene Techniken für erfolgreiche Sprachanwendungen
Fortgeschrittene Techniken für erfolgreiche SprachanwendungenFortgeschrittene Techniken für erfolgreiche Sprachanwendungen
Fortgeschrittene Techniken für erfolgreiche Sprachanwendungen
 
Die sieben Projektphasen für Voice Projekte
Die sieben Projektphasen für Voice ProjekteDie sieben Projektphasen für Voice Projekte
Die sieben Projektphasen für Voice Projekte
 
Künstliche Intelligenz – Traum und Wirklichkeit
Künstliche Intelligenz – Traum und WirklichkeitKünstliche Intelligenz – Traum und Wirklichkeit
Künstliche Intelligenz – Traum und Wirklichkeit
 
Multi-Modal Voice Development with Amazon Alexa
Multi-Modal Voice Development with Amazon AlexaMulti-Modal Voice Development with Amazon Alexa
Multi-Modal Voice Development with Amazon Alexa
 

Migration vom ZF1 zum ZF2 von einfach bis fies (IPC Spring 2013, Berlin)

  • 1. Ralf Eggert | Travello GmbH Migration vom ZF1 zum ZF2 von einfach bis fies
  • 2. Über Ralf Eggert • Dipl. Wirtschaftsinformatiker (FH) • Jahrgang 1972 • GF Travello GmbH • Buchautor zum ZF1 & ZF2 (AW / Galileo) • Kolumnist PHP-Magazin • ZF seit 2006 • Contributor • https://profiles.google.com/eggert.ralf
  • 3. Und Sie? • Erfahrungen ZF1? • Erfahrungen ZF2? • Projekte schon migriert? • Falls nein, warum nicht? • Falls ja, Ihre Erfahrungen?
  • 4. Überblick • Einführung • ZF1 Projekt vorbereiten • ZF2 Skeleton integrieren • Startseite nach ZF2 migrieren • MVC-Layer für Blog Modul migrieren • Authentifizierung & Autorisierung migrieren • Model-Layer für Blog Modul migrieren
  • 6. Ausreden Gründe gegen Migration • Technische Gründe – PHP 5.3 • Betriebswirtschaftliche Gründe – Kunde scheut den Aufwand • Fachliche Gründe – Know-how fehlt • Organisatorische Gründe – Keine Zeit
  • 7. Gründe für Migration • Zend Framework 1 – Keine Weiterentwicklung – Support durch Zend wird 2014 eingestellt • Zend Framework 2 – Stetige Weiterentwicklung – Support durch Zend bis mindestens 2016 • Zend Framework 3 – Kommt in 2014 – Migration von ZF2 nach ZF3 deutlich einfacher
  • 8. Probleme bei Migration • Kein Tool für automatische Migration • Kein Migration Layer (war mal versprochen) • Migration-Guide in der ZF2 Dokumentation fehlte lange und ist jetzt noch unvollständig • ZF1 bietet viele Freiheiten & verlangt keine 100% feste Struktur wie andere Frameworks • Allgemeingültige Schritt-für-Schritt-Anleitung für alle Anwendungen schwer umsetzbar
  • 9. Unterschiede ZF1 und ZF2 I • Genutzte PHP Features – Namespaces – Closures – Late Static Binding • Git / GitHub • Neue Konzepte – »Echte« Modularität – Dependency Injection / Service-Locator – Event-Driven Architecture
  • 10. Unterschiede ZF1 und ZF2 II • ZF1: Convention over Configuration • ZF2: Configuration over Convention • Kein ZendRegistry im ZF2 • Kein ZendApplication im ZF2 • Zend_Controller → ZendMvc • ZendForm: keine Dekorierer (ach menno ;-)) • ZendPdf und ZendService nicht im Core • Viele Internationalisierungskomponenten entfallen wegen Nutzung von ext/intl
  • 11. Unterschiede ZF1 und ZF2 III • Überarbeitete Komponenten – ZendAuthentication, ZendDb, ZendForm, ZendInputFilter, ZendMvc, ZendPermissions, ZendView... • Neue Komponenten – ZendEventManager, ZendModuleManager, ZendServiceManager, ZendDi, ZendStdlib... • Ausgelagerte und entfallene Komponenten – ZendDate, ZendDojo, ZendGdata, ZendLocale, ZendPdf, ZendRegistry, ZendService...
  • 12. »Einfache« Migration • Zend Framework 1.11 oder 1.12 im Einsatz • Empfohlene Projektstruktur wird eingehalten • Anwendung in mehrere Module unterteilt • Wenige eigene Framework-Erweiterungen • View-Skripte verwenden PHP • CSS und JS Frameworks beibehalten • Thin Controllers / Fat Models • Zend_Db_Table nur als Datenquelle verwendet
  • 13. Komplexe Migration • Zend Framework 1.8 bis 1.10 im Einsatz • Projektstruktur teilweise eingehalten • Anwendung unvollständig in Module unterteilt • Einige wesentliche Framework-Erweiterungen • View-Skripte mit gängiger Template-Engine • CSS und JS Frameworks austauschen • Medium Controllers / Medium Models • Zend_Db_Table stark mit Methoden erweitert
  • 14. Fiese Umsetzung • Zend Framework 1.0 bis 1.7 im Einsatz • Empfohlene Projektstruktur ignoriert • Module gar nicht verwendet (Struktur) • Sehr viele Framework-Erweiterungen • View-Skripte setzen HTML_Template_IT ein • Weder CSS noch JS Frameworks vorhanden • Fat Controllers / No Models • Zend_Db_Table wird nicht eingesetzt
  • 15. Lösungsansätze • ZF1 Anwendung in Namensräume portieren – https://github.com/zendframework/Namespacer – Viel manuelle Arbeit erforderlich • ZF1 Library in ZF2 Applikation oder ZF2 Library in ZF1 Applikation verwenden – https://zf2.readthedocs.org/en/latest/ migration/zf1_zf2_parallel.html • ZF1 Anwendung und ZF2 Anwendung parallel laufen lassen
  • 16. Vorgehensweise • ZF1 Projekt vorbereiten – »Default« Modul einrichten – Verzeichnisse umbenennen • ZF2 Projekt integrieren – .htaccess Weiche für ZF1 und ZF2 • Routing beachten • Startseite migrieren • Nacheinander Module umziehen
  • 17. Beispiel ZF1 Anwendung • Setzt folgende Komponenten ein – Zend_Acl, Zend_Auth, Zend_Cache, Zend_Db, Zend_Navigation, Zend_Filter, Zend_Form, Zend_Locale, Zend_Translate, Zend_Validate, ... • Verwendet – Twitter Bootstrap – jQuery – CKEditor – HTMLPurifier
  • 19. Stufe 1 ZF1 Projekt vorbereiten
  • 20. Erste Vorbereitungen • Backup des ZF1 Projektes (!) • Start mit Kopie des gesamten Projektes • Versionsverwaltung verwenden – Fehlerhafte Schritte sind zurück nehmbar – Branches für verschiedene Schritte denkbar • Neue Datenbank oder Kopie erstellen • Neuen Virtual Host einrichten • PHP Upgrade auf mindestens PHP 5.3.3 • Projekt in IDE der Wahl einrichten
  • 21. Modul »Default« einrichten • Pfad /application/modules/default • Klasse Default_Bootstrap erweitert Zend_Application_Module_Bootstrap in Datei Bootstrap.php • Unter /application bleiben Verzeichnis /modules und Datei Bootstrap.php übrig • Alles andere ins »Default« Modul • index.php anpassen für application.ini im »Default« Modul
  • 23. Konfiguration in application.ini • Nicht mehr notwendig – resources.frontController.controllerDirectory • Pfade ggf. für »Default« Modul anpassen – resources.layout.layoutPath – resources.view.basePath – resources.translate.content • Aufnehmen, falls nicht vorhanden – resources.modules[] = "" • Einstellungen für Staging development, production, usw. überprüfen
  • 24. Verzeichnisse umbenennen • Verzeichnisse umbenennen – /application => /application.zf1 – /data => /data.zf1 – /library => /library.zf1 – /tests => /tests.zf1 • Konfiguration für Verzeichnisse anpassen – APPLICATION_PATH in /public/index.php – include_path in /public/index.php – Pfade in application.ini
  • 25. ZF1 Front-Controller-Datei • Datei umbenennen in /public – index.php => index.zf1.php • Konfiguration in .htaccess anpassen RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteRule .* index.zf1.php
  • 26. Anwendung prüfen! • Läuft die Anwendung noch? • Sind alle Module aufrufbar? • Sind alle Seiten des »Default« Moduls aufrufbar (Homepage, usw.)? • Werden alle Seitenbereiche angezeigt? • Was ist mit Übersetzungen? • Macht PHP 5.3 Probleme? • Erst wenn alles läuft, Migration fortsetzen!
  • 27. Stufe 2 ZF2 Skeleton integrieren
  • 28. Skeleton Application downloaden • Als ZIP herunterladen und entpacken – https://github.com/zendframework/ ZendSkeletonApplication • Alle Dateien und Verzeichnisse ins ZF1 Projekt kopieren außer – /public • ZF2 installieren – php composer.phar selfupdate – php composer.phar install
  • 29. ZF2 Front-Controller-Datei • Aus SkeletonApplication ins ZF1 Projekt – index.php => index.zf2.php • PROJECT_PATH, APPLICATION_PATH und APPLICATION_ENV definieren • Konfiguration in .htaccess anpassen RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^application(.*)$ index.zf2.php RewriteCond %{REQUEST_FILENAME} !-f RewriteRule .* index.zf1.php
  • 30. ZF2 Assets • Asset Verzeichnisse ins ZF1 Projekt kopieren – /public/css – /public/img – /public/js • Ggf. auf Dateiüberschreibungen achten – Verschiedene Twitter Bootstrap Versionen? – Verschiedene jQuery Versionen? – Grafiken wie favicon.ico • style.css aus SkeletonApplication ignorieren
  • 31. Anwendung prüfen! • Prüfen, ob alle Seiten aus der alten ZF1 Anwendung korrekt angezeigt werden! • Was passiert beim Aufruf der neuen URL /application? • Wird Twitter Bootstrap, jQuery geladen? • Wenn alles klappt, wird ZF2 Skeleton Application angezeigt • => ZF1 und ZF2 laufen parallel
  • 32. Vorteile dieses Ansatzes • Das alte ZF1 Projekt kann parallel zu neuen ZF2 Features betrieben werden • Features können schrittweise von ZF1 nach ZF2 portiert werden • Wenn alle alten ZF1 Features portiert sind, können .zf1 Verzeichnisse entfernt werden
  • 33. Nachteile dieses Ansatzes • Layouts sind unabhängig – Lösung: Layouts duplizieren • Konfigurierbare Kombination einer Navigation aus ZF1 und ZF2 nur schwer möglich – Lösung: Navigation duplizieren • Ist Nutzer in ZF1 angemeldet, ist geschützter Zugriff auf ZF2 Module erschwert – Lösung: Sessions in Datenbank speichern
  • 34. Routing • Überschneidungen beim Routing vermeiden! • Neue ZF2 Features bekommen neue Routen • Vorhandene ZF1 Routen wiederverwenden, wenn ZF2 Modul ein altes ZF1 Modul ersetzt • Im ZF2 keine »globalen« Routen verwenden • Starter für neue ZF2 Routen müssen in der .htaccess notiert werden
  • 35. Stufe 3 Startseite nach ZF2 migrieren
  • 36. .htaccess anpassen • Anfragen für Homepage auf index.zf2.php umleiten RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^$|^en$ index.zf2.php RewriteRule ^application(.*)$ index.zf2.php RewriteCond %{REQUEST_FILENAME} !-f RewriteRule .* start.zf1.php • Testen!
  • 37. Layout migrieren • Aus dem ZF1 ins ZF2 kopieren • Veränderte View-Helper anpassen • Fehlende View-Helper auskommentieren • Layout hierarchisch? – Header, Footer, Sidebar – Umsetzung z.B. mit ApplicationListener • SkeletonApplication Assets entfernen – CSS Datei style.css & Grafik zfs-logo.png • Testen!
  • 38. Navigation migrieren • ZF1 Navigation – /application.zf1/modules/default/configs/ application.ini • ZF2 Navigation konfigurieren – /module/Application/config/module.config.php – Service nicht vergessen! • Links zur ZF1 Anwendung als URI definieren – Nach Migration der Module ändern • Partial für Ausgabe im Twitter Bootstrap Style • Testen!
  • 39. Translator migrieren I • Dateien der SkeletonApplication löschen – /module/Application/language/* • Übersetzungsdateien kopieren – Von /modules/default/locales/*.php – Nach /module/Application/language/ • Konfiguration in module.config.php ändern • Testen!
  • 40. Translator migrieren II • Fehlende Module unter /module anlegen – /module/ModulName/config/ module.config.php => translator – /module/ModulName/language/ – /module/ModulName/Module.php : getConfig() • Übersetzungsdateien kopieren – Für jedes Modul • Module aktivieren – /config/application.config.php • Testen!
  • 41. Autoloading für ZF1 Dateien I • ClassMap für ZF1 Module erstellen – in /application.zf1/modules • Konfiguration im Application Modul – Module::getAutoloaderConfig() • Wahlweise – include_path in /public/index.php ergänzen mit PROJECT_ROOT . '/library.zf1' – Alle require_once Statements aus den ZF1 Library Dateien entfernen
  • 42. Autoloading für ZF1 Dateien II namespace Application; class Module { public function getAutoloaderConfig() { return array( 'ZendLoaderClassMapAutoloader' => array( 'zf1' => PROJECT_ROOT . '/application.zf1/modules/autoload_classmap.php', ), 'ZendLoaderStandardAutoloader' => array( 'autoregister_zf' => true, 'namespaces' => array( __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__, ), 'prefixes' => array( 'Zend' => PROJECT_ROOT . '/library.zf1/Zend', 'Company' => PROJECT_ROOT . '/library.zf1/Company', ), ), ); } }
  • 43. ZF1 Model-Service in ZF2 nutzen • IndexController in Application Modul greift auf Blog_Service_Article zu • Klasse sollte gefunden werden • Konfigurationsprobleme – cache nicht in Zend_Registry vorhanden – Kein Default Adapter für Zend_Db_Table gesetzt • Lösung: – CompatibilityListener einrichten, um Konfigurationsprobleme zu lösen
  • 44. CompatibilityListener (Auszug) namespace ApplicationListener; class CompatibilityListener implements ListenerAggregateInterface { [...] public function setupZF1Compatibility(EventInterface $e) { $config = new Zend_Config_Ini( PROJECT_PATH . '/application.zf1/modules/default/configs/application.ini', APPLICATION_ENV ); $cacheOptions = $config->resources->cachemanager->database->toArray(); $cache = Zend_Cache::factory( $cacheOptions['frontend']['name' ], $cacheOptions['backend' ]['name' ], $cacheOptions['frontend']['options'], $cacheOptions['backend' ]['options'] ); Zend_Registry::set('cache', $cache); $dbOptions = $config->resources->db->toArray(); $db = Zend_Db::factory($dbOptions['adapter'], $dbOptions['params']); Zend_Db_Table::setDefaultAdapter($db); } }
  • 45. Startseiten View-Skript migrieren I • View-Skript kopieren – Von /application.zf1/modules/default/ views/scripts/index/index.phtml – Nach /module/Application/view/ application/index/index.phtml • Probleme mit View-Helpern – URL View-Helper fehlen Routen – URL View-Helper andere Parameter-Reihenfolge – View-Helper Date und Time fehlen
  • 46. Startseiten View-Skript migrieren II • Eigenen Date View-Helper einrichten – Zur Ausgabe von Datumswerte – Konfiguration für Service-Manager • Alternative – DateFormat View-Helper • Testen!
  • 47. Offene Punkte • Navigation zeigt alle Menüpunkte, da noch keine ACL eingerichtet ist • User Widget fehlt noch in der Seitenleiste • Modul User migrieren • Modul Blog migrieren
  • 49. Zusammenfassung • ZF2 Anwendung kann ZF1 Klassen verwenden • Layout, Navigation, Translator und View- Skript wurden migriert • CompatibilityListener für Migration von Konfigurationseinstellungen • ZF1 Module wurden zum Teil in ZF2 Anwendung eingerichtet • Startseite nutzt Blog_Service_Article
  • 50. Stufe 4 MVC-Layer für Blog Modul migrieren
  • 51. Routing migrieren I • Anfragen für Blog Modul in .htaccess umleiten RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^$|^en$ index.zf2.php RewriteRule ^application(.*)$ index.zf2.php RewriteRule ^(de|en)/blog|beitrag|kategorie |nutzer(.*)$ index.zf2.php RewriteCond %{REQUEST_FILENAME} !-f RewriteRule .* start.zf1.php
  • 52. Routing migrieren II • Jedes ZF2 Modul sollte immer mindestens eine eigene Route haben – Nicht auf eine globale Route verlassen! • Es werden vier Routen benötigt – Generelle Route für Blog Modul – Spezielle Route für Blogbeiträge – Spezielle Route für Beiträge einer Blogkategorie – Spezielle Route für Beiträge eines Nutzers
  • 53. Navigation migrieren • Navigation-Konfiguration aus Application Modul ins Blog Modul verschieben • Seitentyp von uri auf mvc wechseln • Reihenfolge der Menüpunkte durch Parameter order festlegen
  • 54. Controller migrieren I • Controller in module.config.php konfigurieren und mit Routen matchen • Verzeichnis anlegen – /module/Blog/src/Blog/Controller • Controller mit benötigten Methoden anlegen – IndexController mit indexAction(), showAction(), categoryAction(), usw. – AdminController – CategoryController – usw.
  • 55. Controller migrieren II • Code der Aktionsmethoden aus ZF1 Modul übernehmen und anpassen – Parameter holen mit params() Controller-Plugin – Umleitungen für redirect() Plugin anpassen – URL-Generierung für url() Plugin anpassen – Templatevariablen an ViewModel übergeben • Verwendung der ZF1 Model-Services kann vorerst beibehalten werden
  • 56. View-Skripte migrieren • View-Manager konfigurieren, damit View- Skripte gefunden werden können • Verzeichnisse anlegen – /module/Blog/view/blog/index/ – /module/Blog/view/blog/admin/ – /module/Blog/view/blog/category/ • Code der View-Skripte aus ZF1 Modul übernehmen und anpassen – Einsatz der Standard View-Helper überprüfen – Eigene View-Helper migrieren
  • 57. View-Helper migrieren • View-Helper im Modul Blog konfigurieren, damit sie gefunden werden • Im View-Helper darauf achten: – Statt $this->view wie im ZF1 muss im ZF2 $this->getView() verwendet werden – Auf Parameter der Standard View-Helper achten • Url, Translate, usw. • Anwendung testen!
  • 58. Model-Layer & Forms übernehmen • Im Administrationsbereich werden vorerst folgende ZF1 Klassen weiterverwendet – Model-Layer mit Entities, Datenquellen, Mapper und Model-Service – Formulare mit Filtern und Validatoren • Im CompatibilityListener konfigurieren – Zend_Controller_Front benötigt ggf. Instanzen vom Request und Response Objekt – Zend_Translate zur Verwendung mit Zend_Form – Namensräume für eigene Filter und Validatoren
  • 59. CompatibilityListener (Auszug) I namespace ApplicationListener; class CompatibilityListener implements ListenerAggregateInterface { public function setupZF1Compatibility(EventInterface $e) { Zend_Controller_Front::getInstance() ->setRequest(new Zend_Controller_Request_Http()) ->setResponse(new Zend_Controller_Response_Http()) ->setDispatcher(new Zend_Controller_Dispatcher_Standard()); $translations = array(); $applicationConfig = $e->getApplication()->getServiceManager() ->get('ApplicationConfig'); foreach ($applicationConfig['modules'] as $module) { $localesFile = PROJECT_PATH . '/module/' . $module . '/language/' . $e->getRouteMatch()->getParam('lang') . '.php'; if (file_exists($localesFile)) { $translations = array_merge($translations, include $localesFile); ksort($translations); } } [...]
  • 60. CompatibilityListener (Auszug) II [...] $translator = new Zend_Translate(array( 'adapter' => 'Array', 'content' => $localesFile, 'locale' => $e->getRouteMatch()->getParam('lang'), )); $translator->addTranslation( $translations, $e->getRouteMatch()->getParam('lang') ); Zend_Form::setDefaultTranslator($translator); Zend_Filter::addDefaultNamespaces('Company_Filter'); Zend_Validate::addDefaultNamespaces('Company_Validate'); } }
  • 61. Weitere Migrationen • AdminController zum Pflegen der Blogbeiträge inkl. der View-Skripts • CategoryController zum Pflegen der Blogkategorien inkl. der View-Skripts • ZF1 Formulare benötigen für Ausgabe eine Zend_View Instanz! • Testen!
  • 62. Zusammenfassung • Blog Modul läuft auf ZF2 mit einigen Einschränkungen – Verwendet noch ZF1 Model-Layer – Verwendet noch ZF1 Formulare – Verwendet noch ZF1 Filter und Validatoren – Ist abhängig vom CompatibilityListener
  • 64. User-Widget migrieren • View-Helper migrieren • Anfragen zum Einloggen auf ZF1 User Modul umleiten • View-Helper konfigurieren • UserWidget in Seitenleiste ausgeben
  • 65. Authentifizierung • CompatibilityListener konfiguriert Zend_Session für ZF1 Authentifizierung – Konfiguration aus application.ini holen – SaveHandler einrichten – Session konfigurieren – Zend_Auth Instanz im Service-Manager als Service »UserAuthentication« speichern
  • 66. CompatibilityListener (Auszug) namespace ApplicationListener; class CompatibilityListener implements ListenerAggregateInterface { public function setupZF1Compatibility(EventInterface $e) { [...] $sessionOptions = $config->resources->session->toArray(); $saveHandlerClass = $sessionOptions['saveHandler']['class']; $saveHandler = new $saveHandlerClass( $sessionOptions['saveHandler']['options'] ); unset($sessionOptions['saveHandler']); Zend_Session::setOptions($sessionOptions); Zend_Session::setSaveHandler($saveHandler); $e->getApplication()->getServiceManager() ->setService('UserAuthentication', Zend_Auth::getInstance()); } }
  • 67. Autorisierung • Konfiguration der Benutzerrechte in den module.config.php Dateien der Module • Erstellung von UserAclAcl, die ZendAcl erweitert und ACL-Konfiguration verarbeitet • Factory für UserAclAcl • AuthorizationListener zum Prüfen der Benutzerrechte mit ACL und der Rolle – Bei fehlenden Rechten Umleitung auf forbidden Seite des ZF1 User Moduls
  • 68. ACL mit Navigation kombinieren • Konfiguration der Navigation mit Parametern resource und privilege erweitern • Navigation-Konfiguration auf MVC Seiten umstellen • Navigation für User Modul ins Modul • Erweiterung vom AuthorizationListener zur Übergabe der aktuellen Zend_Auth Rolle sowie ACL an Navigation View-Helper
  • 69. Zusammenfassung • ZF2 der Anwendung nutzt Authentifizierung des ZF1 User Moduls • ZF2 der Anwendung stellt Autorisierung selber bereit (wegen ZendNavigation) • User-Widget leitet entsprechend auf ZF1 User Modul um • Später kann gesamtes User Modul migriert werden
  • 70. Stufe 6 Model-Layer für Blog Modul migrieren
  • 71. Model-Entities • Model-Entities nahezu 1:1 migrierbar • Umschreibung auf Namensräume sinnvoll • ZendStdlibArraySerializableInterface – Implementation sinnvoll – Für Einsatz mit Hydratoren • Instanzierung über Service-Manager
  • 72. Table-Gateways • ZendDbTableGatewayTableGateway als Datenquelle implementieren • Einsatz eines ResultSets mit Hydratoren, um Instanzen der Model-Entities zu erhalten • Abfragen von Daten als Methoden mithilfe von ZendDbSqlSql implementieren • Ansonsten nicht zu viel Logik implementieren • Instanzierung über Service-Manager
  • 73. Mapper und Hydratoren I • Aufgaben des Mappers – Übergabe Arraydaten an Objekt und umgekehrt – Aufbereitung Daten zum Schreiben in Datenbank – Methoden zum Lesen der Daten • Mapper auflösen – Aufbereitung der Daten zum Schreiben → Model-Service – Methoden zum Lesen der Daten → TableGateway
  • 74. Mapper und Hydratoren II • Hydrator kann Eigenschaften eines Objektes mit Arraydaten befüllen und umgekehrt – Datenbank → Objekt – Objekt → Datenbank – Formulardaten → Objekt • Beispiele für Hydratoren – ZendStdlibHydratorArraySerializable – ZendStdlibHydratorClassMethods – ZendStdlibHydratorReflection ... • Einsatz des Hydrator-Service-Managers
  • 75. Model-Services • Model-Services nahezu 1:1 migrierbar – Verknüpfung zum Mapper nicht notwendig – Stattdessen Abfragen direkt an TableGateway – Methoden create(), update() und delete() bereiten Daten für TableGateway vor – Ggf. Einsatz von ZendPaginator sinnvoll, da mit Model-Entities kombinierbar • Ging im ZF1 nicht ohne weiteres • Instanzierung über Service-Manager
  • 76. Formulare • Große Unterschiede zwischen ZF1 und ZF2 – Keine Dekoratoren (schade!) – Ausgabe per View-Helper – Kombination mit Input-Filtern, Hydratoren und Model-Entities möglich • Alle Formulare von Grund auf neu aufbauen! • Dazu Input-Filter erstellen, die auch unabhängig vom Formular verwendbar sind • Instanzierung über Service-Manager
  • 77. Fazit • Selbst für eine gut vorbereitete ZF1 Anwendung ist Migration zum ZF2 aufwändig • Bei komplexeren Anwendungen ist ein Schritt-für-Schritt Neubau meist sinnvoll • Tipp: – Nicht als erstes ZF2 Projekt ein ZF1 migrieren – Stattdessen ein neues ZF2 Projekt aufbauen, um sich einzuarbeiten
  • 78. Vielen Dank für Ihre Aufmerksamkeit! Ralf Eggert https://profiles.google.com/eggert.ralf