Ankündigung

Einklappen
Keine Ankündigung bisher.

Silex / ServiceProvider Konzept

Einklappen

Neue Werbung 2019

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

  • Silex / ServiceProvider Konzept

    Hallo zusammen,

    ich beschäftige mich zurzeit ein wenig mit Silex und in diesem Zusammenhang mit dem Konzept der Services bzw. ServiceProviders.

    Wenn ich das richtig sehe ist Silex an sich im Grunde genommen ein erweitertes Pimple-Container mit vorkonfigurierten Services wie request, routes, controllers etc. Eben mit allem was für ein Framework so benötigt wird (natürlich plus die entsprechende Framework-Logik, die sich intern dieser Services bedient). Die Applikation selbst ist somit gleichzeitig auch ein einfacher ServiceLocator.

    Dabei sind die sogenannten ServiceProvider sozusagen vorkonfigurierte Services, die sich leicht zu jeder Silex-Applikation hinzufügen lassen.

    PHP-Code:
    $app->register(new MyService()); 
    Soweit so gut. Nun sehe ich mir den Beispielcode an für einen einfachen ServiceProvider:

    http://silex.sensiolabs.org/doc/providers.html

    PHP-Code:
    use Silex\Application;
    use 
    Silex\ServiceProviderInterface;

    class 
    HelloServiceProvider implements ServiceProviderInterface
    {
        public function 
    register(Application $app)
        {
            
    $app['hello'] = $app->protect(function ($name) use ($app) {
                
    $default $app['hello.default_name'] ? $app['hello.default_name'] : '';
                
    $name $name ?: $default;

                return 
    'Hello '.$app->escape($name);
            });
        }

        public function 
    boot(Application $app)
        {
        }

    und stelle fest, daß alle Parameter des „Hello“ Service einfach im $app-container gespeichert werden. Daraufhin habe ich mir mal die Implementierung einiger Silex ServiceProvider angeschaut

    https://github.com/silexphp/Silex/tr...Silex/Provider

    und sehe da - überall das Gleiche! Alles an Parametern wird einfach in den globalen Namensraum des Applikations-Containers rein geklatscht.

    Nehmen wir z.B. den SessionServiceProvider:

    https://github.com/silexphp/Silex/bl...ceProvider.php

    alle internen Parameter des Services werden einfach im Namensraum der $app gespeichert.

    Damit mutiert die Application mit jedem weiteren Service zu einem globalen Storage für alle Services und alle die internen Serviceparameter. Kapselung der Daten – Fehlanzeige, Schutz der Daten – Fehlanzeige!

    Es ist von überall und jederzeit problemlos möglich nicht nur die Services zu ändern oder komplett zu überschreiben, sondern auch jeden internen ServiceParameter zu manipulieren. Alles liegt global und komplett ungeschützt auf dem Präsentierteller!

    Und nicht nur das, wenn man z.B. einen neuen ServiceProvider definiert und diesem zufällig einen Namen vergibt, der bereits von einem anderen Service verwendet wird, dann wird der Eine Service durch den Anderen einfach kommentarlos überschrieben, je nachdem was zuletzt registriert wird. Damit werden Fremde Serviceprovider-Bibliotheken, ohne in den Quelltext zu schauen, quasi zum russischen Roulette.

    Einfache Vertippter innerhalb der ServiceProviders können ebenfalls leicht zu schwer lokalisierbaren Fehlern führen:

    PHP-Code:
    class HelloService implements ServiceProviderInterface {
        public function 
    register(Application $app)
        {
            
    $app['hello'] = function () use ($app) {
                return 
    'Hello Jack';
            };
        }

        public function 
    boot(Application $app)
        {
        }
    }

    class 
    HalloService implements ServiceProviderInterface {
        public function 
    register(Application $app)
        {
            
    $app['hello'] = function () use ($app) {
                return 
    'Hallo Peter';
            };
        }

        public function 
    boot(Application $app)
        {
        }
    }


    $app->register(new HelloService());
    $app->register(new HalloService());

    $app->get('/hello', function () use ($app) {
        return 
    $app['hello'];
    });
    # Hallo Peter 

    Darüber hinaus gibt es natürlich auch keine konkrete Schnittstellen für den Zugriff auf die einzelnen Services. D.h. keinerlei Unterstützung durch die IDE für sämtliche Services.

    Nun drängt sich mir die Frage auf, ob Silex mit der akt. Implementierung des ServiceProvider-Konzepts nicht eine der elementarsten Regeln für gutes OOD, die Datenkapselung, derart stark verletzt , daß es sich damit selbst als (Micro)-Framework quasi komplett disqualifiziert?

    vg
    jack88

    P.S.
    Achtung: ich sehe gerade, daß die Backslashes in den Codebeispielen gefiltert werden:

    PHP-Code:
    use Silex\Application
    (Zwischen Silex und Application ist ein Backslash! (use Silex\Application )
    -


  • #2
    Silex Service Provider sind eigentverantwortlich in Sachen Kollisionserkennung, wenn du wünscht das der Application-Container sich gegen das überschreiben zur wehr setzt erweitere Silex\Application um diese Funktionalität doch.

    Das die meisten der Silex Service Provider sich nicht darum stören ob schon wer vorher den Application Container Key genutzt hat, ist wohl eher nicht Silex anzulasten.
    [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


    • #3
      Ein Framework definiert normalerweise die Rahmenbedingung und gibt somit eine Richtlinie für die Entwickler vor, an der sich diese orientieren können/sollten.

      Die meisten Entwickler greifen ja nicht zu einem Framework um es zu erweitern/verbessern, sondern weil sie sich durch eine durchdachte Struktur und tot getestete Komponenten unter anderem mehr Sicherheit und eine bessere Architektur erhoffen.

      Deshalb sehe ich hier die Verantwortung bei Silex. Das Framework verleitet durch das ServiceProvider-Konzept schlicht zu einer sehr unsauberen Arbeitsweise.

      Solche Defizite in einem bekannten Framework wie Silex zu finden überrascht mich doch sehr.

      vg
      jack
      -

      Kommentar


      • #4
        Das sich immernoch in der nahezu ersten Version befindet. Aber okay, ich bin ( ebenfalls ) gespannt wie Silex 2 wird, wenn es denn kommt. Ich denke schon das der Application Container einer der Dinge sein wird, die man dabei generalüberholen könnte.
        [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


        • #5
          Ich denke schon das der Application Container einer der Dinge sein wird, die man dabei generalüberholen könnte.
          Das denke ich auch. Und in Sachen Providers ist silex auch nicht grade fresh-breeze. ORM-Support wär da auch mal nicht ganz verkehrt.

          Kommentar


          • #6
            Leider läßt die akt. Entwicklung nicht darauf schließen, dass sich an diesem Konzept irgendetwas ändert oder besser wird.

            Das sieht man eigentlich jetzt schon sowohl an den akt. Implementierungen der ServiceProvider als auch an der register-methode der Application:

            PHP-Code:
            /**
                 * Registers a service provider.
                 *
                 * @param ServiceProviderInterface $provider A ServiceProviderInterface instance
                 * @param array                    $values   An array of values that customizes the provider
                 *
                 * @return Application
                 */
                
            public function register(ServiceProviderInterface $provider, array $values = array())
                {
                    
            $this->providers[] = $provider;

                    
            $provider->register($this);

                    foreach (
            $values as $key => $value) {
                        
            $this[$key] = $value;
                    }

                    return 
            $this;
                } 
            Das ist wirklich extrem übel.

            vg
            jack
            -

            Kommentar


            • #7
              naja, du kannst schon deine keys protecten

              angenommen du hast

              PHP-Code:
              $app->register(new MyService()); 
              im service intern erweiterst du den DI container

              PHP-Code:
              public function register(){
              $app['test'] = $app->protect(function(){});

              nun möchte jemand $app['test'] überschreiben geht es nicht, denn $app['test'] ist im protected drin https://github.com/fabpot/Pimple/blo...ainer.php#L182

              persönlich gefällt mir aber der Ansatz, dass ich bestimmte arraykeys definieren kann und andere können es überschreiben, so muss man nicht von irgendwelchen basisklassen ableiten und eventeull nicht notwendige abhängikeit mit injezieren sondern man hat die freiheit x belibige klasse mit eigener einfach ersetzen.


              ich versuche das ganze sogar zu erleichtern indem ich konstanten für die keys definiere damit andere in ihrer IDE dann eine autocompletition haben

              https://github.com/Opentribes/Core/b...roller.php#L21

              bezüglich totgetestet und rahmenbediengungen etc , kann man ja dann Symfony nutzen, silex ist eher ein loses framework der dir alles erlaubt, es hat ein paar kleinere vorkonfigurierte dinge und outofthebox provider aber du musst diese nicht nutzen
              apt-get install npm -> npm install -g bower -> bower install <package> YOLO https://www.paypal.me/BlackScorp | Mein Youtube PHP Kanal: https://www.youtube.com/c/VitalijMik

              Kommentar


              • #8
                naja, du kannst schon deine keys protecten
                Nein, das kannst Du nicht. Die Methode protect hat keine Schutzfunktion für Parameter oder keys, sie ist ganz anders zu verstehen:

                Because Pimple sees anonymous functions as service definitions, you need to wrap anonymous functions with the protect() method to store them as parameter
                persönlich gefällt mir aber der Ansatz, dass ich bestimmte arraykeys definieren kann und andere können es überschreiben,
                Ja, das bringen globale Variablen so mit sich, sie sind halt sehr bequem und flexibel anzuwenden. Bekanntermaßen ist diese enorme Flexibilität leider mit einigen gravierenden Nachteilen verbunden.

                Schau Dir einfach mal die register() Methode genau an. Damit ist es problemlos möglich alleine schon durch das bloße Registrieren eines ServiceProviders die komplette Applikation unbrauchbar zu machen und zwar mitten in ihrem Kern:

                $app->register(new HalloService(), array('routes' => 'Irgendein Parameter'));

                und nichts geht mehr.

                Jeder ServiceProvider kann die Applikation komplett zerstören, ihr Verhalten ändern, ganze Kernmodule auswechseln, einfach alles.

                Das ist in etwa so, als wenn jedes Programm beliebige Änderungen am Betriebssystem vornehmen könnte. Wäre das gut?

                vg
                jack
                -

                Kommentar


                • #9
                  jedes hat seine vor und nachteile,

                  alles zu verstecken und festzunageln bedeutet, viele konfigurations möglichkeiten oder konventionen notwendig, viele abstrakte klassen zur ableitung notwendig, in spezial fällen eingeschränkte flexibilität, kompabilität der basis anwendung kann auch ganze applikationen zerstören etc etc

                  Code:
                  Jeder ServiceProvider kann die Applikation komplett zerstören, ihr Verhalten ändern, ganze Kernmodule auswechseln, einfach alles.
                  für mich klingt das nach viel freiheit, ein schutz gegen dummheit gibt es ja sowieso nicht, also versuche ich viele möglichkeiten zu bieten und wer dumm genug ist aus den freiheiten ein chaos anzurichten, ist selbst schuld

                  Das ist in etwa so, als wenn jedes Programm beliebige Änderungen am Betriebssystem vornehmen könnte. Wäre das gut?
                  Und jedes Programm erweitert die funktionialität des Betriebsystems, macht auch veränderungen(neue datei anlegen, externe services wie smtp, http etc ansprechen usw)

                  stell dir vor, du könntest mit einem browser auf die GPU deiner grafikkarte zugreifen.. das wäre doch verrückt oder?

                  es kommt halt wie immer auf den anwendungsfall an, ich habe gerade deshalb zb silex benutzt, nicht weil ich eine sammlung von phpscripten habe mit vorgegebenen konventionen/konfigurationen sondern vielmehr weil ich die freiheit habe alles selber so zu nutzen wie ich es für richtig halte
                  apt-get install npm -> npm install -g bower -> bower install <package> YOLO https://www.paypal.me/BlackScorp | Mein Youtube PHP Kanal: https://www.youtube.com/c/VitalijMik

                  Kommentar


                  • #10
                    jedes hat seine vor und nachteile,
                    Sowie das beliebte register_globals=on. Die Vorteile waren so verlockend, daß man sich schließlich gezwungen sah die Option per default auf off zu setzen um den Nachteilen vorzubeugen.

                    Jeder ServiceProvider kann die Applikation komplett zerstören, ihr Verhalten ändern, ganze Kernmodule auswechseln, einfach alles.

                    > für mich klingt das nach viel freiheit,
                    FREIHEIT? Für mich klingt das nach Anarchie. Es ist keine Freiheit wenn jeder ein Atomkraftwerk stilllegen oder die Wasserversorgung unterbrechen kann.

                    Und jedes Programm erweitert die funktionialität des Betriebsystems
                    Es spricht nichts gegen Erweiterungen, aber bitteschön unter einer Kernbedingung: sie dürfen die Stabilität des gesamten Systems nicht gefährden.

                    Mit Deinen Aussagen stellst Du zumindest eines der elementarsten Konzepte von OOP, nämlich das Konzept der Datenkapselung komplett in Frage.

                    Meiner Ansicht nach gehören Datenkapselung und das Vermeiden von Globals zu den grundlegendsten Regeln für gutes Softwaredesign. Diese Regeln werden in Silex definitiv im großen Stil verletzt. Das halte ich für ein Problem, insbesondere deshalb, weil solche Frameworks vor allem gerne Anfängern empfohlen werden.

                    Wer weiß, möglicherweise wirst Du Deine akt. Signatur irgendwann nur minimal anpassen müssen

                    "Service registriert und Script geht nicht.. No Joke Silex"

                    vg
                    jack
                    -

                    Kommentar


                    • #11
                      Also ich finde du solltest das mit Fabien Potencier diskutieren. Weil er hat schlussendlich die Design-Entscheidung gefällt und keinen Zettel da gelassen warum er sich so entschieden hat. Aber ich vermute mal aus dem Grund weil Silex so offen wie möglich konzipiert wurde.

                      Ich glaub bei FlightPHP drehst du ganz ab, wenn du es siehst.. ^^
                      [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
                        Zitat von jack88 Beitrag anzeigen
                        Sowie das beliebte register_globals=on. Die Vorteile waren so verlockend, daß man sich schließlich gezwungen sah die Option per default auf off zu setzen um den Nachteilen vorzubeugen.
                        der unterschied zwischen silex und globals ist, dass du deine $app irgendwie weiterleiten musst, da wo $app relevant ist nutzt man es halt, da wo es nicht relevant ist und man nur teile des $app container braucht, leitet man es über DI weiter. bei globals hatte man diese einschränkung nicht

                        Zitat von jack88 Beitrag anzeigen
                        FREIHEIT? Für mich klingt das nach Anarchie. Es ist keine Freiheit wenn jeder ein Atomkraftwerk stilllegen oder die Wasserversorgung unterbrechen kann.
                        ja weniger regeln beudetet schwierigere kontrolle

                        Zitat von jack88 Beitrag anzeigen
                        Es spricht nichts gegen Erweiterungen, aber bitteschön unter einer Kernbedingung: sie dürfen die Stabilität des gesamten Systems nicht gefährden.
                        nun sind aber Kernbedienungen nicht in den Steingemeißelt und werden auch im Laufe der Jahre mal eben verändert, hält man sich ein mal dran, muss man es immer machen und mit der veränderung die applikation anpassen, hat man es nicht gemacht, gibt es kompabilitätsprobleme

                        Zitat von jack88 Beitrag anzeigen
                        Mit Deinen Aussagen stellst Du zumindest eines der elementarsten Konzepte von OOP, nämlich das Konzept der Datenkapselung komplett in Frage.

                        Meiner Ansicht nach gehören Datenkapselung und das Vermeiden von Globals zu den grundlegendsten Regeln für gutes Softwaredesign. Diese Regeln werden in Silex definitiv im großen Stil verletzt. Das halte ich für ein Problem, insbesondere deshalb, weil solche Frameworks vor allem gerne Anfängern empfohlen werden.
                        würde ich nicht sagen, unter Datenkapselung wird protected, private etc gemeint, wenn ich eine komplette klasse ersetze, wird diese eben nicht so funktionieren wie gedacht, aber es gibt ja interfaces mit denen man die Kernbedienungen bestimmen kann und ich finde, interfaces sind sogar bessere rahmenbedienungen als vorgegebene ordnerstrukturen.

                        ja, du kannst bei silex $app['irgendwas'] überschreiben, jederzeit. aber du kannst die weiterbenutzung von $app['irgendwas'] durch gegebene interfaces steuern.

                        Zitat von jack88 Beitrag anzeigen
                        Wer weiß, möglicherweise wirst Du Deine akt. Signatur irgendwann nur minimal anpassen müssen

                        "Service registriert und Script geht nicht.. No Joke Silex"

                        vg
                        jack
                        nein, das problem bei meinem joke ist, dass die Kommentare, die deinen code beschreiben sollen, in Doctrine blöderweise auch noch das Verhalten steuern. Kommentare sollten halt keine magische logik haben, service überschreiben ist was anderes, da hat man wenigstens code benutzt, welcher für logik zuständig ist.


                        ich erlaube jedem, die silex keys zu überschreiben und durch eigene zu ersetzen
                        https://github.com/Opentribes/Core/b...ry.php#L34-L36

                        aber wenn die es tun, dann sollen sie sich gefällig an mein interface halten
                        https://github.com/Opentribes/Core/b...ccount.php#L32

                        keine Anarchie mehr freiheit mit ein wenig kontrolle
                        apt-get install npm -> npm install -g bower -> bower install <package> YOLO https://www.paypal.me/BlackScorp | Mein Youtube PHP Kanal: https://www.youtube.com/c/VitalijMik

                        Kommentar


                        • #13
                          @troy

                          Also ich finde du solltest das mit Fabien Potencier diskutieren.
                          Naja, ich diskutiere ja auch nicht jedes Mal mit der Merkel wenn sie eine politische Entscheidung getroffen hat. Man darf doch eine eigene Meinung haben, die Entscheidungen der anderen kritisch hinterfragen und mit Gott und der Welt darüber diskutieren - dafür sind schliesslich öffentliche Foren auch da.

                          Wenn Dich das Thema nicht interessiert, dann ignoriere es doch einfach und wenn Du meine Argumente oder Sichtweise für falsch hältst dann kannst Du sie ja gerne widerlegen.

                          weil Silex so offen wie möglich konzipiert wurde.
                          Unter dem Begriff offen versteht man bei objektorientierten Softwareentwürfen eigentlich, dass die Komponenten offen für Erweiterungen, aber geschlossen für Änderungen sind/sein sollen. Das ist bei Silex nicht der Fall. Silex ist (durch das ServiceProvider-Konzept) offen wie ein Scheunentor welches nicht geschlossen werden kann.

                          Ich denke es kann zumindest nicht schaden, wenn man das weiß.

                          vg
                          jack
                          -

                          Kommentar


                          • #14
                            Interessant das du das so siehst, wie ich gerade schon jprangenberg auf Facebook mitteilte missverstehst du die Intention von Silex ~1.0. Es ist von Silex erwünscht das Services von Hause aus tun und lassen können was sie wollen, es liegt an dir das abzuändern wenn es dir nicht passt. Silex baut auf einen Dependency Container auf ( Pimple ) der das zulässt und dahingehend erst abgesichert werden muss, wenn er denn diese Funktionalität besitzen soll.

                            Grundsätzlich kann ich ja verstehen das es dich stört, aber du erwartest von einem Micro-Framework das was ein Fullstack Framework leisten würde. Silex bezieht sich auf den einfach(sten) Umgang mit den Micro-Framework Komponenten, es ist schlichtweg nicht weiter zu vereinfachen Services anzulegen und erweiterbar zu machen.

                            Silex ist okay so wie es ist, wer striktes Service-Handling will, soll sich dieses bitte selbst implementieren. Der Aufwand und die Logik dazu ist relativ gering.
                            [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


                            • #15
                              missverstehst du die Intention von Silex ~1.0. Es ist von Silex erwünscht das Services von Hause aus tun und lassen können was sie wollen,�*
                              Das ist eine ziemlich merkwürdige Art zu argumentieren.

                              Wenn ich ein Framework hätte, bei dem es viele globale Variablen gibt und ich es damit begründe, daß es die Intention von diesem Framework ist Variablen so einfach wie möglich verfügbar zu machen, dann wäre das also ok?

                              - sind globale Variblen grundsätzlich schlecht,
                              - ist Datenkapselung grundsätzlich gut,
                              - ist das Open-Closed-Prinzip grundsätzlich gut,

                              oder hängt es letztendlich von der "Intention" ab?

                              Sollen wir das alles jetzt in Frage stellen, oder können wir uns darauf einigen , daß diese Prinzipien gelten?

                              Verletzt Silex diese Prinzipien? Ich meine JA und zwar alle drei.

                              Ist das gut, profitiert irgendjemand von der Verletzung der o.g. Prinzipien?

                              vg
                              jack
                              -

                              Kommentar

                              Lädt...
                              X