Frameworks | Kolumne

Alles im Flow: Von TYPO3 Flow 2, Performance 2.0 und vielem mehr
Kommentare

Eineinhalb Jahre hat sich das Flow-Core-Team Zeit gelassen, um an dem zweiten Major-Release des Frameworks zu arbeiten. Neben dem neuen Namen hat sich auch auf Featureseite einiges getan und mithilfe des Feedbacks aus der Community flossen zahlreiche Optimierungen in Version 2.0 ein. Bei Erscheinen dieser Ausgabe müsste die finale Version TYPO3 Flow 2.0 bereits veröffentlicht sein – Grund genug, einen Blick auf die letzten Neuerungen zu werfen und einen Ausblick auf die nächsten Versionen zu wagen.

Integration Composer und Session Management Wie bereits in der ersten Ausgabe dieser Kolumne erwähnt, betrifft eine der grundlegendsten Änderungen das Paketmanagement: TYPO3 Flow selbst, wie auch alle darauf aufbauenden Pakete, sind nun Composer-kompatibel. Sämtliche vom Core-Team unterstützte Pakete haben wir auf packagist.org eingetragen, wodurch die Installation einer frischen Flow-Distribution – ein installierter Composer vorausgesetzt – sehr einfach von statten geht:

composer.phar create-project typo3/flow-base-distribution MyNewFlowProject

Weitere Pakete – ob nun Flow-basiert oder aus einer anderen Bibliothek – lassen sich ebenfalls durch Composer nachinstallieren:

composer.phar require robertlemke/akismet composer.phar require phpunit/phpunit

Sessions werden in Flow 2.0 nicht mehr über die von PHP bereitgestellten Funktionen, sondern über die HTTP-Foundation, die Teil von Flow ist, umgesetzt. Dies eröffnet neue Möglichkeiten, wenn Sessions in einer verteilten Serverumgebung eingesetzt werden: der Session-Manager behält jederzeit den Überblick über aktive Sessions und kann bei Bedarf dafür verwendet werden, um an Sessions zu gelangen, die nicht mit dem aktuellen HTTP-Request verbunden sind (Listing 1).

Listing 1

$currentSession = $this->sessionManager->getCurrentSession();
$preferredColor = $currentSession->getData('preferred_color');

$someoneElsesSessionId = 'csAIF2EfaB2DwLN6io9xswO3dg5IwFym';
$otherSession = $this->sessionManager->getSession($someoneElsesSessionId);
$someData = $otherSession->getData('some_data');
$timestamp = $otherSession->getLastActivityTimestamp();
$otherSession->setData('some_new_data', 'some new data for remote session');

$mySession->addTag('staff');
$staffSessions = $this->sessionManager->getSessionsByTag('staff');

Die Session-Daten werden mithilfe des Cache-Backends gespeichert. Aktuell wird die Unterstützung für die Speicherung im Dateisystem, dem APC Key-Value Store, in Memcache, in PDO-Datenbanken und Redis mitgeliefert.

Rollenmanagement

Auch das Security Framework hat einige neue Features spendiert bekommen. Eines der wichtigsten ist sicherlich die erweiterte Behandlung von Rollen. In früheren Versionen wurden Rollen in den Policy.yaml-Dateien ohne besonderen Namensraum definiert und paketübergreifend genutzt:

roles:

  BlogEditor: [ Editor ]   BlogAdministrator: BlogEditor

In diesem Beispiel wird eine neue Rolle BlogEditor definiert, die von der Rolle Editor erbt, die in einem anderen Paket definiert wurde. BlogAdministrator wiederum erbt von der neuen Rolle BlogEditor. In TYPO3 Flow 2.0 wurden für Rollen Namensräume eingeführt. Die obige Definition sieht in der neuen Syntax nun folgendermaßen aus:

roles:

  BlogEditor: [ TYPO3.Neos:Editor ]   BlogAdministrator: BlogEditor

Aus anderen Paketen kann auf die Rolle BlogEditor durch den voll qualifizierten Namen Paketname.BlogEditor verwiesen werden.

Viel wichtiger als die reine Syntax ist aber die Tatsache, dass Rollen nun in der Datenbank mit persistiert werden: Zwar lassen sich Rollen nach wie vor in der Policy.yaml definieren, zusätzlich kann dies aber auch zur Laufzeit über ein API geschehen. Dadurch lässt sich eine flexible Benutzerverwaltung mit einer entsprechenden Benutzeroberfläche realisieren.

Geschwindigkeit 2.0

Im Zuge eines Performance-Code-Sprints konnte das Flow-Team diverse Bereiche im Flow-Core stark beschleunigen und den Speicherverbrauch erheblich senken. Je nach Applikation ließ sich die Geschwindigkeit bis auf das Vierfache steigern! Neben vielen Detailverbesserungen und einem eigenen Cache für Doctrine-Queries sind dafür zwei neue Funktionen verantwortlich: Lazy Dependency Injection und Static Method Result Compilation.

Lazy Dependency Injection

Die Abhängigkeiten einer Klasse, zum Beispiel die eines Action Controllers, lassen sich in Flow komfortabel injecten – am einfachsten (und performantesten) geht das mithilfe von Property Injection:

class ProductController extends ActionController {

  /**    * @FlowInject    * @var AcmeDemoProductAvailabilityService    */   protected $productAvailabilityService

In diesem Beispiel benötigt der ProductController in einer seiner Actions Zugriff auf einen Service, der die Lieferbarkeit eines Produkts ermittelt. Durch die @FlowInject-Annotation wird diese Abhängigkeit automatisch gelöst – von nun an findet sich in $productAvailabilityService immer der entsprechende Service. Einige Actions kommen aber womöglich ohne diesen Service aus – beispielsweise createAction() oder eine deleteAction(). Hier würde der Service nun unnötig instanziiert und in den Controller injectet. In Flow 2.0 ist Property Injection nun standardmäßig lazy: Anstelle des echten Service wird nur eine Closure injiziert, die, sobald auf sie zugegriffen wird, sich automatisch in die echte Serviceinstanz verwandelt. Besonders in umfangreicheren Klassen mit vielen Abhängigkeiten lässt sich so das Laden von hunderten von Klassendateien vermeiden.

Static Method Result Compilation

Manche Teile einer Flow-Applikation verwenden Daten, die zwar zur Laufzeit statisch sind, aber im Programmcode nicht hart kodiert werden können oder sollten. Ein Beispiel sind die Validierungsregeln des MVC-Frameworks: die Basisinformationen für solche Regeln (welche PHP-Methoden gibt es und welchen Typ haben die Parameter dieser Methoden) sind statisch. Wir wollen dem Entwickler aber nicht zumuten, diese Informationen über eine Konfiguration zu setzen (Don’t-Repeat-Yourself-Prinzip); daher ermittelt Flow diese automatisch und zur Laufzeit. Leider verlangsamt das die Anwendung bei jedem Aufruf. Eine Lösung für dieses Problem ist, das Resultat einer Methode, die zur Laufzeit immer das gleiche Ergebnis liefern würde, statisch zu kompilieren. In Flow 2.0 wird genau das getan, sobald eine Methode statisch und mit der Annotation @FlowCompileStatic gekennzeichnet ist (Listing 2).

Listing 2

/**
 * Liefert eine Liste von Methoden und ihren Parametern
 *
 * @param TYPO3FlowObjectObjectManagerInterface $objectManager
 * @return array
 * @FlowCompileStatic
 */
static public function getActionMethodParameters($objectManager) {
  $reflectionService = $objectManager->get('TYPO3FlowReflectionReflectionService');
  $className = get_called_class();
  $methodParameters = $reflectionService->getMethodParameters($className, get_class_methods($className));
  foreach ($methodParameters as $parameterName => $parameterInfo) {
    ...
  }
  return $methodParameters;
}

Die Methode getActionMethodParameters() würde in obigem Fall nur ein einziges Mal, nämlich wenn die Flow-Anwendung das erste Mal gestartet wird, aufgerufen. Da zur Kompilierzeit nur Teile des Frameworks initialisiert sind, wird der Object Manager mitgeliefert, über den auch ohne Dependency Injection Zugriff auf viele Objekte möglich ist.

Weitere Informationen und Ausblick

Nach den großen Änderungen durch die Umbenennung des Projekts und der Einführung von Composer, brechen jetzt ruhigere Zeiten an – zumindest was die Abwärtskompatibilität angeht. Denn an Plänen für neue Funktionen und Verbesserungen für Flow 2.1 mangelt es nicht.

Das TYPO3-Flow-Team wird zukünftige Releases nach dem Schema der semantischen Nummerierung veröffentlichen: alle Upgrades von einer 2.x-Version auf eine höhere Version aus dem 2.x-Zweig bleiben abwärtskompatibel, solange sich Entwickler an das offizielle API halten. Ob man sich in diesem Rahmen bewegt, lässt sich leicht feststellen: Alle freigegebenen Methoden sind durch eine @api-Annotation gekennzeichnet.

Sämtliche Informationen zur neuen Version 2.0 und der Migration von bestehenden Projekten finden Sie in den Release Notes.

Zu guter Letzt sei an dieser Stelle noch ein großer Dank an das unermüdliche Kernteam und den zahlreichen Helfern der Community ausgesprochen: Die Weiterentwicklung von Flow wird fast ausschließlich durch ihre Zeit und Arbeit bewerkstelligt, getrieben von dem immerwährenden Ziel, der PHP-Welt eine exzellente Entwicklungsplattform zu bieten.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -