Ankündigung

Einklappen
Keine Ankündigung bisher.

[OOP] Grid Class Design / Recursive Objects

Einklappen

Neue Werbung 2019

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

  • [OOP] Grid Class Design / Recursive Objects

    Hi,

    Aufgabenstellung:
    Ich habe ein Grid-Objekt, welches die Zeilen, Spalten und Zellen beinhalten soll.

    Da der GC seit 5.3 auch mit rekursiven Objekten fertig, habe ich mir gedacht, dass wie folgt aufzubauen (nur schematisch):

    PHP-Code:
    class Grid {
       var 
    $rows// array von GridRows
       
    var $columns// array von GridColumns
    }
    class 
    GridColumn {
       var 
    $index// unique index, wird zur identifizierung genutzt
       
    var $grid// referenz zum grid
    }
    class 
    GridRow {
       var 
    $grid// referenz zum grid
       
    var $cells// array von GridCells
    }
    class 
    GridCell {
       var 
    $row// referenz zur reihe

    Oder in Worten: Das Grid beinhaltet Spalten und Zeilen, Zeilen enthalten Zellen und alles verweist auf seine Eltern.

    Gibt es irgendwelche Bedenken bei solch einer Stuktur, die ich nicht sehe, oder hat jemand vielleicht sogar einen besseren Lösungsansatz ?

    PS: Die Frage ob ein Grid in PHP Sinn macht ist unrelevant

    Gruß Nils

  • #2
    Zitat von BreezeKeeper Beitrag anzeigen
    einen besseren Lösungsansatz ?
    Dazu müsste man wissen, was du mit dem Konstrukt eigentlich vor hast. Technisch spricht nichts dagegen.
    [IMG]https://g.twimg.com/twitter-bird-16x16.png[/IMG][URL="https://twitter.com/fschmengler"]@fschmengler[/URL] - [IMG]https://i.stack.imgur.com/qh235.png[/IMG][URL="https://stackoverflow.com/users/664108/fschmengler"]@fschmengler[/URL] - [IMG]http://i.imgur.com/ZEqflLv.png[/IMG] [URL="https://github.com/schmengler/"]@schmengler[/URL]
    [URL="http://www.schmengler-se.de/"]PHP Blog[/URL] - [URL="http://www.schmengler-se.de/magento-entwicklung/"]Magento Entwicklung[/URL] - [URL="http://www.css3d.net/"]CSS Ribbon Generator[/URL]

    Kommentar


    • #3
      Ne Grid-Klasse Es geht darum Daten, welche für die Ausgabe gedacht sind so zu strukturieren, dass auch später eine Änderung über Hooks möglich ist. Nehmen wir das einfachste Beispiel: Ich habe ne Webapp, die Daten in einer Tabelle anzeigt. Nun soll diese Tabelle die Möglichkeit haben von Dritten angepasst zu werden z.B. eine weitere Spalte hinzufügen. Natürlich kann man Markup auch mit JS anpassen, aber das Ganze soll Serverseitig geschehen (hat verschiedene Gründe).

      Kommentar


      • #4
        Grids sind in PHP garnicht so weltfremd, jedes 2-Dimensionale Array ist theoretisch eins. Ich würde allerdings nicht hingehen und für jede Grid-Zelle eine Instanz, sowie für jede Zeile eine Instanz die mehrere Zellen-Instanzen hält erzeugen, das ist Resourcenverschwendung in meinen Augen. In Theorie reicht eine im speicher existente Grid-Instanz, die die Daten festhält und maximal 2 weitere gleichzeitig präsente Instanzen je Zelle / Zeile auf die gerade zugegriffen wird.

        Wenn du einen Ansatz brauchst kannst du dir ja mal den Anhang dieses Posts ansehen, dort hab ich dir ein beispiel zusammengebastelt ( PHP 5.3+ ).

        Usage Grid:
        PHP-Code:
        /**
         *  pull autoloader
         **/
        require 'autoload.php';

        /**
         *  import Grid Class from Grid namespace
         **/
        class_alias("Grid\Grid""Grid");

        /**
         *  create grid instance and set 5x5 as size
         **/
        $grid = new Grid;

        $grid->addRows(5);
        $grid->addColumns(5);

        /**
         *  set some data
         **/
        $grid->setData(0,3'a test');
        $grid->setData(2,4'another test');

        /**
         *  add 5 columns after column index 2
         **/
        $grid->addColumns(5/* after column */ 2); 
        Usage aggregatorGrid:
        PHP-Code:
        /**
         *  pull autoloader
         **/
        require 'autoload.php';

        /**
         *  import aggegratorGrid class from Grid namespace
         **/
        class_alias("Grid\aggregatorGrid""aggregatorGrid");

        /**
         *  create grid instance and set 5x5 as size
         **/
        $aggregatedGrid = new aggregatorGrid;
        $aggregatedGrid->addRows(5);
        $aggregatedGrid->addColumns(5);

        /**
         *  execute fill callback on each column ( all ! )
         **/
        $aggregatedGrid->eachColumn(function($col) {
            
        /**
             *  set content to 'Hello World'
             **/
            
        $col->content 'Hello World';

            
        /**
             *  return the object
             **/
            
        return $col;
        });

        /**
         *  add 2 columns after column index 0
         **/
        $aggregatedGrid->addColumns(2/* after column */ 0);

        /**
         *  execute another fill callback on each column
         **/
        $aggregatedGrid->eachColumn(function($col) {
            
        /**
             *  leave if the content has been allready set before
             **/
            
        if ( $col->content ) {
                return;
            }

            
        /**
             *  set 'new content' as content
             **/
            
        $col->content 'new content';

            
        /**
             *  return the object
             **/
            
        return $col;
        });

        # more complex ...

        /**
         *  execute an fill callback on each row
         **/
        $aggregatedGrid->eachRow(function( $rows ) {
            
        /**
             *  execute an fill callback on each column of this row using
             *  the current (countable) row object
             **/
            
        return $rows->eachColumn(function( $col ) use ( $rows ) {
                
        /**
                 *  set content with some mathematical values
                 **/
                
        $col->content 'i have '.(count($rows) - 1).' columns as neighbours';

                
        /**
                 *  set other properties
                 **/
                
        $col->test 'Hello World';

                
        /**
                 *  detect something and append it to the content
                 **/
                
        if ( count($rows) - == $col->columnPosition ) {
                    
        $col->content .= ' and i am the last child';
                }

                if ( 
        $col->columnPosition === ) {
                    
        $col->content .= ' and i am the first child';
                }

                
        /**
                 *  return the object
                 **/
                
        return $col;
            });
        }); 
        Finally: ma guggn was passiert ist:
        PHP-Code:
        var_dump($grid->getGridData(), $aggregatedGrid->getGridData()); 
        Results:
        Code:
        array(5) {
          [0]=>
          array(10) {
            [0]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [1]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [2]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [3]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [4]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [5]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [6]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [7]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [8]=>
            array(1) {
              ["content"]=>
              string(6) "a test"
            }
            [9]=>
            array(1) {
              ["content"]=>
              NULL
            }
          }
          [1]=>
          array(10) {
            [0]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [1]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [2]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [3]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [4]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [5]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [6]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [7]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [8]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [9]=>
            array(1) {
              ["content"]=>
              NULL
            }
          }
          [2]=>
          array(10) {
            [0]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [1]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [2]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [3]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [4]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [5]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [6]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [7]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [8]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [9]=>
            array(1) {
              ["content"]=>
              string(12) "another test"
            }
          }
          [3]=>
          array(10) {
            [0]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [1]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [2]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [3]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [4]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [5]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [6]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [7]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [8]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [9]=>
            array(1) {
              ["content"]=>
              NULL
            }
          }
          [4]=>
          array(10) {
            [0]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [1]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [2]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [3]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [4]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [5]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [6]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [7]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [8]=>
            array(1) {
              ["content"]=>
              NULL
            }
            [9]=>
            array(1) {
              ["content"]=>
              NULL
            }
          }
        }
        und
        Code:
        array(5) {
          [0]=>
          array(7) {
            [0]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(55) "i have 6 columns as neighbours and i am the first child"
              ["test"]=>
              string(11) "Hello World"
            }
            [1]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [2]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [3]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [4]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [5]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [6]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(54) "i have 6 columns as neighbours and i am the last child"
              ["test"]=>
              string(11) "Hello World"
            }
          }
          [1]=>
          array(7) {
            [0]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(55) "i have 6 columns as neighbours and i am the first child"
              ["test"]=>
              string(11) "Hello World"
            }
            [1]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [2]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [3]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [4]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [5]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [6]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(54) "i have 6 columns as neighbours and i am the last child"
              ["test"]=>
              string(11) "Hello World"
            }
          }
          [2]=>
          array(7) {
            [0]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(55) "i have 6 columns as neighbours and i am the first child"
              ["test"]=>
              string(11) "Hello World"
            }
            [1]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [2]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [3]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [4]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [5]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [6]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(54) "i have 6 columns as neighbours and i am the last child"
              ["test"]=>
              string(11) "Hello World"
            }
          }
          [3]=>
          array(7) {
            [0]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(55) "i have 6 columns as neighbours and i am the first child"
              ["test"]=>
              string(11) "Hello World"
            }
            [1]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [2]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [3]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [4]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [5]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [6]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(54) "i have 6 columns as neighbours and i am the last child"
              ["test"]=>
              string(11) "Hello World"
            }
          }
          [4]=>
          array(7) {
            [0]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(55) "i have 6 columns as neighbours and i am the first child"
              ["test"]=>
              string(11) "Hello World"
            }
            [1]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [2]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [3]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [4]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [5]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(30) "i have 6 columns as neighbours"
              ["test"]=>
              string(11) "Hello World"
            }
            [6]=>
            array(3) {
              ["columnData"]=>
              NULL
              ["content"]=>
              string(54) "i have 6 columns as neighbours and i am the last child"
              ["test"]=>
              string(11) "Hello World"
            }
          }
        }
        P.S.: der gezippte Anhang enthält sublime2 projekt und php-source nebst einer "read it - not use it"-trap die du wenn du den source verstanden hast simpel entfernen kannst.
        Angehängte Dateien
        [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
          wieso nimmt man da keine mysql-Tabelle ?
          Dort hast doch alles was Du brauchst: Spalten, Reihen, Zellen.

          Einfügen, Bearbeiten, Ändern, Löschen von Reihen, Spalten ...

          Müßte sich doch in ein Objekt übersetzen lassen.
          Eine if-else-Abfrage nimmt, ordentlich geschrieben eine Menge Platz weg. Platzsparend geht es mit einem ternären Operator.

          Kommentar


          • #6
            Das geht dann schon in Richtung ORM, ein Grid ist etwas simpler... Excel wäre da eher vergleichbar. Der Hauptunterschied liegt in meinen Augen darin, das bei einem Grid die Addressierung frei wählbar ist, eine Matrix in die man an beliebigen Positionen etwas einfügen kann und das die Datentypen in den Zellen nicht konsistent sein müssen über Spalten.
            Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

            Kommentar


            • #7
              Das Grid ist ein Steuerelement (Component, Control, ... ) für den View. Wie soll man denn ein View-Element durch ne MySQL-Tabelle ersetzen können?!

              Ob man jetzt für jede Zelle eine Instanz braucht, hängt davon ab was man damit tun will. Falls es verschiedene Zelltypen gibt oder individuelle Formatierungen dann ja. Bei dem Grid in unserem Framework beschränke ich mich darauf die Spalten festzulegen (Welcher Wert wird in dieser Spalte wie angezeigt). Die Zeilen ergeben sich aus der Item-Collection, die man zuweist. Jeder Spalte, lässt sich auf Wunsch dann auch nochmal ein Template zuweisen, das auch PHP enthalten kann, so dass so zu einer bedingten Formatierung auf Basis der Werte kommen kann.

              Wenn man noch Inline-Editing integrieren möchte, hat man auch wieder die Möglichkeit das über Zellen-Objekte zu machen (dann ist es egal, wo der Inhalt herkommt) oder bei uns greifen wir auf die Feldeigenschaften des angezeigten Felds aus dem ORM-Mapping zurück.

              Ich würde die Spalten konfigurieren, sowie die Zeilen aus der Item-Collection generieren. Beiden würde ich keine Referenzen auf die Zellen geben. Die würde ich als mxn Matrix speichern.

              Kommentar


              • #8
                Naja trotzdem gehst du nicht hin und baust bei einem 100x100-Grid 10000 Cell-Objekte in deine Collection, wenn jemand "alle" Zellen mit dem gleichen Wert beschreiben will. Da reicht eine Cell-Instanz vollkommen.
                [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
                  var $rows;
                  Aber php 5.3...?

                  Kommentar


                  • #10
                    Vielleicht mal angucken: https://de.wikipedia.org/wiki/Fliege...wurfsmuster%29
                    [COLOR="#F5F5FF"]--[/COLOR]
                    [COLOR="Gray"][SIZE="6"][FONT="Georgia"][B]^^ O.O[/B][/FONT] [/SIZE]
                    „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                    [URL="http://www.php.de/javascript-ajax-und-mehr/107400-draggable-sorttable-setattribute.html#post788799"][B]Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“[/B][/URL][/COLOR]
                    [COLOR="#F5F5FF"]
                    --[/COLOR]

                    Kommentar

                    Lädt...
                    X