Ankündigung

Einklappen
Keine Ankündigung bisher.

Objekte nur 1x erstellen und anschließend immer nur referenzieren

Einklappen

Neue Werbung 2019

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

  • Objekte nur 1x erstellen und anschließend immer nur referenzieren

    Hallo,
    ich habe folgendes Problem und möchte es relativ elegant lösen, die Frage ist wie man das am besten macht:

    Problem:
    PHP-Code:

    //Objekt erstellen
    $meinObjekt1 = new MeineKlasse('arg1''arg2''arg3');


    /*
    Irgendwo an einer anderen Stelle im Script wird das Objekt erneut benötigt
    und über eine Loader-Funktion automatisch via "new" erstellt, ich möchte
    aber eigentlich eine Referenz auf das zuvor erstellte Objekt "$meinObjekt1",
    da es mit den gleichen Übergabeparametern erstellt wurde.
    */
    $meinObjekt2 = new MeineKlasse('arg1''arg2''arg3'); 
    Die Objekte repräsentieren, vereinfacht, eine Zeile in einer Datenbanktabelle und um die Konsistenz zu wahren sollte es in einem laufenden Script nur einmal erstellt werden.

    Um das Problem zu lösen dachte ich an eine statische Funktion in der Klasse übergeordneten Klasse ("dbobject") von "MeineKlasse", die die Objekt-Instanzen beim erstellen in einem Array verwaltet.

    Nicht funktional, ähnlich wie nach dem Singelton Pattern:
    PHP-Code:

    class dbobject {

    protected static 
    $_instance_manager = array();

    protected static function 
    getInstance($arg1$arg2$arg3) {
    $class_name get_called_class();
      
    $key = static::getInstanceKey();
      if(!
    array_key_exists($key, static::$_instance_manager)) {
      static::
    $_instance_manager[$key] = new $class_name($arg1$arg2$arg3);
    }
    return static::
    $_instance_manager[$key];
    }

    //Vereinfacht
    protected static function getInstanceKey($arg1$arg2$arg3) {
        
    $key $arg1 $arg2 $arg3;
        
    retrun md5($key);
    }


    }

    class 
    MeineKlasse extends dbobject {

      public function 
    __construct($arg1$arg2$arg3) {
        
    //mach was
      
    }

    }

    //In beiden Variablen soll eine Referenz auf das gleiche Objekt sein
    $meinObjekt1 MeineKlasse::getInstance('arg1''arg2''arg3');
    //
    $meinObjekt2 MeineKlasse::getInstance('arg1''arg2''arg3'); 

    Ist das der beste Weg oder bietet PHP dafür andere Hilfsmittel?



    Um das Problem weiter zu verkomplizieren, eine variable Anzahl von Übergabeparametern bei den abgeleiteten Klassen wäre denkbar. Das wäre mit eigenen statischen "getInstance" Funktionen der abgeleiteten Klassen machbar, eine flexible Lösung der übergeordneten Klasse wäre aber bequemer.

    Ein weiteres Problem ist denke, dass Objekte nie während das Script läuft entladen werden, da sie ja in dem statischen Array referenziert werden, das könnte in Bezug auf Speicher ein Problem sein.


    Ich hoffe, ich habe das Problem gut genug erklärt und könnt mir evtl. helfen.

    Dank euch

    lg

  • #2
    Ich habe fuer sowas eine Minimalklasse:

    PHP-Code:
    class Cache {
        
    /**
         * @var array
         */
        
    private $instances=object[];

        
    /**
         * @param string $key
         * @param Closure $callback
         * @return object
         */
        
    public function get($keyClosure $callback) {
            if(!
    array_key_exists($key$this->instances)) {
                
    $this->instances[$key] = $callback();
            }
            return 
    $this->instances[$key];
        }

    PHP-Code:
    public function getObject() {
        return 
    $this->cache->get(__FUNCTION__, function () {
            return new \
    Some\Object();
        });

    Kommentar


    • #3
      weis nicht, probier mal folgendes aus

      PHP-Code:
      $param1 'fooo';
      //usw
      $meinObjekt = function() use($param1,$param2,$param3){
      return new 
      Irgendwas($param1,$param2,$param3);

      das ganze zentral hinterlegen spaeter im code
      PHP-Code:
      require_once 'datei-mit-objekten.php';

      var_dump($meinObjekt); 
      das waere eine art poor DI. alternativ , benutze https://github.com/fabpot/pimple
      apt-get install npm -> npm install -g bower -> bower install <package> YOLO [URL]https://www.paypal.me/BlackScorp[/URL] | Mein Youtube PHP Kanal: [url]https://www.youtube.com/c/VitalijMik[/url]

      Kommentar


      • #4
        Das Zaberwort heißt hier Singleton-Pattern.

        Kommentar


        • #5
          Pimple ist doch Müll

          Kinger, hast du den Beitrag gelesen?

          Kommentar


          • #6
            Tut es nicht - Schon gar nicht in diesem Fall. Schau Dir eher mal Identity Maps an.

            Und noch eher solltest Du lieber ein fertiges ORM als diese Eigenkreation benutzen.

            Kommentar


            • #7
              Durchgelesen hab ich mir den nicht. Ich kenne aber das Pattern aus der Programmierung und habe danch einfach mal im zusammenhang mit php gesucht.

              Hab jetzt nochmal drauf geschaut. Warum ist der Artikel nicht gut?

              EDIT: Ach du meinst diesen Beitreig. Nun ja ... überflogen. Aber man könnte das Singleton auch in den Constructor einbauen, denn kann man auch das Schlüsswort "new" nutzen. Nicht schön, sollte aber funktionieren.

              Und hiermit sollte man variable Anzahl an Parametern realisieren konnen.

              Kommentar


              • #8
                Zitat von Kinger Beitrag anzeigen
                Durchgelesen hab ich mir den nicht. Ich kenne aber das Pattern aus der Programmierung und habe danch einfach mal im zusammenhang mit php gesucht.

                Hab jetzt nochmal drauf geschaut. Warum ist der Artikel nicht gut?

                EDIT: Ach du meinst diesen Beitreig. Nun ja ... überflogen. Aber man könnte das Singleton auch in den Constructor einbauen, denn kann man auch das Schlüsswort "new" nutzen. Nicht schön, sollte aber funktionieren.

                Und hiermit sollte man variable Anzahl an Parametern realisieren konnen.
                Dieses Licht ist ziemlich dunkel.

                @Xfer: Wenn du das so willst dann bring deine Instanz dort hin. Du hast mit keinem Wort etwas darüber verloren wie du instanzen bisher verwaltest noch wie die Ziel-Objekte / Scopes überhaupt an ihre Instanzen kommen.
                [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


                • #9
                  Zitat von tr0y Beitrag anzeigen
                  @Xfer: Wenn du das so willst dann bring deine Instanz dort hin. Du hast mit keinem Wort etwas darüber verloren wie du instanzen bisher verwaltest noch wie die Ziel-Objekte / Scopes überhaupt an ihre Instanzen kommen.
                  Das war ja seine Frage... Er hat nichts, was ihm gefaellt.

                  Kommentar


                  • #10
                    Zitat von rkr Beitrag anzeigen
                    Er hat nichts, was ihm gefaellt.
                    Aus welchem Satz liest du das heraus?

                    Ansonsten kann ich dem Hinweis von tr0y nur beipflichten.

                    Kommentar


                    • #11
                      Zitat von rkr Beitrag anzeigen
                      Pimple ist doch Müll
                      und die welt ist scheisse

                      aussage ohne begruendung ist doch auch Muell
                      apt-get install npm -> npm install -g bower -> bower install <package> YOLO [URL]https://www.paypal.me/BlackScorp[/URL] | Mein Youtube PHP Kanal: [url]https://www.youtube.com/c/VitalijMik[/url]

                      Kommentar


                      • #12
                        Hab begründet

                        Kommentar


                        • #13
                          Hallo,
                          vielen Dank schon mal für die bisherigen Tipps.

                          Die Begriffe Object-Relational Mapping und Identity Maps sind denke ich sehr interessant, aber vielleicht wird es auch eine eigene kleine Lösung, schauen wir mal.

                          Im Moment erstelle ich jedes Objekt einfach per "new MeineKlasse(a, b, c)" und halte sie in lokalen Variablen oder Variablen in anderen Objekten.

                          Die automatische Objekt-Erzeugung beschränkt sich bisher darauf, dass es z.B. Funktionen gibt, die schauen ob eine vorgegebene Variable Null ist, wenn das der Fall ist wird das entsprechende Objekt erstellt, wenn nicht der Wert, das Objekt (Referenz) der Variable zurückgegeben. Die Variable ist aber halt immer nur in einen lokalen Kontext.

                          Ich möchte halt eine Lösung, die global ist und die doppelte Erstellung eines Objekte mit den gleichen Parametern unterbindet bzw. verwaltet, deswegen die Frage, was der beste Ansatz ist.

                          lg

                          Kommentar


                          • #14
                            Und dafür taugt der von mir dargestellte Ansatz nicht?

                            Kommentar


                            • #15
                              Zitat von Xfer Beitrag anzeigen
                              Hallo,
                              vielen Dank schon mal für die bisherigen Tipps.

                              Die Begriffe Object-Relational Mapping und Identity Maps sind denke ich sehr interessant, aber vielleicht wird es auch eine eigene kleine Lösung, schauen wir mal.

                              Im Moment erstelle ich jedes Objekt einfach per "new MeineKlasse(a, b, c)" und halte sie in lokalen Variablen oder Variablen in anderen Objekten.

                              Die automatische Objekt-Erzeugung beschränkt sich bisher darauf, dass es z.B. Funktionen gibt, die schauen ob eine vorgegebene Variable Null ist, wenn das der Fall ist wird das entsprechende Objekt erstellt, wenn nicht der Wert, das Objekt (Referenz) der Variable zurückgegeben. Die Variable ist aber halt immer nur in einen lokalen Kontext.

                              Ich möchte halt eine Lösung, die global ist und die doppelte Erstellung eines Objekte mit den gleichen Parametern unterbindet bzw. verwaltet, deswegen die Frage, was der beste Ansatz ist.

                              lg
                              Der beste Ansatz für das von dir beschriebene Szenario ist dass du das Objekt Das du andernorts benötigst sauber in die Klasse oder Funktion routest ( via Dependency Injection - egal mit welcher Art ).

                              Dependecy Container wie Pimple oder PHP-DI halten fertig Konfigurierte und instanziierte Objekte für dich fest und werden als ganzer container einer Methode oder einem Objekt übergeben. Beide Container können auch mit Factory Lambdas arbeiten um so das Instanziieren erst dann nötig zu machen wenn das jeweilige Objekt überhaupt erst angefordert wird.

                              Und keine sorge Pimple ist alles andere als Müll. Pimple gehört ( mit Absicht ) zu den flexibelsten und einfachsten Dependecy Injection Container. rkr vertritt nur leider die Ansicht, das ein Dependency Container erst dann Wertvoll ist, wenn er mit Commons überladen wurde.
                              [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

                              Lädt...
                              X