Wie eigenständig sind die Framework-Komponenten wirklich?

Aura, ZF2 und Symfony2 im Decoupling-Vergleich
Kommentare

Nachdem Paul Jones sein PHP-5.4-Framework Aura vorgestellt hat, sollte er uns zeigen, dass die Aura-Pakete eigenständiger sind als die Pendants von Zend oder Symfony. Anhand eines Beispiels mit der Filter-Komponente, die sämtliche Frameworks in eigenen Lösungen anbieten, demonstriert er uns die glänzenden Stellen seines Frameworks.

Paul M. Jones hat unlängst die General Availability der meisten Komponenten seines Aura Frameworks angekündigt. Es handelt sich um das erste Framework, was komplett auf PHP 5.4 basiert. Schon mit dem Vorgänger SolarPHP wagte Jones als erster den großen Schritt in eine neue PHP-Version, damals war es PHP 5.

Kurz nach dem Release stand er uns Rede und Antwort, doch waren wir uns nicht ganz sicher, ob wir einen bestimmten Punkt seiner Framework-Vorstellung so im Raum stehen lassen konnten. Also hakten wir nach:

PHP Magazin: Ich würde gerne noch einmal an unserem letzten Punkt einhaken, bei dem wir über andere Frameworks sprechen. Die jeweils zweiten Generationen von Symfony und Zend Framework sind ebenfalls stark entkoppelt worden. Ganz offenbar wird dies, wenn man sieht, wie Symfony-Komponenten in Drupal 8 verwendet werden oder Anleitungen im Netz kursieren, anhand derer man Komponenten aus Zend Framework 2 und Symfony2 gemischt nutzen kann. Was macht Aura hier anders oder besser?

Paul Jones: In der Lage zu sein, Symfony2- oder ZF2-Module zu verwenden, ist gar nicht die Unterscheidung, die ich machen will. Die Unterscheidung ist, dass die Aura-Pakete (mit der einzigen Ausnahme des Framework-Pakets) voneinander unabhängig sind, und keine paketübergreifende Abhängigkeiten haben. Zumindest bei manchen Komponenten von Symfony2 und ZF2 ist das anders.

Im Vergleich untersuchen wir etwas, das relativ einfach sein sollte: Eingabevalidierung und -filterung. Fangen wir mit ZF2 an, machen dann mit Symfony2 weiter und hören mit Aura auf. in jedem Fall werden wir versuchen, das Paket herunterzuladen und seine Tests durchlaufen zu lassen. Das sollte ein guter Indikator dafür sein, ob das Paket unabhängig verwendet werden kann oder nicht. Wir werden feststellen, dass dies in ZF2 überhaupt nicht möglich ist, in Symfony2 immerhin eingeschränkt funktioniert und es unter Aura trivial ist.

Zend Framework 2

Wir laden zunächst das ZF2 InputFilter-Paket herunter. Anscheinend ist es nicht zum eigenständigen Download verfügbar. Es ist ein Repository auf GitHub, aber dort befindet sich nur das komplette Framework, nicht ausschließlich der InputFilter.

Na gut. Wenigstens können wir über den Composer die InputFilter-Komponente in einem Projekt einbinden. Wir werden dazu eine Composer-Datei nach der ZF2-Anleitung erstellen und das InputFilter-Paket installieren. Das compser.json sieht wie folgt aus:

    {
        "repositories": [
            {
                "type": "composer",
                "url": "https://packages.zendframework.com/"
            }
        ],
        "require" : {
            "zendframework/zend-inputfilter" : "2.0.*"
        }
    }

Nachdem wir Composer in dasselbe Verzeichnis herunterladen, starten wir den Installer und bekommen das zu sehen:

    $ ./composer.phar install
    Loading composer repositories with package information
    Installing dependencies
      - Installing zendframework/zend-stdlib (2.0.5)
        Downloading: 100%         

      - Installing zendframework/zend-servicemanager (2.0.5)
        Downloading: 100%         

      - Installing zendframework/zend-filter (2.0.5)
        Downloading: 100%         

      - Installing zendframework/zend-i18n (2.0.5)
        Downloading: 100%         

      - Installing zendframework/zend-validator (2.0.5)
        Downloading: 100%         

      - Installing zendframework/zend-inputfilter (2.0.5)
        Downloading: 100%         

    zendframework/zend-stdlib suggests installing pecl-weakref (Implementation of weak references for StdlibCallbackHandler)
    zendframework/zend-servicemanager suggests installing zendframework/zend-di (ZendDi component)
    zendframework/zend-filter suggests installing zendframework/zend-crypt (ZendCrypt component)
    zendframework/zend-validator suggests installing zendframework/zend-db (ZendDb component)
    zendframework/zend-validator suggests installing zendframework/zend-math (ZendMath component)
    Writing lock file
    Generating autoload files
    $ 

Um Eingabefilterung in ZF2 zu nutzen, werden sechs andere Pakete benötigt und ein paar weitere vorgeschlagen.

Nun, da wir es installiert haben, wo sind die Tests? Sie sind nicht im Composer-Paket enthalten, wobei ich vermute, dass sie beim Framework als Ganzes enthalten sind. Es erscheint mir, als sei das Zend-Angebot nicht ganz freistehend.

(Wenn wir genau hinsehen, dann erkennen wir, dass InputFilter aus mindestens zwei anderen Paketen zusammengesetzt ist, die unsere Zwecke erfüllen: ZendValidator und ZendFilter. Wenn man sich jedoch diese beiden näher anschaut, sind sie nicht vergleichbar mit dem Aura.Filter oder dem Symfony2-Validator.)

Symfony2

Wir machen dasselbe mit Symfony2. Diesmal ist [die Validator-Komponente] in GitHub verfügbar. Wir klonen das Paket und lassen die Tests durchlaufen:

    $ git clone https://github.com/symfony/Validator.git
    Cloning into Validator...
    remote: Counting objects: 3459, done.
    remote: Compressing objects: 100% (672/672), done.
    remote: Total 3459 (delta 2708), reused 3451 (delta 2700)
    Receiving objects: 100% (3459/3459), 621.73 KiB | 730 KiB/s, done.
    Resolving deltas: 100% (2708/2708), done.
    $ cd Validator/Tests/
    $ phpunit
    [phpunit fails]

Dem Anschein nach können wir nicht einfach das Paket herunterladen und die Tests starten. Im Readme heißt es, wir müssen die „–dev“-Abhängigkeiten via Composer installieren. Also downloaden wir erst Composer ins klonierte Repository, und anschließend machen wir Folgendes:

    $ ./composer.phar install --dev
    Loading composer repositories with package information
    Installing dependencies
    Nothing to install or update
    Loading composer repositories with package information
    Installing dev dependencies
      - Installing symfony/yaml (dev-master bed4fdd)
        Cloning bed4fddc24392513e01b32a78d600b1272ed9a6c

      - Installing symfony/locale (dev-master 2dceded)
        Cloning 2dcededb060dfb6289ad8bb3f2a7a4e00929c4dc

      - Installing symfony/http-foundation (dev-master 067c310)
        Cloning 067c310fe4d0691a24adc97f39500233a58e42cb

    Writing lock file
    Generating autoload files

Interessant zu sehen, dass wir drei weitere Pakete brauchen, damit die Tests laufen. Das sieht für mich nach paketübergreifenden Abhängigkeiten aus. Bei einem Blick in die Code-Basis offenbart sich diese Vermutung als Wahrheit:

  • If you want to use the YAML loader included with the Validator, you need that YAML package after all.
  • If you want to validate against anything related to locales or languages, you need the Locale package. For example, the LangaugeValidator.php file makes a static call to SymfonyComponentLocaleLocale::getLanguages().
  • If you want to use Annotations with the Validator, it looks like you need Doctrine, which isn’t a part of the Symfony vendor hierarchy at all. Goodness knows what *that* will require.

Jedenfalls können wir jetzt die Tests durchlaufen lassen. Die Fortschrittsmeldungen habe ich im Folgenden entfernt:

    $ phpunit
    PHPUnit 3.7.9 by Sebastian Bergmann.
    ...
    Time: 8 seconds, Memory: 17.75Mb

    OK, but incomplete or skipped tests!
    Tests: 987, Assertions: 1091, Skipped: 12.
    $ 

Zwölf Tests müssen wegen fehlender Abhängigkeiten übersprungen werden. Starten wir phpunit –verbose, dann entdecken wir, dass:

  • drei Tests übersprungen werden, weil APC für die Kommandozeile nicht geladen ist, was kein so großes Problem ist
  • sechs Tests übersprungen werden, weil die Doctrine Common Library fehlt
  • drei Tests übersprungen werden, weil benötigte Kommentare fehlen

Genau wie bei der ZF2 Filter-Komponente scheint es, als sei die Symfony2-Validierungskomponente nicht ganz eigenständig. Sie hat externe Abhängigkeiten, die erst erfüllt werden müssen, damit sie vollständig nutzbar ist.

Aura.Filter

Zum Schluss betrachten wir das Aura.Filter-Paket. Es steht auf GitHub zum Download bereit. Versuchen wir einmal, es zu klonen und zu testen; erneut habe ich den Testfortschritt im Folgenden ausgespart:

    $ git clone git@github.com:auraphp/Aura.Filter.git
    Cloning into Aura.Filter...
    remote: Counting objects: 1105, done.
    remote: Compressing objects: 100% (373/373), done.
    remote: Total 1105 (delta 631), reused 1076 (delta 602)
    Receiving objects: 100% (1105/1105), 725.94 KiB | 606 KiB/s, done.
    Resolving deltas: 100% (631/631), done.
    $ cd Aura.Filter/tests/
    $ phpunit
    PHPUnit 3.7.9 by Sebastian Bergmann.

    Configuration read from /Users/pmjones/Aura.Filter/tests/phpunit.xml
    ...
    Time: 4 seconds, Memory: 9.75Mb

    OK (1009 tests, 1443 assertions)
    $ 

Keine externen Abhängigkeiten und nichts Zusätzliches wird benötigt, damit die Tests laufen. Das Paket ist komplett selbsttragend, unabhängig und entkoppelt. Jetzt vergleiche man den Speicherbedarf und die vergangene Zeit mit Symfony2: Rund die Hälfte des Speichers und rund halb so viel Zeit wurden benötigt, um rund 30 Prozent mehr Assertions im Tests zu überprüfen. (Übrigens haben wir 100 Prozent Testabdeckung, wobei ich nicht weiß, wie es da bei Zend oder Symfony aussieht.)

Schlussfolgerung

Mit dem oben stehenden will ich nicht behaupten, dass Zend Framework 2 oder Symfony2 eine schlechte Architektur haben oder unbrauchbar sind oder irgendwie negativ auffallen. Es sind gute Projekte und die Komponenten scheinen auch recht gut zu sein.

Ich sage nur, dass ihr Angebot separater Pakete nicht immer gut entkoppelt ist. Das liegt daran, dass sie mit einem Framework begonnen haben und anschließend versucht haben, einzelne Teile davon zu extrahieren. Einige Komponenten sind sogar frei von Abhängigkeiten.

In Aura hingegen gilt der Libraries-First-Ansatz: Jedes Paket ist wirklich entkoppelt, unabhängig, selbstgenügsam und ohne paketübergreifende Abhängigkeiten. Das ist der eigentliche Unterschied, den ich hiermit betonen wollte.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -