SlideShare ist ein Scribd-Unternehmen logo
1 von 55
Downloaden Sie, um offline zu lesen
Ralf Eggert | Travello GmbH

Zend Framework 2 - Best Practices

Quelle: DASPRiD / flickr
Über Ralf Eggert
• Geschäftsführer Travello GmbH
• Buchautor & Kolumnist
– Zend Framework 1 (Addison-Wesley)
– Zend Framework 2 (Galileo Computing)
– PHP Magazin

• Zend Framework seit 2006
• Contributor, Speaker, Trainer
– http://www.ralfeggert.de/
– http://www.zendframeworkschulung.de/
Drei Fragen an das Publikum?
• Wer
– hat Erfahrungen mit dem Zend Framework 2?
– entwickelt an einem Zend Framework 2 Projekt?
– hat ein ZF2 Projekt im Live-Betrieb?
MVC

Quelle: D. Braun / pixelio.de
Model-View-Controller
• Entwurfsmuster
– Model: Business Logik
– View: Präsentationslogik
– Controller: Steuerungslogik

• Warum MVC?
– Übersichtlichkeit
– Testbarkeit
– Wartbarkeit

• Paradigma
– »Thin Controllers / Fat Models«
Bestandteile einer ZF2 Anwendung
• Entitäten
• Hydratoren

• Controller
• Controller-Plugins

• TableGateways
• Formulare
• InputFilter
• Filter
• Validatoren

• View-Skripte
• View-Helper
Bad Practice: MVC
Filter
Filter
Filter

Formular

Input
Filter
Validator

Request

Validator

Controller

Validator

Manuela
Peter

Datenbank

Klaus
Entität

Response

View

ViewSkripte

ViewHelper
Lösung: Model-Services einführen
• Model-Services
• Entitäten
• Hydratoren

• Controller
• Controller-Plugins

• TableGateways
• Formulare
• InputFilter
• Filter
• Validatoren

• View-Skripte
• View-Helper
Better Practice: Controller & Model-Service

ModelService

Request

Controller

Formular

Response

View
Better Practice: Model mit Model-Service

Controller

Manuela

Filter
Filter

Peter

Filter

Klaus
Entität

Hydrator

Model
Service

Input
Filter

Validator
Validator

Datenbank

Validator
Better Practice: View mit Model-Service

Controller

View

ViewSkripte

Response

ViewHelper

nur lesend!

Model
Service
Vorteile einer sauberen Trennung
• Alles hat seinen Platz
• Model-Service verwendbar von
– Webanwendung
– Cron-Job
– RESTful Webservice
– Javascript-Anwendung

• Datenvalidierung nicht an Formular gekoppelt
Verschiedene Datenspeicher

ZF2
TableGateway
Doctrine
ORM

Controller

ModelService
Dateisystem
REST
SOAP
XML-RPC
Module

Quelle: Carsten Jünger / pixelio.de
Zend Framework 2 Module
• Anwendungsspezifische Module
– Verzeichnis /module

• Fremdmodule
– Verzeichnis /vendor

• Unternehmensmodule
– Verzeichnis /corporate
– Oder Unternehmensname, z.B. /travello

• Module können aufeinander aufbauen
• Module können andere erweitern
Abhängigkeiten von ZF2 Modulen I
• Beispiel: Modul Application
• Funktionen
– Layout
– Fehlerseiten
– Module laden
– Konfiguration (z.B. Navigation)

• Zugriff für andere Module
– Ergänzende Konfiguration z.B. für ZendNavigation

• Zugriff auf andere Module
– Widgets über View-Helper aufrufen
Abhängigkeiten von ZF2 Modulen II
• Beispiel: Modul User
• Funktionen
– Registrierung
– Authentifizierung
– Autorisierung
– Event-Listener

• Zugriff für andere Module
– View-Helper: userIsAllowed und userWidget
– Controller-Plugin: userIsAllowed

• Direkten Zugriff auf Services vermeiden
Wiederverwendbarkeit
• Jedes Modul braucht eigene Routen
• .dist Datei für Konfiguration
– Für /config/autoload Verzeichnis

• Generalisiertes Markup im View verwenden
– Twitter Bootstrap
– Eigene CSS Struktur

• Abhängigkeiten zu anderen Modulen reduzieren
• Anderen Module Zugriff ermöglichen
– View-Helper
– Controller Plugins
Fremdmodule
• http://modules.zendframework.com/
• https://github.com/ZF-Commons
• https://github.com/zfcampus
• Beispiele:
– ZfcUser / ZfcUser2
– DoctrineModule
– DoctrineORMModule
– ZendDeveloperTools
– BjyProfiler
ZF2 Module - Best Practices
• Modulkonfiguration cachen!
– Achtung! Nur getConfig() wird gecached

• Jedes Modul konfiguriert eigenes Routing
– Vermeiden: Keine einzelne Route für alle Module

• onBootstrap() und init() sparsam nutzen
• Nicht überladen: module.config.php
– Konfigurationsdaten für Schuhgrößen, Währungskurse,
Bildgrößen, finnische Biermarken usw. auslagern

• Unternehmensmodule wiederverwenden
Service-Manager

Quelle: neurolle - Rolf / pixelio.de
Service Locator
• Service-Locator
– Entwurfsmuster

• Service-Manager
– Konkrete Implementation

• Aufgaben
– Instanziierung von Objekten / Services
– Bereitstellung der Instanzen zur Wiederverwendung
Spezialisierte Service-Manager

ServiceManager
Controller
Loader

Route-Plugin
Loader

Controller-Plugin
Manager

Serializer-Adapter
Manager

View-Helper
Manager

Hydrator
Manager

Validator
Manager

Filter
Manager
Form-Element
Manager

Input-Filter
Manager
Beispiel Factory (mit kleiner Unschärfe)
// Datei /module/Customer/src/Customer/Form/CustomerFormFactory.php
namespace CustomerForm;
use ZendServiceManagerFactoryInterface;
use ZendServiceManagerServiceLocatorInterface;
class CustomerFormFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $formElementManager)
{
$serviceLocator
= $formElementManager->getServiceLocator();
$hydratorManager
= $serviceLocator->get('HydratorManager');
$inputFilterManager = $serviceLocator->get('InputFilterManager');
$filter = $inputFilterManager->get('CustomerCustomerFilter');
$config = $inputFilterManager->getServiceLocator()->get('Config');
$form = new CustomerForm($config['country_options']);
$form->setHydrator($hydratorManager->get('ArraySerializable'));
$form->setInputFilter($filter);
return $form;
}
}
Beispiel Factory (verbessert)
// Datei /module/Customer/src/Customer/Form/CustomerFormFactory.php
namespace CustomerForm;
use ZendServiceManagerFactoryInterface;
use ZendServiceManagerServiceLocatorInterface;
class CustomerFormFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $formElementManager)
{
$serviceLocator
= $formElementManager->getServiceLocator();
$hydratorManager
= $serviceLocator->get('HydratorManager');
$inputFilterManager = $serviceLocator->get('InputFilterManager');
$filter = $inputFilterManager->get('CustomerCustomerFilter');
$config = $serviceLocator->get('Config');
$form = new CustomerForm($config['country_options']);
$form->setHydrator($hydratorManager->get('ArraySerializable'));
$form->setInputFilter($filter);
return $form;
}
}
Konfiguration (Auszug)
// Datei /module/Customer/config/module.config.php
return array(
'input_filters' => array(
'invokables' => array(
'CustomerCustomerFilter'
),
'shared' => array(
'CustomerCustomerFilter'
),
),

=> 'CustomerInputFilterCustomerFilter',
=> true,

'form_elements' => array(
'invokables' => array(
'CustomerAddressFieldset' => 'CustomerFormCustomerAddressFieldset',
),
'factories' => array(
'CustomerCustomerForm'
=> 'CustomerFormCustomerFormFactory',
),
'shared' => array(
'CustomerCustomerForm'
=> true,
),
),
);
Service Manager - Best Practices
• Spezialisierte Service-Manager nutzen
• ServiceLocatorAwareInterface meiden
• Service-Manager niemals injizieren! Nein, nie!
• new möglichst nur in Factories verwenden
• Initializer sparsam einsetzen
• Abstract Factories sparsam einsetzen
• Factory Closures in Konfigurationsdateien
verhindern Caching
• ZendServiceManager schneller als ZendDi
Event-Manager

Quelle: Rainer Sturm / pixelio.de
Event-Manager im MVC
• MVC Events
– »bootstrap«
– »route«
– »dispatch« / »dispatch.error«
– »render« / »render.error«
– »finish«

• Mvc Events für eigene Zwecke verwenden
– Nach »route« Event Sprache der Anwendung festlegen
– Nach »dispatch.error« Event Fehlermeldungen loggen
– Vor »finish« Event HTML aufräumen / minifizieren
Event-Manager im Model-Service
// Datei /module/Order/src/Order/Service/OrderService.php
namespace OrderService;
use ZendEventManagerEventManagerInterface;
use ZendDebugDebug;
class OrderService
{
protected $eventManager;
public function setEventManager(EventManagerInterface $eventManager)
{
$eventManager->setIdentifiers(array(__CLASS__);
$this->eventManager = $eventManager;
}
public function getEventManager()
{
return $this->eventManager;
}
public function saveOrder($id)
{
$this->getEventManager()->trigger('preOrder', __CLASS__, array('id' => $id));
Debug::dump('Save order ' . $id);
$this->getEventManager()->trigger('postOrder', __CLASS__, array('id' => $id));
}
}
Event-Manager konfigurieren
use ZendDebugDebug;
use ZendEventManagerEventManager;
use OrderServiceOrderService;
$eventManager = new EventManager();
$eventManager->attach('postOrder', function ($e) {
Debug::dump('Update stock');
}, 100);
$eventManager->attach('postOrder', function ($e) {
Debug::dump('Send order confirmation');
}, 300);
$eventManager->attach('preOrder', function ($e) {
Debug::dump('Check stock');
});
$orderService = new OrderService();
$orderService->setEventManager($eventManager);
$orderService->saveOrder('12345');
// output
string 'Check stock' (length=11)
string 'Save order 12345' (length=16)
string 'Send order confirmation' (length=23)
string 'Update stock' (length=12)
Event Manager - Best Practices
• Eindeutige Identifier verwenden (Klassenname)
• SharedEventManager
– Fallback für alle Event-Manager Instanzen
– Events für nicht existente Objekte registrieren

• EventManagerAwareInterface
• Listener
– Aggregat-Klassen (ListenerAggregateInterface)
– Closures
Formularverarbeitung

Quelle: Matthias Preisinger / pixelio.de
Formularverarbeitung
• InputFilter
– ZendInputFilterInputFilter erweitern
– Input-Elemente in init() per Factory hinzufügen
– Hierarchische InputFilter möglich

• Formulare
– ZendFormForm erweitern
– Formularelemente in init() per Factory hinzufügen
– Hierarchie durch Fieldsets umsetzbar
Konfiguration Filter & Validatoren
// Datei /module/Customer/config/module.config.php
return array(
'filters' => array(
'invokables' => array(
'CustomerAddress' => 'CustomerFilterAddressFilter',
),
),
'validators' => array(
'invokables' => array(
'CustomerCountry' => 'CustomerValidatorCountryValidator',
),
),
);
Beispiel InputFilter
// Datei /module/Customer/src/Customer/InputFilter/CustomerFilter.php
namespace CustomerInputFilter;
use ZendInputFilterInputFilter;
class CustomerFilter extends InputFilter
{
public function init()
{
$this->add(array(
'name'
=> 'address',
'filters'
=> array(
array('name' => 'CustomerAddress'),
),
));
$this->add(array(
'name'
=> 'country',
'validators' => array(
array('name' => 'CustomerCountry'),
),
));
}
}
Formularverarbeitung - Best Practices
• Validierung und Formularanzeige trennen
– Im Model-Service mit InputFilter validieren
– Im Controller Formular bereitstellen

• Controller
– Plugin PostRedirectGet
– Plugin FilePostRedirectGet

• Spezialisierte Service-Manager verwenden
Application-Management

Quelle: Helene Souza / wikimedia
Application-Management
• Management des Lebenszyklus der Anwendung
• Mehrere Stufen (DTAP)
– Development
– Testing
– Acceptance
– Production

• Weiche in /public/index.php
• Pro Stufe eigene Konfiguration
Application-Management Weiche
// Datei /public/index.php
define('APPLICATION_ENV',

(getenv('APPLICATION_ENV')
? getenv('APPLICATION_ENV')
: 'production'));

define('APPLICATION_ROOT', realpath(__DIR__ . '/..'));
require_once '../vendor/autoload.php';
chdir(dirname(__DIR__));
switch (APPLICATION_ENV) {
case 'production':
$configFile = APPLICATION_ROOT . '/config/production.config.php';
break;
case 'development':
default:
$configFile = APPLICATION_ROOT . '/config/development.config.php';
break;
}
ZendMvcApplication::init(include $configFile)->run();
Development Konfiguration
// Datei /config/development.config.php
return array(
'modules' => array(
'Application',
'User',
'Cms',
'Blog',
'ZendDeveloperTools',
),
'module_listener_options' => array(
'config_glob_paths' => array(
'config/autoload/{,*.}{production,development,local}.php',
),
'module_paths' => array(
'./module',
'./vendor',
),
),
);
Production Konfiguration
// Datei /config/production.config.php
return array(
'modules' => array(
'Application',
'User',
'Cms',
),
'module_listener_options' => array(
'config_glob_paths' => array(
'config/autoload/{,*.}{production}.php',
),
'module_paths' => array(
'./module',
'./vendor',
),
'cache_dir'
=> './data/cache',
'config_cache_enabled'
=> false,
'config_cache_key'
=> 'module_config_cache',
'module_map_cache_enabled' => false,
'module_map_cache_key'
=> 'module_map_cache',
),
);
Performance

Quelle: günther gumhold / pixelio.de
ZF2 Performance
• Modulkonfiguration cachen
– Closures nicht cachebar
– Achtung: Nur getConfig() wird gecached

• ClassMaps und TemplateMaps einsetzen
– Generator Skripte in /vendor/bin

• Möglichst wenige parallele Routen
• Fremdmodule
– EdpSuperluminal
– SpiffyNavigation
– OcraCachedViewResolver
Performancebremsen
• Größte Performancebremsen in Anwendung
– Ineffiziente Datenbankabfragen
– Nicht performante Berechnungen
– Gelesene Daten werden nicht gecached

• Generell
– Einsatz eines Frameworks immer langsamer als
prozedurale Skripte

• Tipp
– Eigenen Suchindex aufbauen
Security

Quelle: piu700 / pixelio.de
ZF2 Komponenten für Security
• Authentifizierung / Autorisierung
– ZendAuthentication
– ZendPermissions
– ZendCaptcha

• »Filter Input, Escape Output«
– ZendFilter
– ZendValidator
– ZendInputFilter
– ZendEscaper

• Sichere Zufallswerte
– ZendMath
Einsatzzwecke
• Passwörter verschlüsseln
– MD5 Hashes sind nicht sicher!
– ZendCryptPasswordBcrypt

• XSS vermeiden
– Daten filtern und escapen

• SQL Injection vermeiden
– Mit ZendDbSql sicherer implementieren

• Cross Site Request Forgery
– ZendFormElementCsrf einsetzen
Migration vom ZF1

Quelle: sokaeiko / pixelio.de
Probleme bei Migration vom ZF1
• Kein Tool für automatische Migration
• Kein Migration Layer
• Migration-Guide in ZF2 Doku 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
• Kein ZF-spezifisches Problem
Migration ZF1 nach ZF2
• ZF1 und ZF2 parallel betreiben
• Weiche in .htaccess einrichten
• ZF2 Module müssen ZF1 Routing beachten
• Modul für Modul migrieren
• »Fat Models« leichter migrierbar
• »Fat Controller« schwerer migrierbar
• Weitere Quellen
– Artikel im PHP Magazin 6/2013 (Teil 1)
– IPC Spring Session: http://goo.gl/dgl8zH
Weiche in .htaccess
// Datei /public/.htaccess
RewriteEngine

on

# Slash am Ende entfernen
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
# Umschreiberegeln für ZF2
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^$ index.zf2.php
RewriteRule ^customer(.*)$ index.zf2.php
RewriteRule ^order(.*)$ index.zf2.php
RewriteRule ^cms(.*)$ index.zf2.php
# Umschreiberegeln für ZF1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.zf1.php
Das ZF3 kommt
demnächst in diesem Kino

Quelle: DASPRiD / flickr
Fragen?!

Quelle: Tony Hegewald / pixelio.de
Ralf Eggert | Travello GmbH

Vielen Dank für Eure Aufmerksamkeit

Quelle: DASPRiD / flickr

Weitere ähnliche Inhalte

Was ist angesagt?

Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...
Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...
Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...Gregor Biswanger
 
Automatischer Build mit Maven - OPITZ CONSULTING - Stefan Scheidt
Automatischer Build mit Maven - OPITZ CONSULTING - Stefan ScheidtAutomatischer Build mit Maven - OPITZ CONSULTING - Stefan Scheidt
Automatischer Build mit Maven - OPITZ CONSULTING - Stefan ScheidtOPITZ CONSULTING Deutschland
 
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
 
Building Enterprise Applications with AngularJS (GDG DevFest Karlsruhe 2014)
Building Enterprise Applications with AngularJS (GDG DevFest Karlsruhe 2014)Building Enterprise Applications with AngularJS (GDG DevFest Karlsruhe 2014)
Building Enterprise Applications with AngularJS (GDG DevFest Karlsruhe 2014)Christian Janz
 
Maven2 - Die nächste Generation des Buildmanagements?
Maven2 - Die nächste Generation des Buildmanagements?Maven2 - Die nächste Generation des Buildmanagements?
Maven2 - Die nächste Generation des Buildmanagements?Thorsten Kamann
 
Electron.NET: Cross-Platform Desktop Software mit ASP.NET Core
Electron.NET: Cross-Platform Desktop Software mit ASP.NET CoreElectron.NET: Cross-Platform Desktop Software mit ASP.NET Core
Electron.NET: Cross-Platform Desktop Software mit ASP.NET CoreGregor Biswanger
 
Spring Boot - Wird Spring jetzt wirklich einfach?
Spring Boot - Wird Spring jetzt wirklich einfach?Spring Boot - Wird Spring jetzt wirklich einfach?
Spring Boot - Wird Spring jetzt wirklich einfach?jenspresser
 
ESEconf2011 - Bosch Andy: "JavaServer Faces im Portal - Statusbestimmung"
ESEconf2011 - Bosch Andy: "JavaServer Faces im Portal - Statusbestimmung"ESEconf2011 - Bosch Andy: "JavaServer Faces im Portal - Statusbestimmung"
ESEconf2011 - Bosch Andy: "JavaServer Faces im Portal - Statusbestimmung"Aberla
 

Was ist angesagt? (11)

Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...
Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...
Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...
 
Automatischer Build mit Maven - OPITZ CONSULTING - Stefan Scheidt
Automatischer Build mit Maven - OPITZ CONSULTING - Stefan ScheidtAutomatischer Build mit Maven - OPITZ CONSULTING - Stefan Scheidt
Automatischer Build mit Maven - OPITZ CONSULTING - Stefan Scheidt
 
Introduction to Apache Maven 3 (German)
Introduction to Apache Maven 3 (German)Introduction to Apache Maven 3 (German)
Introduction to Apache Maven 3 (German)
 
Workshop: Besseres C#
Workshop: Besseres C#Workshop: Besseres C#
Workshop: Besseres C#
 
Building Enterprise Applications with AngularJS (GDG DevFest Karlsruhe 2014)
Building Enterprise Applications with AngularJS (GDG DevFest Karlsruhe 2014)Building Enterprise Applications with AngularJS (GDG DevFest Karlsruhe 2014)
Building Enterprise Applications with AngularJS (GDG DevFest Karlsruhe 2014)
 
Maven2 - Die nächste Generation des Buildmanagements?
Maven2 - Die nächste Generation des Buildmanagements?Maven2 - Die nächste Generation des Buildmanagements?
Maven2 - Die nächste Generation des Buildmanagements?
 
Electron.NET: Cross-Platform Desktop Software mit ASP.NET Core
Electron.NET: Cross-Platform Desktop Software mit ASP.NET CoreElectron.NET: Cross-Platform Desktop Software mit ASP.NET Core
Electron.NET: Cross-Platform Desktop Software mit ASP.NET Core
 
Einblicke in Zend Server Cluster Manager
Einblicke in Zend Server Cluster ManagerEinblicke in Zend Server Cluster Manager
Einblicke in Zend Server Cluster Manager
 
Einführung Maven
Einführung MavenEinführung Maven
Einführung Maven
 
Spring Boot - Wird Spring jetzt wirklich einfach?
Spring Boot - Wird Spring jetzt wirklich einfach?Spring Boot - Wird Spring jetzt wirklich einfach?
Spring Boot - Wird Spring jetzt wirklich einfach?
 
ESEconf2011 - Bosch Andy: "JavaServer Faces im Portal - Statusbestimmung"
ESEconf2011 - Bosch Andy: "JavaServer Faces im Portal - Statusbestimmung"ESEconf2011 - Bosch Andy: "JavaServer Faces im Portal - Statusbestimmung"
ESEconf2011 - Bosch Andy: "JavaServer Faces im Portal - Statusbestimmung"
 

Andere mochten auch

Best Practices with Zend Framework - Matthew Weier O'Phinney
Best Practices with Zend Framework - Matthew Weier O'PhinneyBest Practices with Zend Framework - Matthew Weier O'Phinney
Best Practices with Zend Framework - Matthew Weier O'Phinneydpc
 
Using Zend Framework 2 Book Presentation
Using Zend Framework 2 Book PresentationUsing Zend Framework 2 Book Presentation
Using Zend Framework 2 Book Presentationolegkrivtsov
 
Zend Framework 2 - Basic Components
Zend Framework 2  - Basic ComponentsZend Framework 2  - Basic Components
Zend Framework 2 - Basic ComponentsMateusz Tymek
 
MVC with Zend Framework
MVC with Zend FrameworkMVC with Zend Framework
MVC with Zend Frameworkwebholics
 

Andere mochten auch (7)

Best Practices with Zend Framework - Matthew Weier O'Phinney
Best Practices with Zend Framework - Matthew Weier O'PhinneyBest Practices with Zend Framework - Matthew Weier O'Phinney
Best Practices with Zend Framework - Matthew Weier O'Phinney
 
Using Zend Framework 2 Book Presentation
Using Zend Framework 2 Book PresentationUsing Zend Framework 2 Book Presentation
Using Zend Framework 2 Book Presentation
 
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJSZend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
 
Zend Framework 2 - Basic Components
Zend Framework 2  - Basic ComponentsZend Framework 2  - Basic Components
Zend Framework 2 - Basic Components
 
Why MVC?
Why MVC?Why MVC?
Why MVC?
 
Model View Controller (MVC)
Model View Controller (MVC)Model View Controller (MVC)
Model View Controller (MVC)
 
MVC with Zend Framework
MVC with Zend FrameworkMVC with Zend Framework
MVC with Zend Framework
 

Ähnlich wie Zend Framework 2 - Best Practices

Zend Framework 2 feat. MongoDB
Zend Framework 2 feat. MongoDBZend Framework 2 feat. MongoDB
Zend Framework 2 feat. MongoDBRalf Eggert
 
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 AnwendungRalf Eggert
 
WPF Dos n Don'ts - der WPF Rundumschlag
WPF Dos n Don'ts - der WPF RundumschlagWPF Dos n Don'ts - der WPF Rundumschlag
WPF Dos n Don'ts - der WPF RundumschlagHendrik Lösch
 
PHP-Module in statischen Seiten - Architektur-Ansätze
PHP-Module in statischen Seiten - Architektur-AnsätzePHP-Module in statischen Seiten - Architektur-Ansätze
PHP-Module in statischen Seiten - Architektur-AnsätzeRalf Lütke
 
JavaScript goes Enterprise - Node.js-Anwendungen mit Visual Studio und den No...
JavaScript goes Enterprise - Node.js-Anwendungen mit Visual Studio und den No...JavaScript goes Enterprise - Node.js-Anwendungen mit Visual Studio und den No...
JavaScript goes Enterprise - Node.js-Anwendungen mit Visual Studio und den No...Peter Hecker
 
Qualitätssicherung in Webprojekten
Qualitätssicherung in WebprojektenQualitätssicherung in Webprojekten
Qualitätssicherung in WebprojektenSebastian Springer
 
Modulare Enterprise Systeme - Eine Einführung
Modulare Enterprise Systeme - Eine EinführungModulare Enterprise Systeme - Eine Einführung
Modulare Enterprise Systeme - Eine EinführungAndreas Weidinger
 
Drupal Austria Roadshow in Klagenfurt
Drupal Austria Roadshow in KlagenfurtDrupal Austria Roadshow in Klagenfurt
Drupal Austria Roadshow in Klagenfurtdasjo
 
Agile Softwareentwicklung mit Rails
Agile Softwareentwicklung mit RailsAgile Softwareentwicklung mit Rails
Agile Softwareentwicklung mit RailsHussein Morsy
 
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 PraxisTobias Kraft
 
Wie programmiere Ich ein Modul? Erste Schritte.
Wie programmiere Ich ein Modul? Erste Schritte.Wie programmiere Ich ein Modul? Erste Schritte.
Wie programmiere Ich ein Modul? Erste Schritte.flagbit
 
AdminCam 2017 IBM Connections Troubleshooting
AdminCam 2017 IBM Connections  TroubleshootingAdminCam 2017 IBM Connections  Troubleshooting
AdminCam 2017 IBM Connections TroubleshootingNico Meisenzahl
 
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?adesso AG
 
2007 - Basta!: Nach soa kommt soc
2007 - Basta!: Nach soa kommt soc2007 - Basta!: Nach soa kommt soc
2007 - Basta!: Nach soa kommt socDaniel Fisher
 
Fanstatic pycon.de 2012
Fanstatic pycon.de 2012Fanstatic pycon.de 2012
Fanstatic pycon.de 2012Daniel Havlik
 

Ähnlich wie Zend Framework 2 - Best Practices (20)

Zend Framework 2 feat. MongoDB
Zend Framework 2 feat. MongoDBZend Framework 2 feat. MongoDB
Zend Framework 2 feat. MongoDB
 
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
 
#PinkDB DataVault
#PinkDB DataVault#PinkDB DataVault
#PinkDB DataVault
 
WPF Dos n Don'ts - der WPF Rundumschlag
WPF Dos n Don'ts - der WPF RundumschlagWPF Dos n Don'ts - der WPF Rundumschlag
WPF Dos n Don'ts - der WPF Rundumschlag
 
MVVM mit WPF
MVVM mit WPFMVVM mit WPF
MVVM mit WPF
 
PHP-Module in statischen Seiten - Architektur-Ansätze
PHP-Module in statischen Seiten - Architektur-AnsätzePHP-Module in statischen Seiten - Architektur-Ansätze
PHP-Module in statischen Seiten - Architektur-Ansätze
 
GWT – Google Web Toolkit in der Praxis
GWT – Google Web Toolkit in der PraxisGWT – Google Web Toolkit in der Praxis
GWT – Google Web Toolkit in der Praxis
 
JavaScript goes Enterprise - Node.js-Anwendungen mit Visual Studio und den No...
JavaScript goes Enterprise - Node.js-Anwendungen mit Visual Studio und den No...JavaScript goes Enterprise - Node.js-Anwendungen mit Visual Studio und den No...
JavaScript goes Enterprise - Node.js-Anwendungen mit Visual Studio und den No...
 
Qualitätssicherung in Webprojekten
Qualitätssicherung in WebprojektenQualitätssicherung in Webprojekten
Qualitätssicherung in Webprojekten
 
Modulare Enterprise Systeme - Eine Einführung
Modulare Enterprise Systeme - Eine EinführungModulare Enterprise Systeme - Eine Einführung
Modulare Enterprise Systeme - Eine Einführung
 
Drupal Austria Roadshow in Klagenfurt
Drupal Austria Roadshow in KlagenfurtDrupal Austria Roadshow in Klagenfurt
Drupal Austria Roadshow in Klagenfurt
 
Agile Softwareentwicklung mit Rails
Agile Softwareentwicklung mit RailsAgile Softwareentwicklung mit Rails
Agile Softwareentwicklung mit Rails
 
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
 
Wie programmiere Ich ein Modul? Erste Schritte.
Wie programmiere Ich ein Modul? Erste Schritte.Wie programmiere Ich ein Modul? Erste Schritte.
Wie programmiere Ich ein Modul? Erste Schritte.
 
AdminCam 2017 IBM Connections Troubleshooting
AdminCam 2017 IBM Connections  TroubleshootingAdminCam 2017 IBM Connections  Troubleshooting
AdminCam 2017 IBM Connections Troubleshooting
 
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?
 
Enterprise APEX
Enterprise APEXEnterprise APEX
Enterprise APEX
 
2007 - Basta!: Nach soa kommt soc
2007 - Basta!: Nach soa kommt soc2007 - Basta!: Nach soa kommt soc
2007 - Basta!: Nach soa kommt soc
 
BizSpark goes Cloud
BizSpark goes CloudBizSpark goes Cloud
BizSpark goes Cloud
 
Fanstatic pycon.de 2012
Fanstatic pycon.de 2012Fanstatic pycon.de 2012
Fanstatic pycon.de 2012
 

Mehr von 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 heuteRalf 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 EditionRalf 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 entwickelnRalf 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 ReiseRalf Eggert
 
8. Hamburg Voice Interface Meetup
8. Hamburg Voice Interface Meetup8. Hamburg Voice Interface Meetup
8. Hamburg Voice Interface MeetupRalf Eggert
 
Alexa Skill Maintenance
Alexa Skill MaintenanceAlexa Skill Maintenance
Alexa Skill MaintenanceRalf Eggert
 
Vom Zend Framework zu Laminas
Vom Zend Framework zu LaminasVom Zend Framework zu Laminas
Vom Zend Framework zu LaminasRalf 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 100Ralf Eggert
 
Vom Zend Framework zu Laminas
Vom Zend Framework zu LaminasVom Zend Framework zu Laminas
Vom Zend Framework zu LaminasRalf Eggert
 
Alexa for Hospitality
Alexa for HospitalityAlexa for Hospitality
Alexa for HospitalityRalf 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 SprachanwendungenRalf 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 ProjekteRalf Eggert
 
Künstliche Intelligenz – Traum und Wirklichkeit
Künstliche Intelligenz – Traum und WirklichkeitKünstliche Intelligenz – Traum und Wirklichkeit
Künstliche Intelligenz – Traum und WirklichkeitRalf 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 AlexaRalf Eggert
 
Mein Haus, mein Auto, mein Backend
Mein Haus, mein Auto, mein BackendMein Haus, mein Auto, mein Backend
Mein Haus, mein Auto, mein BackendRalf Eggert
 
Zend/Expressive 3 – The Next Generation
Zend/Expressive 3 – The Next GenerationZend/Expressive 3 – The Next Generation
Zend/Expressive 3 – The Next GenerationRalf Eggert
 

Mehr von Ralf Eggert (20)

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
 
Mein Haus, mein Auto, mein Backend
Mein Haus, mein Auto, mein BackendMein Haus, mein Auto, mein Backend
Mein Haus, mein Auto, mein Backend
 
Zend/Expressive 3 – The Next Generation
Zend/Expressive 3 – The Next GenerationZend/Expressive 3 – The Next Generation
Zend/Expressive 3 – The Next Generation
 

Zend Framework 2 - Best Practices

  • 1. Ralf Eggert | Travello GmbH Zend Framework 2 - Best Practices Quelle: DASPRiD / flickr
  • 2. Über Ralf Eggert • Geschäftsführer Travello GmbH • Buchautor & Kolumnist – Zend Framework 1 (Addison-Wesley) – Zend Framework 2 (Galileo Computing) – PHP Magazin • Zend Framework seit 2006 • Contributor, Speaker, Trainer – http://www.ralfeggert.de/ – http://www.zendframeworkschulung.de/
  • 3. Drei Fragen an das Publikum? • Wer – hat Erfahrungen mit dem Zend Framework 2? – entwickelt an einem Zend Framework 2 Projekt? – hat ein ZF2 Projekt im Live-Betrieb?
  • 4. MVC Quelle: D. Braun / pixelio.de
  • 5. Model-View-Controller • Entwurfsmuster – Model: Business Logik – View: Präsentationslogik – Controller: Steuerungslogik • Warum MVC? – Übersichtlichkeit – Testbarkeit – Wartbarkeit • Paradigma – »Thin Controllers / Fat Models«
  • 6. Bestandteile einer ZF2 Anwendung • Entitäten • Hydratoren • Controller • Controller-Plugins • TableGateways • Formulare • InputFilter • Filter • Validatoren • View-Skripte • View-Helper
  • 8. Lösung: Model-Services einführen • Model-Services • Entitäten • Hydratoren • Controller • Controller-Plugins • TableGateways • Formulare • InputFilter • Filter • Validatoren • View-Skripte • View-Helper
  • 9. Better Practice: Controller & Model-Service ModelService Request Controller Formular Response View
  • 10. Better Practice: Model mit Model-Service Controller Manuela Filter Filter Peter Filter Klaus Entität Hydrator Model Service Input Filter Validator Validator Datenbank Validator
  • 11. Better Practice: View mit Model-Service Controller View ViewSkripte Response ViewHelper nur lesend! Model Service
  • 12. Vorteile einer sauberen Trennung • Alles hat seinen Platz • Model-Service verwendbar von – Webanwendung – Cron-Job – RESTful Webservice – Javascript-Anwendung • Datenvalidierung nicht an Formular gekoppelt
  • 15. Zend Framework 2 Module • Anwendungsspezifische Module – Verzeichnis /module • Fremdmodule – Verzeichnis /vendor • Unternehmensmodule – Verzeichnis /corporate – Oder Unternehmensname, z.B. /travello • Module können aufeinander aufbauen • Module können andere erweitern
  • 16. Abhängigkeiten von ZF2 Modulen I • Beispiel: Modul Application • Funktionen – Layout – Fehlerseiten – Module laden – Konfiguration (z.B. Navigation) • Zugriff für andere Module – Ergänzende Konfiguration z.B. für ZendNavigation • Zugriff auf andere Module – Widgets über View-Helper aufrufen
  • 17. Abhängigkeiten von ZF2 Modulen II • Beispiel: Modul User • Funktionen – Registrierung – Authentifizierung – Autorisierung – Event-Listener • Zugriff für andere Module – View-Helper: userIsAllowed und userWidget – Controller-Plugin: userIsAllowed • Direkten Zugriff auf Services vermeiden
  • 18. Wiederverwendbarkeit • Jedes Modul braucht eigene Routen • .dist Datei für Konfiguration – Für /config/autoload Verzeichnis • Generalisiertes Markup im View verwenden – Twitter Bootstrap – Eigene CSS Struktur • Abhängigkeiten zu anderen Modulen reduzieren • Anderen Module Zugriff ermöglichen – View-Helper – Controller Plugins
  • 19. Fremdmodule • http://modules.zendframework.com/ • https://github.com/ZF-Commons • https://github.com/zfcampus • Beispiele: – ZfcUser / ZfcUser2 – DoctrineModule – DoctrineORMModule – ZendDeveloperTools – BjyProfiler
  • 20. ZF2 Module - Best Practices • Modulkonfiguration cachen! – Achtung! Nur getConfig() wird gecached • Jedes Modul konfiguriert eigenes Routing – Vermeiden: Keine einzelne Route für alle Module • onBootstrap() und init() sparsam nutzen • Nicht überladen: module.config.php – Konfigurationsdaten für Schuhgrößen, Währungskurse, Bildgrößen, finnische Biermarken usw. auslagern • Unternehmensmodule wiederverwenden
  • 22. Service Locator • Service-Locator – Entwurfsmuster • Service-Manager – Konkrete Implementation • Aufgaben – Instanziierung von Objekten / Services – Bereitstellung der Instanzen zur Wiederverwendung
  • 24. Beispiel Factory (mit kleiner Unschärfe) // Datei /module/Customer/src/Customer/Form/CustomerFormFactory.php namespace CustomerForm; use ZendServiceManagerFactoryInterface; use ZendServiceManagerServiceLocatorInterface; class CustomerFormFactory implements FactoryInterface { public function createService(ServiceLocatorInterface $formElementManager) { $serviceLocator = $formElementManager->getServiceLocator(); $hydratorManager = $serviceLocator->get('HydratorManager'); $inputFilterManager = $serviceLocator->get('InputFilterManager'); $filter = $inputFilterManager->get('CustomerCustomerFilter'); $config = $inputFilterManager->getServiceLocator()->get('Config'); $form = new CustomerForm($config['country_options']); $form->setHydrator($hydratorManager->get('ArraySerializable')); $form->setInputFilter($filter); return $form; } }
  • 25. Beispiel Factory (verbessert) // Datei /module/Customer/src/Customer/Form/CustomerFormFactory.php namespace CustomerForm; use ZendServiceManagerFactoryInterface; use ZendServiceManagerServiceLocatorInterface; class CustomerFormFactory implements FactoryInterface { public function createService(ServiceLocatorInterface $formElementManager) { $serviceLocator = $formElementManager->getServiceLocator(); $hydratorManager = $serviceLocator->get('HydratorManager'); $inputFilterManager = $serviceLocator->get('InputFilterManager'); $filter = $inputFilterManager->get('CustomerCustomerFilter'); $config = $serviceLocator->get('Config'); $form = new CustomerForm($config['country_options']); $form->setHydrator($hydratorManager->get('ArraySerializable')); $form->setInputFilter($filter); return $form; } }
  • 26. Konfiguration (Auszug) // Datei /module/Customer/config/module.config.php return array( 'input_filters' => array( 'invokables' => array( 'CustomerCustomerFilter' ), 'shared' => array( 'CustomerCustomerFilter' ), ), => 'CustomerInputFilterCustomerFilter', => true, 'form_elements' => array( 'invokables' => array( 'CustomerAddressFieldset' => 'CustomerFormCustomerAddressFieldset', ), 'factories' => array( 'CustomerCustomerForm' => 'CustomerFormCustomerFormFactory', ), 'shared' => array( 'CustomerCustomerForm' => true, ), ), );
  • 27. Service Manager - Best Practices • Spezialisierte Service-Manager nutzen • ServiceLocatorAwareInterface meiden • Service-Manager niemals injizieren! Nein, nie! • new möglichst nur in Factories verwenden • Initializer sparsam einsetzen • Abstract Factories sparsam einsetzen • Factory Closures in Konfigurationsdateien verhindern Caching • ZendServiceManager schneller als ZendDi
  • 29. Event-Manager im MVC • MVC Events – »bootstrap« – »route« – »dispatch« / »dispatch.error« – »render« / »render.error« – »finish« • Mvc Events für eigene Zwecke verwenden – Nach »route« Event Sprache der Anwendung festlegen – Nach »dispatch.error« Event Fehlermeldungen loggen – Vor »finish« Event HTML aufräumen / minifizieren
  • 30. Event-Manager im Model-Service // Datei /module/Order/src/Order/Service/OrderService.php namespace OrderService; use ZendEventManagerEventManagerInterface; use ZendDebugDebug; class OrderService { protected $eventManager; public function setEventManager(EventManagerInterface $eventManager) { $eventManager->setIdentifiers(array(__CLASS__); $this->eventManager = $eventManager; } public function getEventManager() { return $this->eventManager; } public function saveOrder($id) { $this->getEventManager()->trigger('preOrder', __CLASS__, array('id' => $id)); Debug::dump('Save order ' . $id); $this->getEventManager()->trigger('postOrder', __CLASS__, array('id' => $id)); } }
  • 31. Event-Manager konfigurieren use ZendDebugDebug; use ZendEventManagerEventManager; use OrderServiceOrderService; $eventManager = new EventManager(); $eventManager->attach('postOrder', function ($e) { Debug::dump('Update stock'); }, 100); $eventManager->attach('postOrder', function ($e) { Debug::dump('Send order confirmation'); }, 300); $eventManager->attach('preOrder', function ($e) { Debug::dump('Check stock'); }); $orderService = new OrderService(); $orderService->setEventManager($eventManager); $orderService->saveOrder('12345'); // output string 'Check stock' (length=11) string 'Save order 12345' (length=16) string 'Send order confirmation' (length=23) string 'Update stock' (length=12)
  • 32. Event Manager - Best Practices • Eindeutige Identifier verwenden (Klassenname) • SharedEventManager – Fallback für alle Event-Manager Instanzen – Events für nicht existente Objekte registrieren • EventManagerAwareInterface • Listener – Aggregat-Klassen (ListenerAggregateInterface) – Closures
  • 34. Formularverarbeitung • InputFilter – ZendInputFilterInputFilter erweitern – Input-Elemente in init() per Factory hinzufügen – Hierarchische InputFilter möglich • Formulare – ZendFormForm erweitern – Formularelemente in init() per Factory hinzufügen – Hierarchie durch Fieldsets umsetzbar
  • 35. Konfiguration Filter & Validatoren // Datei /module/Customer/config/module.config.php return array( 'filters' => array( 'invokables' => array( 'CustomerAddress' => 'CustomerFilterAddressFilter', ), ), 'validators' => array( 'invokables' => array( 'CustomerCountry' => 'CustomerValidatorCountryValidator', ), ), );
  • 36. Beispiel InputFilter // Datei /module/Customer/src/Customer/InputFilter/CustomerFilter.php namespace CustomerInputFilter; use ZendInputFilterInputFilter; class CustomerFilter extends InputFilter { public function init() { $this->add(array( 'name' => 'address', 'filters' => array( array('name' => 'CustomerAddress'), ), )); $this->add(array( 'name' => 'country', 'validators' => array( array('name' => 'CustomerCountry'), ), )); } }
  • 37. Formularverarbeitung - Best Practices • Validierung und Formularanzeige trennen – Im Model-Service mit InputFilter validieren – Im Controller Formular bereitstellen • Controller – Plugin PostRedirectGet – Plugin FilePostRedirectGet • Spezialisierte Service-Manager verwenden
  • 39. Application-Management • Management des Lebenszyklus der Anwendung • Mehrere Stufen (DTAP) – Development – Testing – Acceptance – Production • Weiche in /public/index.php • Pro Stufe eigene Konfiguration
  • 40. Application-Management Weiche // Datei /public/index.php define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production')); define('APPLICATION_ROOT', realpath(__DIR__ . '/..')); require_once '../vendor/autoload.php'; chdir(dirname(__DIR__)); switch (APPLICATION_ENV) { case 'production': $configFile = APPLICATION_ROOT . '/config/production.config.php'; break; case 'development': default: $configFile = APPLICATION_ROOT . '/config/development.config.php'; break; } ZendMvcApplication::init(include $configFile)->run();
  • 41. Development Konfiguration // Datei /config/development.config.php return array( 'modules' => array( 'Application', 'User', 'Cms', 'Blog', 'ZendDeveloperTools', ), 'module_listener_options' => array( 'config_glob_paths' => array( 'config/autoload/{,*.}{production,development,local}.php', ), 'module_paths' => array( './module', './vendor', ), ), );
  • 42. Production Konfiguration // Datei /config/production.config.php return array( 'modules' => array( 'Application', 'User', 'Cms', ), 'module_listener_options' => array( 'config_glob_paths' => array( 'config/autoload/{,*.}{production}.php', ), 'module_paths' => array( './module', './vendor', ), 'cache_dir' => './data/cache', 'config_cache_enabled' => false, 'config_cache_key' => 'module_config_cache', 'module_map_cache_enabled' => false, 'module_map_cache_key' => 'module_map_cache', ), );
  • 44. ZF2 Performance • Modulkonfiguration cachen – Closures nicht cachebar – Achtung: Nur getConfig() wird gecached • ClassMaps und TemplateMaps einsetzen – Generator Skripte in /vendor/bin • Möglichst wenige parallele Routen • Fremdmodule – EdpSuperluminal – SpiffyNavigation – OcraCachedViewResolver
  • 45. Performancebremsen • Größte Performancebremsen in Anwendung – Ineffiziente Datenbankabfragen – Nicht performante Berechnungen – Gelesene Daten werden nicht gecached • Generell – Einsatz eines Frameworks immer langsamer als prozedurale Skripte • Tipp – Eigenen Suchindex aufbauen
  • 47. ZF2 Komponenten für Security • Authentifizierung / Autorisierung – ZendAuthentication – ZendPermissions – ZendCaptcha • »Filter Input, Escape Output« – ZendFilter – ZendValidator – ZendInputFilter – ZendEscaper • Sichere Zufallswerte – ZendMath
  • 48. Einsatzzwecke • Passwörter verschlüsseln – MD5 Hashes sind nicht sicher! – ZendCryptPasswordBcrypt • XSS vermeiden – Daten filtern und escapen • SQL Injection vermeiden – Mit ZendDbSql sicherer implementieren • Cross Site Request Forgery – ZendFormElementCsrf einsetzen
  • 49. Migration vom ZF1 Quelle: sokaeiko / pixelio.de
  • 50. Probleme bei Migration vom ZF1 • Kein Tool für automatische Migration • Kein Migration Layer • Migration-Guide in ZF2 Doku 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 • Kein ZF-spezifisches Problem
  • 51. Migration ZF1 nach ZF2 • ZF1 und ZF2 parallel betreiben • Weiche in .htaccess einrichten • ZF2 Module müssen ZF1 Routing beachten • Modul für Modul migrieren • »Fat Models« leichter migrierbar • »Fat Controller« schwerer migrierbar • Weitere Quellen – Artikel im PHP Magazin 6/2013 (Teil 1) – IPC Spring Session: http://goo.gl/dgl8zH
  • 52. Weiche in .htaccess // Datei /public/.htaccess RewriteEngine on # Slash am Ende entfernen RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L] # Umschreiberegeln für ZF2 RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^$ index.zf2.php RewriteRule ^customer(.*)$ index.zf2.php RewriteRule ^order(.*)$ index.zf2.php RewriteRule ^cms(.*)$ index.zf2.php # Umschreiberegeln für ZF1 RewriteCond %{REQUEST_FILENAME} !-f RewriteRule .* index.zf1.php
  • 53. Das ZF3 kommt demnächst in diesem Kino Quelle: DASPRiD / flickr
  • 55. Ralf Eggert | Travello GmbH Vielen Dank für Eure Aufmerksamkeit Quelle: DASPRiD / flickr