Ankündigung

Einklappen
Keine Ankündigung bisher.

Fehlende Abhängigkeiten in composer.json Dateien von Symfony Components

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Fehlende Abhängigkeiten in composer.json Dateien von Symfony Components

    Symfony beschriebt die „symfony components“ selbst wie folgt:

    Die Symfony Components bilden für die Webentwicklung typische Grundfunktionen ab. Sie stellen die Basis des vollständigen Symfony-Frameworks dar, können aber auch für sich allein eingesetzt werden, da sie über keine festgelegten Abhängigkeiten verfügen.
    (http://symfony.com/de/components)

    Jede Komponente verfügt über eine eigene composer.json und sollte sich somit problemlos auch ohne das Framework benutzen lassen.

    Eine Zeile in der eignen composer.json genügt bereits um die Komponente in das eigene Projekt einzubinden:

    Code:
    {
        "require": {
            "symfony/dom-crawler": "~2.7"
        }
    }
    dann

    Code:
    composer install
    und alles ist fertig installiert – sehr schön

    Auf github.com findet man die Komponente unter https://github.com/symfony/symfony/t...ent/DomCrawler

    und die Readme Datei beinhaltet bereits ein paar kleinere Beispiele.

    Ok, also ein erster Test:

    Code:
    require '../vendor/autoload.php';
    
    use Symfony\Component\DomCrawler\Crawler;
    
    $crawler = new Crawler();
    $crawler->addContent('<html><body><p>Hello World!</p></body></html>');
    
    print $crawler->filter('body > p')->text();
    das Ergebnis sieht dann so aus:

    Code:
    Fatal error: Uncaught exception 'RuntimeException' with message 'Unable to filter with a CSS selector as the Symfony CssSelector is not installed (you can use filterXPath instead).' in …..vendor/symfony/dom-crawler/Symfony/Component/DomCrawler/Crawler.php on line�*669
    Der Grund dafür ist dass eine benötigte Klasse (Symfony\Component\CssSelector\CssSelector) nicht mit installiert wurde, da sie nicht in composer.json der Komponente eingetragen ist.

    Ich dachte zuerst, daß es sich nur um ein Versehen/Bug handeln kann, bis ich nach einigen Stichproben festgestellt habe, daß auch in vielen anderen Komponenten die Abhängigkeiten beim Installieren nicht berücksichtigt werden?!!!

    Nun bin ich neugierig geworden und habe mir das auch bei ZF2 angeschaut (https://github.com/zendframework/zf2...r/library/Zend). Alles OK soweit ich das stichprobenartig feststellen konnte, die benötigten Bibliotheken sind in der jeweiligen composer.json eingetragen und werden automatisch mit installiert.

    Hat vielleicht jemand eine Idee was sich symfony dabei gedacht hat?

    VG
    jack
    -

  • #2
    Optionale Funktionalität. Die Komponente definiert sich nicht nur aus der Methode filter().

    Kommentar


    • #3
      Symfony empfiehlt dir Pakete die du installieren kannst wenn du die volle Funktionalität des aktuellen Pakets haben willst. ( Solche Empfehlungen stehen im "suggest"-Teil der composer.json des Pakets und werden dir beim installieren des Pakets angezeigt.
      [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

      Kommentar


      • #4
        „Optionale Funktionalität.“ ???

        „Empfehlung“ ???

        Ist das euer ernst? Eine Klassenmethode einfach als „optionale Funktionalität“ bezeichen und statische Kopplung als „Empfehlung“ behandeln?

        Demnach würde die Vorgehensweise zum Auflösen von Abhängigkeiten in Komponenten so aussehen:
        Code:
        class A {
            public function foo() {
                // ...
            }
        
            public function bar() {
                if (!class_exists('B')) {
                    throw new \RuntimeException('Vorsicht optionale Funktionalität');
                }
                new B();
            }
        }
        composer.json
        Code:
        "suggest": {
            "B": "Sie sollten lieber B installieren bevor sie A->bar() aufrufen!"
        }
        Das ist das was symfony aktuell macht.

        vg
        jack
        -

        Kommentar


        • #5
          Ich denke eher, dass das per Lazy-Loading geregelt wird und nicht so, wie du das da darstellst.
          [QUOTE=nikosch]Macht doch alle was Ihr wollt mit Eurem Billigscheiß. Von mir aus sollen alle Eure Server abrauchen.[/QUOTE]

          Kommentar


          • #6
            Ich denke eher, dass das per Lazy-Loading geregelt wird und nicht so, wie du das da darstellst.
            Es ist exakt so wie ich es dargestellt habe:

            https://github.com/symfony/symfony/b.../composer.json

            Code:
            "require": {
                    "php": ">=5.3.9"
                },
            .....
                "suggest": {
                    "symfony/css-selector": ""
                },
            }
            https://github.com/symfony/symfony/b....php#L666-L674
            Zeile 666-674:

            Code:
            public function filter($selector)
            {
                if (!class_exists('Symfony\\Component\\CssSelector\\CssSelector')) {
                    throw new \RuntimeException('Unable to filter with a CSS selector as the Symfony CssSelector is not installed (you can use filterXPath instead).');
                }
                // The CssSelector already prefixes the selector with descendant-or-self::
                return $this->filterRelativeXPath(CssSelector::toXPath($selector));
            }
            vg
            jack
            -

            Kommentar


            • #7
              ::filter() ist ein CssSelector Wrapper. Das ist auch so beabsichtigt. der DOM Crawler ist ursprünglich ein XPATH Crawler mit optionalem CssSelector Wrapper ( sofern installiert ).

              Ja das ist unser ernst, ja genau dafür sind mitunter Suggestions. Und ja, das steht auch in der API Documentation von Symfony 2 so. Soll so.
              [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

              Kommentar


              • #8
                Nun gut, aber wo ist da jetzt das Problem? Wenn du das CssSelector-Pack nicht installiert hast kannst du es eben nicht nutzen. Das schränkt aber erstmal nicht die Funktionsweise des Crawlers an sich ein. Crawlen und den Result weiterverarbeiten kannst du eben auch ohne CssSelector.
                [QUOTE=nikosch]Macht doch alle was Ihr wollt mit Eurem Billigscheiß. Von mir aus sollen alle Eure Server abrauchen.[/QUOTE]

                Kommentar


                • #9
                  Mich würde eher stören das alle Symfony Komponenten ohne Contracts implementiert sind.
                  [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

                  Kommentar


                  • #10
                    Nun gut, aber wo ist da jetzt das Problem? Wenn du das CssSelector-Pack nicht installiert hast kannst du es eben nicht nutzen.
                    Ich will ja nicht den CssSelector benutzen sondern den Crawler (eine eigenständige symfony Komponente). Die filter()-Methode ist eine Methode des Crawlers nicht des CssSelectors. Es ist nicht ersichtlich wenn man den Crawler installiert, daß eine bestimmte Methode eine andere Klasse voraussetzt.

                    Normalerweise ist der Composer das richtige Werkzeug um solche Abhängigkeiten beim Installieren der Komponente automatisch aufzulösen (wie das geht kann man sich zb. bei ZF2 Komponenten anschauen). Deshalb ist der Composer ja auch ein dependency manager und nicht bloss ein installer.

                    Suggest ist in composer übrigens nur zu Informationszwecken gedacht und nur für Packete die nicht unbedingt erforderlich sind.

                    https://getcomposer.org/doc/04-schema.md#suggest

                    vg
                    jack
                    -

                    Kommentar


                    • #11
                      Ja und was genau hast du an "enhance" nicht verstanden ? Suggests ist für optionales. CssSelector ist optional und nicht nötig um mit dem DOM Crawler zu arbeiten. Wenn er nötig wird, weil du einen wrapper nutzt, meldet sich DOMCrawler das du dann dazu was installieren solltest.

                      Ich hab keine Ahnung wieso dir das jetzt nen Zacken aus der Krone reißt.
                      [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

                      Kommentar


                      • #12
                        Crawler::filter() ist doch nicht optional. Es gibt grundsätzlich keine Klassenmethoden die optional sind?!!

                        Crawler::filter() benötigt intern den CssSelector, somit ist der CssSelector auch nicht optional.

                        Der CssSelector ist intern fest mit dem Crawler verdrahtet, er kann noch nicht mal von außen übergeben werden (z.B.: filter($selector, iSelector $selectorProzessor), deshalb haben wir es hier mit einer starken statischen Kopplung zwischen den beiden Klassen zu tun.

                        Summa summarum:

                        Die Crawler-Komponente ist nach der Installation nicht voll funktionsfähig und die Aussage „...können aber auch für sich allein eingesetzt werden, da sie über keine festgelegten Abhängigkeiten verfügen.“ nicht richtig. (dies gilt übrigens auch für viele andere symfony Komponenten)

                        Würdet ihr eure Komponentenbibliotheken wirklich so aufbauen? Dann könnte man auf den composer auch gleich komplett verzichten und die Abhängigkeiten einfach in Readme oder Install.txt auflisten.

                        vg
                        jack
                        -

                        Kommentar


                        • #13
                          Ich würde meine Komponentenbibliotheken so nicht aufbauen, nein. An dem Zustand von Symfony können wir aber nix ändern. Du mit Issues und Commits aber schon.
                          [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

                          Kommentar


                          • #14
                            Eigentlich ist die Codequalität bei Symfony sehr hoch und auch das Konzeptionelle sehr ausgereift. Die Jungs machen das ja nicht erst seit gestern. Deswegen war ich schon sehr....sehr überrascht als ich das gesehen habe.

                            Ich kann mir auch nicht vorstellen, daß die Problematik den Machern nicht bekannt ist. Ich vermute ich würde denen nichts neues erzählen. Ich verstehe es nur nicht wieso die Abhängigkeiten in der composer.json nicht eintragen werden – was könnte dagegen sprechen?

                            Würde man z.B. in dem o.g. Beispiel die composer.json nur geringfügig wie folgt ergänzen:

                            Code:
                            "require": {
                                "php": ">=5.3.9",
                                "symfony/css-selector": "~2.7|~3.0.0"
                                },
                            }
                            dann hätte man tatsächlich eine 100% funktionsfähige Komponente die man unabhängig verwenden kann? Soweit ich das richtig beurteile, wird das z.B. bei ZF2 auch so gemacht.

                            vg
                            jack
                            -

                            Kommentar


                            • #15
                              Apropos Interfaces:

                              Mich würde eher stören das alle Symfony Komponenten ohne Contracts implementiert sind.
                              Ich denke das ist keine Nachlässigkeit o. Ähnliches, sondern eine bewusste Entscheidung gegen Interfaces in Komponentenbibliotheken.

                              Interfaces sind zwar einerseits eine tolle Sache, anderseits haben sie auch einige Schattenseiten.

                              Published Interfaces (im Sinne von http://martinfowler.com/ieeeSoftware/published.pdf) könnten bei einem Projekt wie symfony die Entwicklung erschweren und im langfristigen Verlauf auch zu einigen Problemen führen.

                              z.B.:

                              1) Eine Erweiterung eines Interfaces um eine weitere Methode bedeutet sofort einen Bruch mit allen Klassen, die dieses Interface implementieren. Ein Problem insbesondere bei einem öffentlichen Projekt. Eine Erweiterung einer Klasse ist dagegen völlig unproblematisch.

                              2) Vielleicht haben Entwickler in eigenen Projekten Klassen/Komponenten mit extends bereits um eigene Methoden erweitert und irgendwann finden sich eine dieser Methoden zufällig im neu veröffentlichen Interface, allerdings mit einer anderen Signatur - das wäre ein Problem welches eine Refactorierung ganzer Codeabschnitte in eigenen oder auch in Kundenprojekten zur Folge hätte.

                              Ich denke der robustere Weg bei der Nutzung fremder Komponenten ist der Einsatz eigener Adapter (ggff. mit eigenen Interfaces).

                              vg
                              jack
                              -

                              Kommentar

                              Lädt...
                              X