hotti: Variable an eine Klasse binden

hi,

idealerweise hätte ich das, was in Perl mit tie() möglich ist, auch in PHP. Es wird eine Variable (array) an eine Klasse gebunden, fiktiver Code:

  
$cfg = array();  
$tied = tie($cfg, 'CFG');  
  
$d = $cfg['default'];  
/* hier soll über die Klasse eine Methode aufgerufen werden, welche auf den angeforderten index 'default' ein weiteres Array legt.  
*/  
  
// Noticer: indefined Index  

Wie könnte ich solch ein Verhalten in PHP implementieren? Hat jemand einen Ansatz?

Danke im Vorab,
Horst Hacke

  1. hi,

    hast Du dir mal das Zend Framework angeguckt und dort in den Quellcode (irgendwo hier zB.: http://framework.zend.com/apidoc/2.1/classes/Zend.Db.Sql.ExpressionInterface.html).

    Eine ältere Zend-Mailklasse zum Beispiel:

      
    class Zend_Mail extends Zend_Mime_Message  
    {  
        /**#@+  
         * @access protected  
         */  
      
        /**  
         * @var Zend_Mail_Transport_Abstract  
         * @static  
         */  
        protected static $_defaultTransport = null;  
    
    

    weiter unten gibt es dann eine setter-Methode ...;

    mfg

    tami

    1. hi,

      hast Du dir mal das Zend Framework angeguckt und dort in den Quellcode (irgendwo hier zB.: http://framework.zend.com/apidoc/2.1/classes/Zend.Db.Sql.ExpressionInterface.html).

      Ja, wenn es gelänge, den Zugriff auf einen undefined index in einen Zugriff auf ein nicht vorhandenes Attribut umzubiegen, wäre alles geritzt. Idee?

      Horst

  2. Tach!

    $d = $cfg['default'];
    /* hier soll über die Klasse eine Methode aufgerufen werden, welche auf den angeforderten index 'default' ein weiteres Array legt.
    */
    Wie könnte ich solch ein Verhalten in PHP implementieren? Hat jemand einen Ansatz?

    Du möchtest also einen Array-Zugriff, den du selbst kontrollieren kannst. Dann erstell dir eine Klasse, die das ArrayAccess-Interface implementiert.

    dedlfix.

    1. hi,

      Du möchtest also einen Array-Zugriff, den du selbst kontrollieren kannst. Dann erstell dir eine Klasse, die das ArrayAccess-Interface implementiert.

      Oh, yeah, ... implements... das sieht gut aus, danke Dir!!!!

      Das wird ne ruhige Nacht, in Brettschaltung funktioniert das, morgen kommt der Hammer drauf ;)

      Viele Grüße aus Hackenheim,
      Horst Hacke

  3. Hi,

    idealerweise hätte ich das, was in Perl mit tie() möglich ist, auch in PHP. Es wird eine Variable (array) an eine Klasse gebunden, fiktiver Code:

    $cfg = array();
    $tied = tie($cfg, 'CFG');

    $d = $cfg['default'];
    /* hier soll über die Klasse eine Methode aufgerufen werden, welche auf den angeforderten index 'default' ein weiteres Array legt.
    */

    // Noticer: indefined Index

    
    >   
    > Wie könnte ich solch ein Verhalten in PHP implementieren? Hat jemand einen Ansatz?  
      
    Ich würde versuchen, darauf zu verzichten. Es scheint mir, als ob dieser Ansatz ziemlich genau [Primitive Obsession](http://c2.com/cgi/wiki?PrimitiveObsession) entspricht: du verwendest einen array, obwohl deine Daten kein reiner Array sind sondern eine Sonderbedeutung haben (welches du durch das `tie()`{:.language-php} ausdrücken willst).  
      
    Ein IMHO(!) besserer Ansatz ist es, eine Konfigurationsklasse zu schreiben (ich nehme an, dass cfg für config stehen soll). Dort schreibst du dann deinen []-Operator (also eine Methode `get($key)`{:.language-php}, und darin kannst du dann jegliche Sonderbedeutung reinpacken, die du haben willst.  
      
    Bis die Tage,  
    Matti
    
    1. hi Matti,

      Ich würde versuchen, darauf zu verzichten. Es scheint mir, als ob dieser Ansatz ziemlich genau Primitive Obsession entspricht:

      Nein ;)

      du verwendest einen array,

      Ja.

      obwohl deine Daten kein reiner Array

      Doch ;)

      sind sondern eine Sonderbedeutung haben

      Nein.

      (welches du durch das tie() ausdrücken willst).

      Perl's tie() ist nicht einfach zu verstehen. Ich werde das heute in PHP implementieren, für meinen Bedarf umsetzen und einen kleinen Artikel darüber schreiben. Gestern beim gogeln habe ich gesehen, dass ein breites Interesse daran besteht.

      Viele Grüße,
      Horst

      1. Moin!

        Perl's tie() ist nicht einfach zu verstehen. Ich werde das heute in PHP implementieren, für meinen Bedarf umsetzen und einen kleinen Artikel darüber schreiben. Gestern beim gogeln habe ich gesehen, dass ein breites Interesse daran besteht.

        Ich geb 'n Tipp ab: Reimplementierung von SPL-Objekten.

        - Sven Rautenberg

        1. Moin Sven!

          Perl's tie() ist nicht einfach zu verstehen. Ich werde das heute in PHP implementieren, für meinen Bedarf umsetzen und einen kleinen Artikel darüber schreiben. Gestern beim gogeln habe ich gesehen, dass ein breites Interesse daran besteht.

          Ich geb 'n Tipp ab: Reimplementierung von SPL-Objekten.

          Genau! Jeden Tag ein bischen besser ;)

          Hotti

  4. Mein Ansatz ist ähnlich wie der von dedlfix, jedoch benutze ich eine fertige Klasse bzw. ein fertiges Klassenmodel: ArrayObject

    Das ganze sieht dann ungefähr so aus

    class cHotti extends ArrayObject  
    {  
        public function offsetSet( $key, $value )  
        {  
            if( $key == "default" )  
            {  
                //--- mach was  
            }  
            return parent::offsetSet( $key, $value );  
        }  
    }
    

    Aufgerufen wir das ganze mit

      
    $objHotti = new cHotti();  
    $objHotti["default"] = "meine eingabe";  
    
    

    Also wie ein normales Array. Jedoch kann man die Klasse Hotti um Methoden erweitern. So könnte man dem ganzen z.B. auch eine save Methode geben, welche die Daten in die Datenbank speichert bzw. wiederum eine Klasse initialisiert, die das übernimmt.
    Ein weiterer Vorteil ist, dass das ganze Konstrukt als normales Array betrachtet werden kann. Man kann es mittels foreach durchlaufen. Wer es komplett Objekt orientiert mag kann aber auch die ArrayIterator Klasse benutzen.

    Du kannst auch den get beeinflussen "offsetGet" oder die Methode die bei einem isset($objHotti['default']) aufgerufen wird -> offsetExists.

    Seit dem ich mit dem Teil arbeite wurde mein Code viel effizienter. Kleiner Haken an der Sache ist, dass man den Code etwas mehr "magic" gestaltet und beim Debuggen eventuell Probleme bekommt.

    Hoffe ich konnte helfen.

    Gruß
    Deutsches Finale? Gibt's jedes Jahr im DFB Pokal und da freut sich niemand.
    T-Rex

    1. Tach!

      Mein Ansatz ist ähnlich wie der von dedlfix, jedoch benutze ich eine fertige Klasse bzw. ein fertiges Klassenmodel: ArrayObject

      Ja, das macht dasselbe in grün, und noch etwas mehr, weil es nicht nur ArrayAccess implementiert. Allerdings hat man keinen direkten Zugriff auf die Daten, sondern kann nur die parent-Methoden verwenden. Das kann nachteilig sein, muss es aber nicht.

      Also wie ein normales Array. Jedoch kann man die Klasse Hotti um Methoden erweitern. So könnte man dem ganzen z.B. auch eine save Methode geben, welche die Daten in die Datenbank speichert ...

      Das sollte man möglichst vermeiden, damit die Klasse bei ihrer einen Aufgabe bleibt und kein Universalmonster wird. Eine Kuh melkt sich auch nicht selbst.

      ... bzw. wiederum eine Klasse initialisiert, die das übernimmt.

      Das ist mir etwas unverständlich. Die Speicherung jedenfalls kommt auf den Zweck des Arrays an. Entweder gibt es einen Mapping-Mechanismus, der die Array-Felder in Tabellenfelder umsetzt, oder die Tabelle ist nur ein Key-Value-Speicher oder die Array-Daten werden serialisiert und als ein String in einem Tabellenfeld abgelegt (SLOB: serialized LOB). Letzteres kann man nehmen, wenn die Datenbank nicht auf die einzelnen Elemente zugreifen muss oder Relationen zu pflegen sind.

      Ein weiterer Vorteil ist, dass das ganze Konstrukt als normales Array betrachtet werden kann. Man kann es mittels foreach durchlaufen. Wer es komplett Objekt orientiert mag kann aber auch die ArrayIterator Klasse benutzen.

      Jein. Normale Array-Funktionen kann man damit nicht oder nur begrenzt aufrufen.

      dedlfix.

      1. Ja, das macht dasselbe in grün, und noch etwas mehr, weil es nicht nur ArrayAccess implementiert. Allerdings hat man keinen direkten Zugriff auf die Daten, sondern kann nur die parent-Methoden verwenden. Das kann nachteilig sein, muss es aber nicht.

        Stimmt doch gar nicht. Kannst auf die Daten direkt zugreifen:
        $objHotti['irgend'] = "was";
        echo $objHotti['irgend']; //--- was

        ohne eine Implementierung einer Methode ! Man kann die Parent Methoden aber benutzen um die Eingaben z.B. zu validieren, ändern, loggen etc...

        Also wie ein normales Array. Jedoch kann man die Klasse Hotti um Methoden erweitern. So könnte man dem ganzen z.B. auch eine save Methode geben, welche die Daten in die Datenbank speichert ...

        Das sollte man möglichst vermeiden, damit die Klasse bei ihrer einen Aufgabe bleibt und kein Universalmonster wird. Eine Kuh melkt sich auch nicht selbst.

        Deshalb stehen die Worte z.B. (zum Beispiel) dabei. Es ist nur ein Beispiel, eine Möglichkeit. Es war keine Empfehlung. Und die selbstmelkende Kuh wird gerade von Monsanto gezüchtet! Nee leider nicht, die sind damit beschäftigt die Euter noch größer und eitriger zu bekommen, damit noch mehr Milch weggeschüttet werden kann (EU Vorgabe), aber ich schweife ab :D.

        ... bzw. wiederum eine Klasse initialisiert, die das übernimmt.

        Das ist mir etwas unverständlich.

        Das wäre der richtige Ansatz um das Universalmonster zu umgehen. Dann würde der aufruf nicht so aussehen:
        $objHotti->save();  //--- mit einer internen Speicherroutine
        sondern
        $objSaver->save( $objHotti );  //--- Speicherung wird von einem anderen Objekt übernommen.

        Ein weiterer Vorteil ist, dass das ganze Konstrukt als normales Array betrachtet werden kann. Man kann es mittels foreach durchlaufen. Wer es komplett Objekt orientiert mag kann aber auch die ArrayIterator Klasse benutzen.
        Jein. Normale Array-Funktionen kann man damit nicht oder nur begrenzt aufrufen.

        Das stimmt. Gut dass ich mich hier auf das foreach beschränkt habe. Einige "Array"-Funktionen packen das ArrayObject, andere nicht. Dafür gibts aber die tolle Funktion "getArrayCopy". Dass gibt dir ein Array als Kopie des ArrayObjectes zurück.

        Ansonsten denke ich sollten wir Hotti helfen und nicht unsere Posts zerpflücken. Wobei ich im Moment etwas empfindlich bin, da mein Chef ein Arschloch ist!

        Gruß
        Fussabtretter
        T-Rex

        1. Tach!

          Ja, das macht dasselbe in grün, und noch etwas mehr, weil es nicht nur ArrayAccess implementiert. Allerdings hat man keinen direkten Zugriff auf die Daten, sondern kann nur die parent-Methoden verwenden. Das kann nachteilig sein, muss es aber nicht.

          Stimmt doch gar nicht. Kannst auf die Daten direkt zugreifen:
          $objHotti['irgend'] = "was";
          echo $objHotti['irgend']; //--- was

          ohne eine Implementierung einer Methode !

          Die Methoden sind doch schon implementiert und sie werden durch diese "Direkt"zugriffe auch nur aufgerufen. Man kann die Methoden gleich ohne Umweg aufrufen - wenn man im Code einer abgeleiteten Klasse ist, was ich eigentlich meinte. Von außen ist der Array-Zugriff sinnvoll, denn dafür ist er ja da.

          Ansonsten denke ich sollten wir Hotti helfen und nicht unsere Posts zerpflücken.

          Mein Ziel ist nicht, Posts zu zerpflücken. Das passiert nur nebenbei, wenn ich den einen oder anderen Punkt einer Antwort noch weiter diskutieren möchte.

          dedlfix.

  5. hi,

    idealerweise hätte ich das, was in Perl mit tie() möglich ist, auch in PHP. Es wird eine Variable (array) an eine Klasse gebunden, fiktiver Code:

    Nix fiktiv, hier ist ein Beispiel für PHP mit eigenen Serialize-Algorithmen (freeze, thaw), damit ist die Binärdatei voll kompatibel zu Perl (Hash in Binärdatei).

    Hotti

  6. hi,

    idealerweise hätte ich das, was in Perl mit tie() möglich ist, auch in PHP. Es wird eine Variable (array) an eine Klasse gebunden, fiktiver Code:

    Wozu das gut ist, habe ich hier mal aufgeschrieben heute.

    Nicht ganz so glücklich bin ich mit der Iteration über die Limit-Klause, weil hierbei kein Platzhalter möglich ist (prepared Statement). Es gibt jedoch auch noch einen anderen Grund, das DB-Design zu überarbeiten: Ein zusätzliches Feld, nach dem benutzerdefiniert sortiert werden kann. Über dieses Feld wird dann auch der Iterator laufen und so ist dann auch ein prepared Statement möglich, was der Iteration einen erheblichen Performanzeschub geben wird.

    Also, ich denke, dass ich das auch in PHP hinkriege ;)

    Viele Grüße,
    Rolf

    1. Tach!

      idealerweise hätte ich das, was in Perl mit tie() möglich ist, auch in PHP. Es wird eine Variable (array) an eine Klasse gebunden, fiktiver Code:
      Wozu das gut ist, habe ich hier mal aufgeschrieben heute.

      Wenn es darum geht, ein Array lazy zu befüllen, also erst wenn nach diesem Eintrag gefragt wird, dann wäre in PHP das schon erwähnte ArrayAccess eine Möglichkeit.

      Allerdings sehe ich den Sinn noch nicht. Ein Router routet in der Regel _einen_ Request und nach diesem wird der Speicher wieder aufgeräumt. Beim nächsten Request hat man wieder ein leeres Routing-Array. Für den Fall braucht es nur eine einfache Datenabfragefunktion.

      Nicht ganz so glücklich bin ich mit der Iteration über die Limit-Klause, weil hierbei kein Platzhalter möglich ist (prepared Statement).

      Hmm, das MySQL-Handbuch statiert aber (bis zurück zu Version 5.0, vorher gab es keine Prepared Statements), dass Limit-Werte zwar konstante Integer-Ausdrücke sein müssen, aber Plazhalter in einem Prepared Statement dafür verwendet werden können.

      Es gibt jedoch auch noch einen anderen Grund, das DB-Design zu überarbeiten: Ein zusätzliches Feld, nach dem benutzerdefiniert sortiert werden kann. Über dieses Feld wird dann auch der Iterator laufen und so ist dann auch ein prepared Statement möglich, was der Iteration einen erheblichen Performanzeschub geben wird.

      Bei diesen Teil (und auch schon "Iteration über die Limit-Klausel") verstehe ich nicht, was gemeint ist.

      dedlfix.

      1. hi,

        Allerdings sehe ich den Sinn noch nicht.

        Der Sinn ist der: Ich habe die Routing-Table z.Z. als Array im Hauptspeicher. Das Array wächst...

        Ein Router routet in der Regel _einen_ Request

        Genau. Es wird nur _ein_ URL angefordert. Im Array jedoch liegen sie alle ;)

        [] Für den Fall braucht es nur eine einfache Datenabfragefunktion.

        Ja. Aber: Ich will nicht den bisherigen Code umbauen, sondern weiter mit dem Array arbeiten. D.h., anstelle des Aufrufs einer Methode wird das Array befragt wobei dann im Hintergrund die DB-Abfrage stattfindet.

        Bei diesen Teil (und auch schon "Iteration über die Limit-Klausel") verstehe ich nicht, was gemeint ist.

        Platzhalter wie so etwa "... Limit ?,1" sind nicht möglich. Somit sind auch keine prepared Statements möglich. Ich habe mittlerweile mein DB-Design überarbeitet, es gibt nun ein zusätzliches Feld 'lfdnr' was gleichzeitig die Sortierung erledigt. Platzhalter in etwa "... lfdnr=?" sind jetzt möglich und damit auch ein prepared Statement was die an die DB gekoppelte Iteration wunderbar beschleunigt. Bisherige Tests, ich habs erstmal mit Perl aufgebaut: Das sieht performanzemassig richtig gut aus ;)

        Danke für Dein Interesse!
        Horst

        1. hi,

          Allerdings sehe ich den Sinn noch nicht.

          Der Sinn ist der: Ich habe die Routing-Table z.Z. als Array im Hauptspeicher. Das Array wächst...

          Ein Router routet in der Regel _einen_ Request

          Genau. Es wird nur _ein_ URL angefordert. Im Array jedoch liegen sie alle ;)

          [] Für den Fall braucht es nur eine einfache Datenabfragefunktion.

          Ja. Aber: Ich will nicht den bisherigen Code umbauen, sondern weiter mit dem Array arbeiten. D.h., anstelle des Aufrufs einer Methode wird das Array befragt wobei dann im Hintergrund die DB-Abfrage stattfindet.

          PS: Für's Routing reicht eine Abfrage, das ist richtig. In meinem Array steckt jedoch nicht nur die Routing-Table (das ist nur die Bindung URL=>Klasse) sondern auch die gesamte Konfiguration, wie auch die Hierarchie der Dokumentenablage. D.h., es muss eine Iteration möglich sein. Dafür brauchts einen greifbaren Index  in der Tabelle, diesen über Limit zu emulieren war nur eine Notlösung.

          Weiteres Beispiel: Perl tie, hier haben wir ein im Hauptspeicher abgebildetes Array (liegt in der Instanze) und somit einen greifbaren Index.

          --Rosti

          1. Tach!

            Allerdings sehe ich den Sinn noch nicht.
            Der Sinn ist der: Ich habe die Routing-Table z.Z. als Array im Hauptspeicher. Das Array wächst...
            Ein Router routet in der Regel _einen_ Request
            Genau. Es wird nur _ein_ URL angefordert. Im Array jedoch liegen sie alle ;)

            Das hab ich schon verstanden, aber bei PHP verbleibt zwischen zwei Requests nichts im Hauptspeicher. Das Array wächst also immer nur von 0 auf einen Eintrag, das aber mit jedem Request. Ein Array ist da also sinnlos. Selbst wenn du es zwischen zwei Requests irgendwo serialisiert ablegst, wird die Angelegenheit insgesamt nicht besser.

            Ja. Aber: Ich will nicht den bisherigen Code umbauen, sondern weiter mit dem Array arbeiten. D.h., anstelle des Aufrufs einer Methode wird das Array befragt wobei dann im Hintergrund die DB-Abfrage stattfindet.

            Ein sich selbst füllendes Array für die Anfrage nach nur einem Ergebnis ist nicht gerade ein intentionsgemäßer Gebrauch.

            PS: Für's Routing reicht eine Abfrage, das ist richtig. In meinem Array steckt jedoch nicht nur die Routing-Table (das ist nur die Bindung URL=>Klasse) sondern auch die gesamte Konfiguration, wie auch die Hierarchie der Dokumentenablage. D.h., es muss eine Iteration möglich sein.

            Also eine Universalstruktur, die nun für alles Mögliche und unmögliche verwendet werden soll.

            Dafür brauchts einen greifbaren Index  in der Tabelle, diesen über Limit zu emulieren war nur eine Notlösung.

            Du meinst, viele Einzelabfragen (versteckt in einem Array-Zugriff) sind besser als eine einzige Abfrage nach allen benötigten Werten? Hast du das mal gegeneinander gemessen?

            Platzhalter wie so etwa "... Limit ?,1" sind nicht möglich. Somit sind auch keine prepared Statements möglich.

            Diese Aussage bestätigt, wie schon erwähnt, das MySQL-Handbuch nicht. Mein Test eben auch nicht.

            dedlfix.

            1. hi,

              Das hab ich schon verstanden, aber bei PHP verbleibt zwischen zwei Requests nichts im Hauptspeicher.

              Logo ;)
              Mir gehts jedoch darum, für _eine_ Abfrage nicht ein großes Array in den Hauptspeicher zu legen.

              Ein sich selbst füllendes Array für die Anfrage nach nur einem Ergebnis ist nicht gerade ein intentionsgemäßer Gebrauch.

              Sorry, Missverständnis: Das Array wird nicht 'gefüllt'. Es ist schon voll ;)

              Also bisher habe ich in meinem Bootstrap-Prozess:
              $class = $CFG['/index.html']['class'];
              Diese Class wird gebraucht, um das Response-Objekt als Instanz eben der Klasse zu erstellen (vereinfacht).

              In Zukunft:
              Das Array wird 'gebunden', d.h., es ist 'leer'. Ein Code
              $class = $CFG['/index.html']['class'];
              wird dieses Array NICHT befüllen, sondern nur den Wert zurückliefern.

              Du meinst, viele Einzelabfragen (versteckt in einem Array-Zugriff) sind besser als eine einzige Abfrage nach allen benötigten Werten? Hast du das mal gegeneinander gemessen?

              Nein. Es gilt, die Balance zwischen Performance und Hauptspeicher zu halten, das ist immer eine Gratwanderung. Freilich gibts fürs Routing nur die eine Abfrage auf die Klasse, logisch, ein Request => eine Klasse.

              Wenn es mir nur um das Routing gänge, da wäre das auch ein leichter Tanz auf dem Grat.
              Ein Messen (Benchmark) erübrigt sich: Es ist klar, dass sowohl

              • schon eine einzelne Abfrage (Klasse ermitteln fürs Routing)
                als auch (erst recht)
              • eine Iteration (Sitemap) über ein derart an die DB gekoppeltes Array

              länger dauert, als hätten wir das Array körperlich im RAM liegen. Nach meiner Erfahrung liegt die Hauptverzögerung jedoch im Connect zur DB. Sofern die Verbindung steht, geht das über prepared Statements sehr performant ab. Dabei ists völlig egal, ob die Abfragen über einen Array-Layer laufen oder über Methoden-Aufrufe.

              Es wäre nicht sinnvoll, das Array aus der DB in einem Rutsch zu lesen, weil: Das habe ich jetzt.

              Der Hauptgrund, warum ich diesen Layer einbaue: Alles, was an Code hinten dran hängt, bleibt wie es ist ;)

              Es wäre nicht sinnvoll, den gesamten Code zu ändern zum Einbau von Methoden-Aufrufen, damit werden DB-Abfragen auch nicht performanter, als über den Array-Layer.

              Ergo: Bis jetzt siehts gut aus, wird jedoch noch ein bischen Geficke mit dem Iterator, das ist für mich Neuland, aber ich lerne gerne ;)
              In Perl besteht der Iterator aus 2 Methoden, die zu überlagern sind (FIRSTKEY und NEXTKEY) in PHP ist ein Interface zu implementieren mit 5 Methoden.

              class TieUrlMap extends ArrayObject implements Iterator  
              
              

              Bisher auch kein Problem: Es muss möglich sein, dem Array Werte hinzufügen zu können (temporär aber genauso im Zugriff wie Daten aus der DB). Die Values sind übrigens auch wieder Arrays. Es wird auf ein array_merge hinauslaufen, was ich noch implemtieren muss...

              Schluss für heute ;)

              1. Tach!

                Mir gehts jedoch darum, für _eine_ Abfrage nicht ein großes Array in den Hauptspeicher zu legen.

                Für eine Abfrage braucht es gar kein Array, aber das hab ich ja schon gesagt.

                Ein sich selbst füllendes Array für die Anfrage nach nur einem Ergebnis ist nicht gerade ein intentionsgemäßer Gebrauch.
                Sorry, Missverständnis: Das Array wird nicht 'gefüllt'. Es ist schon voll ;)

                Es tut so, indem es im Hintergrund die Daten holt.

                Das Array wird 'gebunden', d.h., es ist 'leer'. Ein Code
                $class = $CFG['/index.html']['class'];
                wird dieses Array NICHT befüllen, sondern nur den Wert zurückliefern.

                Also, wenn es sich nicht im Hintergrund die Values merkt, um bei der nächsten Abfrage nach demselben Key nicht wieder erneut die Daten holen zu müssen, dann entfernt es sich noch ein weiteres Stück von meinem Verständnis von sinnvoller Verwendung.

                Du meinst, viele Einzelabfragen (versteckt in einem Array-Zugriff) sind besser als eine einzige Abfrage nach allen benötigten Werten? Hast du das mal gegeneinander gemessen?
                Nein. Es gilt, die Balance zwischen Performance und Hauptspeicher zu halten, das ist immer eine Gratwanderung. Freilich gibts fürs Routing nur die eine Abfrage auf die Klasse, logisch, ein Request => eine Klasse.

                Du solltest ja auch nicht die gesamte Datenbank in den Speicher lesen, sondern versuchen, mit so wenig wie möglich Requests die benötigten Daten und nicht unmäßig mehr zu besorgen.

                Wenn du _eine_ Ergebnismenge erzeugst, kann die mysql(/i/nd)-Extension diese in einem Rutsch in den Speicher holen (das macht sie per Default). Fetchen findet dann von dort statt, ist also nur noch ein Speicherzugriff. Wenn du hingegen ein Prepared Statement mehrfach ausführst, muss dazu jedes Mal ein Roundtrip zum DBMS ausgeführt werden.

                dedlfix.

                1. hi,

                  Wenn du _eine_ Ergebnismenge erzeugst, kann die mysql(/i/nd)-Extension diese in einem Rutsch in den Speicher holen (das macht sie per Default). Fetchen findet dann von dort statt, ist also nur noch ein Speicherzugriff. Wenn du hingegen ein Prepared Statement mehrfach ausführst, muss dazu jedes Mal ein Roundtrip zum DBMS ausgeführt werden.

                  Damit habe ich nichts gewonnen, das habe ich jetzt schon.

                  Kleine Ergänzung, zur Limit-Klause: Hier sind, wie angemerkt, keine prepared Statements möglich, da muss die Abfrage jedesmal neu gebildet werden. Das können wir getrost vergessen, der Performanceverlust ist spürbar.

                  Mit einem extra Feld jedoch für den Index (lfdnr) ist ein prepared Statement möglich, das wird im Konstruktor erstellt. Hier gibt es keinen Performanceeinbruch, das funktioniert mit Perl und mit PHP einwandfrei (die Iteration über die Tabelle).

                  Horst H.

                  1. Tach!

                    Kleine Ergänzung, zur Limit-Klause: Hier sind, wie angemerkt, keine prepared Statements möglich, da muss die Abfrage jedesmal neu gebildet werden.

                    Das stimmt so nicht, wie bereits gesagt. Könntest du diese Aussage auf ein bestimmtes Szenario inklusive Nennung aller Versionsnummern einschränken?

                    dedlfix.

                    1. hi,

                      Kleine Ergänzung, zur Limit-Klause: Hier sind, wie angemerkt, keine prepared Statements möglich, da muss die Abfrage jedesmal neu gebildet werden.

                      Das stimmt so nicht, wie bereits gesagt. Könntest du diese Aussage auf ein bestimmtes Szenario inklusive Nennung aller Versionsnummern einschränken?

                      Wozu?
                      Meine Aussage, dass die Iteration über ein an die DB gebundenes Array nur mit einem prepared Statement flüssig läuft, sollte Dir doch reichen.

                      Ansonsten: Machs einfach mal ;)

                      Hotti (habe meine Klasse fertig, läuft prima)

                      --
                      Die Praxis ist der Prüfstein der Wahrheit (Karl Marx).
                      1. hi again,

                        Kleine Ergänzung, zur Limit-Klause: Hier sind, wie angemerkt, keine prepared Statements möglich, da muss die Abfrage jedesmal neu gebildet werden.

                        Das stimmt so nicht, wie bereits gesagt. Könntest du diese Aussage auf ein bestimmtes Szenario inklusive Nennung aller Versionsnummern einschränken?

                        Wozu?
                        Meine Aussage, dass die Iteration über ein an die DB gebundenes Array nur mit einem prepared Statement flüssig läuft, sollte Dir doch reichen.

                        PS als hinkender Vergleich: Wie sich ein Auto mit angezogener Handbremse fährt, ist für mich völlig indiskutabel.

                        Gute Fahrt ;-)
                        Horst H.

                2. hi again,

                  Also, wenn es sich nicht im Hintergrund die Values merkt, um bei der nächsten Abfrage nach demselben Key nicht wieder erneut die Daten holen zu müssen, dann entfernt es sich noch ein weiteres Stück von meinem Verständnis von sinnvoller Verwendung.

                  Es gibt leider nichts zu merken bzw. zu cachen. Beim Iterieren über das an die DB gebundene Array ist jede Abfrage auf ein Array-Element einmalig. Erst beim nächsten Request wiederholt sich das.

                  Wie auch immer, ich habe meine Untaten heute und hier aufgeschrieben und dafür noch Einiges optimieren können, so gibt es wenigstens für den Iterator einen Cache.

                  Auf dem Server ist das life: Klickst Du Hauptindex geht das Gewitter auf die Datenbank los ;)

                  Mir kommt jedoch schon wieder die nächste Idee... das komplette Array vielleicht doch in den Hauptspeicher zu holen, aber nicht immer, sondern nur, wenn die Klasse Map zuschlägt...

                  Schönes Wochenende,
                  Horst H.