Kurt: $_POST Array in db eintragen

Hi,

beim Eintrag in eine db ergibt

[code lang=php]
if (!empty($_POST)) {
$entry_post =  print_r($_POST,true);
}
mitunter einen Fehler, je nach Inhalt.

Kann bzw. muss ich $entry_post noch kontextspezifisch behandeln, damit die DB es immer annimmt?

Gruß, Kurt

  1. [code lang=php]
    if (!empty($_POST)) {
    $entry_post =  print_r($_POST,true);
    }

    $entry_post =  mysql_real_escape_string(print_r($_POST,true));

    erzeugt keinen Abbruch, aber bläht den Eintrag natürlich entsprechend unschön auf. Ist das trotzdem so gedacht und richtig?

    Kurt

  2. Hi,

    beim Eintrag in eine db ergibt

    [code lang=php]
    if (!empty($_POST)) {
    $entry_post =  print_r($_POST,true);
    }
    mitunter einen Fehler, je nach Inhalt.

    Bist du sicher, dass du print_r nutzen willst und nicht z.B. serialize? Dann könntest du es nämlich auch ohne großen Aufwand unserialize()n.

    Nichtsdestotrotz gehört bei beiden Varianten die Beachtung des Kontextwechsels dazu, hier z.B. mit mysql_real_escape_string, wieschon richtig bemerkt wurde.

    Bis die Tage,
    Matti

    1. Bist du sicher, dass du print_r nutzen willst und nicht z.B. serialize?

      Hatte darüber nachgedacht, aber ein Kommentar hielt mich vorerst davon ab:

      Anonymous 28-Feb-2012 08:44
      Please! please! please! DO NOT serialize data and place it into your database. Serialize can be used that way, but that's missing the point of a relational database and the datatypes inherent in your database engine. Doing this makes data in your database non-portable, difficult to read, and can complicate queries.

      Kurt

      1. Hi,

        Bist du sicher, dass du print_r nutzen willst und nicht z.B. serialize?

        Hatte darüber nachgedacht, aber ein Kommentar hielt mich vorerst davon ab:

        Anonymous 28-Feb-2012 08:44
        Please! please! please! DO NOT serialize data and place it into your database. Serialize can be used that way, but that's missing the point of a relational database and the datatypes inherent in your database engine. Doing this makes data in your database non-portable, difficult to read, and can complicate queries.

        Der Kommentar ist vollkommen korrekt, wenn die Alternative ist, die Daten sorgfältig in das vorbereitete Datenbank-Schema einzupflegen. Wenn du aber das print_r-Geraffel reinschreibst, ist es nur ein String ohne jegliche Semantik. Dann trifft der Kommentar genauso zu, zusätzlich ist das parsen des print_r-Ergebnisses deutlich umständlicher im Vergleich zu serialize.

        Bis die Tage,
        Matti

        1. Hi,

          Bist du sicher, dass du print_r nutzen willst und nicht z.B. serialize?

          Hi, was ist der Vorteil von serialisieren?

          Bernd

          1. Hi,

            Bist du sicher, dass du print_r nutzen willst und nicht z.B. serialize?
            was ist der Vorteil von serialisieren?

            Serialisieren (in diesem Kontext) ist der Vorgang, eine beliebige Datenstruktur in eine Zeichenabfolge zu bringen, welche z.B. als String speicherbar ist. Dazu gehört meist eine Deserialisierungsfunktion, welche diese Zeichenfolge wieder in deine Ursprungsdatenstruktur zurückparst.

            Der Vorteil von serialize im Vergleich zu print_r(*, true) ist, dass du serialize einfach mit unserialize wieder zurückparsen kannst (wenn du die Daten mit PHP weiterverarbeiten willst), während du für print_r einen Parser schreiben müsstest.

            Bis die Tage,
            Matti

            1. Der Vorteil von serialize im Vergleich zu print_r(*, true) ist, dass du serialize einfach mit unserialize wieder zurückparsen kannst (wenn du die Daten mit PHP weiterverarbeiten willst), während du für print_r einen Parser schreiben müsstest.

              Hallo,

              und wenn ich die Daten nicht mehr im Ursprungsformat benötige?

              Was verbraucht in der db mehr Speicher oder belastet die db mehr?

              Grüße, Bernd

              1. Hi,

                und wenn ich die Daten nicht mehr im Ursprungsformat benötige?

                dann würde ich dir trotzdem empfehlen, die Daten in einem neutralen Format zu speichern, und nicht schon auf einen konkreten Verwendungszweck aufbereitet - sonst verbaust oder erschwerst du dir eventuelle spätere Erweiterungen.

                Wenn du beispielsweise heute sagst, du möchtest die Daten sowieso nur als HTML ausgeben, und sie daher gleich mit HTML-Tags durchsetzt in der DB speicherst - naja, dann hast du später umso mehr Aufwand, wenn du anstatt eines HTML-Dokuments doch mal ein PDF generieren willst, oder eine auch Plaintext-Version zum Ausdrucken.

                Was verbraucht in der db mehr Speicher oder belastet die db mehr?

                Beides (also serialize und print_r) erzeugt Strings, "belastet" die DB also nur in dem Maß, wie du z.B. Suchoperationen innerhalb dieser Strings durchführst. Zum Speicherverbrauch vergleiche einfach die resultierende Stringlänge.
                Das sollte aber kein Entscheidungskriterium für oder gegen ein bestimmtes Datenformat sein.

                Ciao,
                 Martin

                --
                Keine Sorge, wir finden für jede Lösung ein Problem.
                Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
                1. Beides (also serialize und print_r) erzeugt Strings,

                  Genau deshalb leuchtet mir so gar nicht ein, wo beim Abspeichern von $_POST und $_GET (und darum ging es dem TO wohl) der Vorteil von serialisierten Daten sein soll?

                  Deshalb hatte ich mich hier eingemischt.

                  Aber einen Vorteil serialisierter (onehin schon) Strings sehe ich immer noch nicht.

                  Gruß, Bernd

                  1. Tach!

                    Beides (also serialize und print_r) erzeugt Strings,
                    Genau deshalb leuchtet mir so gar nicht ein, wo beim Abspeichern von $_POST und $_GET (und darum ging es dem TO wohl) der Vorteil von serialisierten Daten sein soll?

                    Da er seine Aufgabenstellung nicht genannt hat, ist es schwierig zu beurteilen, was dafür sinnvoll ist und was weniger.

                    Aber einen Vorteil serialisierter (onehin schon) Strings sehe ich immer noch nicht.

                    Es ist immer von der Aufgabenstellung abhängig. Eine verschachtelte Menüstruktur zum Beispiel, die sich selten ändert, kann man als Nested Sets oder als Elter-Kind-Beziehung in einzelnen Datensätzen speichern. Aber beim Abfragen muss man diese erst wieder in ein verschachteltes Array bringen, auf dass das Template rekursiv daraus das Menü generieren kann. Wenn du stattdessen gleich das Array in seiner fertigen Form serialisiert speicherst, sparst du dir einen mitunter recht aufwendigen Arbeitsschritt. Alternativ könnte man gleich das fertige HTML speichern, aber dann hat man es schwer bei Änderungen. Als Nachteil kann sich erweisen, dass man in der serialisierten Struktur schlecht suchen kann. Aber wenn man diese Funktionalität nicht benötigt, wäre das doch ein passabler Kompromiss zwischen Aufwand und Geschwindigkeit und den doch gelegentlich notwendigen Änderungen.

                    dedlfix.

                    1. Eine verschachtelte Menüstruktur zum Beispiel, die sich selten ändert, kann man als Nested Sets oder als Elter-Kind-Beziehung in einzelnen Datensätzen speichern. Aber beim Abfragen muss man diese erst wieder in ein verschachteltes Array bringen, auf dass das Template rekursiv daraus das Menü generieren kann. Wenn du stattdessen gleich das Array in seiner fertigen Form serialisiert speicherst, sparst du dir einen mitunter recht aufwendigen Arbeitsschritt.

                      Aber wenn er diese verschachtelte Menüstruktur doch in $_POST verpackt hat, ist es dann nicht Wurscht, ob er $_POST über print_r zu einem String macht, den er in der DB ablegt oder über serialisize?

                      Und vorrausgesetzt, er will das Menü später _nicht_ wieder herstellen, wäre er doch gar besser bedient, es nicht zu serialisieren, weil er besser in den abgelegten Daten suchen kann.

                      Ob jetzt print_r oder serialisize eine höhere Serverauslastung verursacht, weiß ich allerdings nicht.

                      Gruß, Bernd

                      1. Tach!

                        Aber wenn er diese verschachtelte Menüstruktur doch in $_POST verpackt hat, ist es dann nicht Wurscht, ob er $_POST über print_r zu einem String macht, den er in der DB ablegt oder über serialisize?

                        print_r() erzeugt eine Ausgabe zu Debug-Zwecken und es geht auch die Typ-Information verloren. Daraus lässt sich schlecht wieder das Original herstellen. Serialisieren ist ein auf Umkehrbarkeit ausgelegter Vorgang. Das Ergebnis ist zwar im Gegensatz zur print_r-Ausgabe nicht (besonders gut) menschenlesbar, geht aber mit unserialize() ebenso einfach wieder in die verarbeitbare Struktur zurückzuwandeln.

                        Und vorrausgesetzt, er will das Menü später _nicht_ wieder herstellen, wäre er doch gar besser bedient, es nicht zu serialisieren, weil er besser in den abgelegten Daten suchen kann.

                        Das Suchen in den beiden Formen geht ungefähr gleich gut, beziehungsweise schlecht. Strings bleiben lesbar, nur die Füllzeichen sind andere, und die stören mitunter beim Finden. Egal was für eine Datenstruktur er in seinem $_POST stehen hat, print_r ist vom Prinzip her eine Einbahnstraße und deshalb vermutlich nicht die beste Lösung für seine wie auch immer geartete Aufgabenstellung.

                        Ob jetzt print_r oder serialisize eine höhere Serverauslastung verursacht, weiß ich allerdings nicht.

                        Das ist unerheblich. Die Unterschiede machen das Kraut nicht fett.

                        Vielleicht zum besseren Verständnis ein Beispiel:

                        $x = array(  
                          'foo' => 'bar[]',  
                          'bla' => false,  
                          'qux' => true,  
                          'numbers' => array(23, 42));
                        

                        print_r() erzeugt diese Ausgabe:

                        Array
                        (
                            [foo] => bar[]
                            [bla] =>
                            [qux] => 1
                            [numbers] => Array
                                (
                                    [0] => 23
                                    [1] => 42
                                )
                        )

                        und serialisiert sieht das so aus:

                        a:4:{s:3:"foo";s:5:"bar[]";s:3:"bla";b:0;s:3:"qux";b:1;s:7:"numbers";a:2:{i:0;i:23;i:1;i:42;}}

                        Es ist bei print_r() zu sehen, dass die eckigen Klammern bei bar[] sich nicht wirklich von denen der Keys unterscheiden. Aber das bekommt man mit einem Parser geregelt. Interessanter ist, dass false und true abhandengekommen sind. In der serialisierten Form sind sie erkennbar: b:0 und b:1

                        dedlfix.

                        1. Es ist bei print_r() zu sehen, dass die eckigen Klammern bei bar[] sich nicht wirklich von denen der Keys unterscheiden. Aber das bekommt man mit einem Parser geregelt. Interessanter ist, dass false und true abhandengekommen sind. In der serialisierten Form sind sie erkennbar: b:0 und b:1

                          Hi dedlfix,

                          faszinierend, Deine Antwort. Danke für die Mühe, die Du Dir gemacht hast.

                          Es gehen also wirklich Informationen verloren??

                            
                          $x = array(  
                            'foo' => 'bar[]',  
                            'bla' => false,  
                            'qux' => true,  
                            'numbers' => array(23, 42));  
                            
                          $x2 = array(  
                            'foo' => 'bar[]',  
                            'bla' => '',  
                            'qux' => true,  
                            'numbers' => array(23, 42));  
                            
                            
                          $abc1 = print_r($x,true);  
                          $abc2 = print_r($x2,true);  
                            
                          if ($abc1 == $abc2) {  
                          echo "identisch";  
                          } else {  
                          echo "nicht identisch";  
                          }  
                            
                          // ergibt identisch!  
                          
                          

                          Sowas???!!!
                          Ich bin verblüfft.

                          Bernd

                      2. Hi,

                        Und vorrausgesetzt, er will das Menü später _nicht_ wieder herstellen, wäre er doch gar besser bedient, es nicht zu serialisieren, weil er besser in den abgelegten Daten suchen kann.

                        Wie ich zu Beginn schrieb, ist die Verwendung abhängig davon, wie er die Daten weiterverarbeiten will. Will er sie mit PHP weiter nutzen, dann ist serialize besser geeignet, da serialize eine Umkehrfunktion hat und print_r nicht.

                        Was das Suchen angeht, ist die Frage, wie er suchen will. Mit MySQL liegen die Daten in beiden Varianten als String vor, sind also gleich gut durchsuchbar.
                        Einige Suchanfragen ("gib mit das Menuitem innerhalb des Menus "Main", welches den Namen "Bla" trägt und den Schlüssel 5 hat") kann man nur beantworten, wenn man die Datenstuktur in ihrer Struktur versteht, da reicht eine Textsuche nicht mehr. Und dann ist serialize klar überlegen.

                        Und nochmals: ich habe genau einen (!) Fall gehabt, wo ich mal mit serialize in der Datenbank etwas abgelegt habe. Da habe ich aber auch eine bewusste Abkürzung genommen, um bestehenden Code möglichst wenig anpassen zu müssen (ich wollte einen bestehenden Job "queuen", d.h. zeitversetzt abarbeiten. Die Jobdaten habe ich in ihrem "Jobobjekt", in diesem Fall ein Mail-Objekt, als serialisierten String in der DB gespeichert und die Queue-Tabelle per cronjob abgearbeitet). Ansonsten empfiehlt es sich eigentlich immer, die Datenstruktur ordentlich in ein Schema einzupassen.

                        Etwas anderes wäre es, wenn man die Datenstuktur für einen Transport serialisieren muss. Hier ist serialize auch print_r überlegen (wenn man nur PHP-clients auf der Gegenseite hat), trotzdem würde ich sprachneutral eher zu JSON oder gar XML tendieren (weil es mir die Möglichkeit offenhält, auf der Gegenseite einen Client in nicht-PHP zu schreiben; der Output von serialize ist zwar auch in anderen Sprachen parsebar, aber ich kenne keine fertige Library, wie sie z.B. JSON für diverse Sprachen anbietet).

                        Ob jetzt print_r oder serialisize eine höhere Serverauslastung verursacht, weiß ich allerdings nicht.

                        Ich denke, der Unterschied ist vernachlässigbar. Darauf eine Entscheidung aufzubauen wäre premature optimization.

                        Bis die Tage,
                        Matti