Ankündigung

Einklappen
Keine Ankündigung bisher.

PDO - Objektübergabe

Einklappen

Neue Werbung 2019

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

  • PDO - Objektübergabe

    Ahoi,

    ich bin gerade dabei ein kleines Projekt auf PDO umzustellen (ich habe vorher eine externe Datenbankklasse verwendet, möchte diese aber gern loswerden).

    Mein erster Versuch war die Einbindung genauso wie meine Datenbankklasse davor, d.h. ich habe in jeder Klasse eine Datei mit den PDO Verbindungsdetails mit require eingebunden und anschließend die PDO Verbindung in eine Klassenvariable ($db) übergeben. In meinen Funktionen wollte ich dann über $this->db darauf zugreifen. Das schien zu funktionieren ich habs in 3 Funktionen eingebaut wieder ein bisschen rumgetestet und kam bei der Fehlermeldung an:
    "PDOException: You cannot serialize or unserialize PDO instances "

    Ich muss zugeben zu 100% verstehe ich diese Fehlermeldung nicht, ich ging davon aus, dass es mit der Speicherung als Klassenvariable zusammenhing. (Liege ich da richtig?)

    Habe das jetzt so umgebastelt, dass ich eine pdoConnect()-Funktion habe und mit dieser in jeder Funktion eine eigene (neue?) Verbindung aufbaue. (Die Funktion returned ein PDO-Objekt, am Anfang jeder Funktion die die Datenbank braucht, rufe ich einmal "pdoConnect()" auf.)
    PHP-Code:
    function pdoConnect()
    {    
               
    $db_username 'xxx';    
               
    $db_pw 'xxx';    
               
    $db_dsn 'mysql:host=localhost;dbname=woh;charset=utf8';      
               
    $db_options = array(    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
                                       
    PDO::ATTR_EMULATE_PREPARES => false,
                                       
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
               return new 
    PDO($db_dsn$db_username$db_pw$db_options);

    Ist das die "richtige" vorgehensweise?
    Wäre es nicht sinnvoller eine Verbindung zu nutzen und diese immer weiterzugeben? Wenn ja wie realisiert man das im normalfall?

    Liebe Grüße
    ChromOxid

    edit: Ist es normal, dass mir beim kopieren von PHP Code jegliche Formatierung verloren geht? Hatte es erst mit einfach nur abschicken versucht, das ergab einen einzeiligen PHP-Code, habe das gerade dann manuell einigermaßen geradegerückt.

  • #2
    Wäre es nicht sinnvoller eine Verbindung zu nutzen und diese immer weiterzugeben? Wenn ja wie realisiert man das im normalfall?
    Ja, die Verbindung erstellst du einmal (zB im zentralen bootstrap) und übergibst das DB-Conn-Objekt überall hinein, wo du diese brauchst.

    Schau mal hier: http://php-de.github.io/jumpto/pdo/#recycle-conn

    Das nennt sich auch dependency injection falls du dich da noch weiter vertiefen willst.

    Kommentar


    • #3
      Ich muss zugeben zu 100% verstehe ich diese Fehlermeldung nicht, ich ging davon aus, dass es mit der Speicherung als Klassenvariable zusammenhing. (Liege ich da richtig?)
      Klingt eher nach dem Versuch, die Klasseninstanz in der Session zu speichern.

      Kommentar


      • #4
        Ergänzung:
        #2 bezog sich auf "je Request". Also das PDO Objekt wird pro Request einmalig erzeugt und dann im Zuge dieses Requests immer wieder verwendet.

        Kommentar


        • #5
          Danke für die Antworten bisher, der erste verlinkte Beitrag stellt das in etwa so dar wie ich es mir am Anfang dachte.
          Zitat von Dormilich Beitrag anzeigen
          Klingt eher nach dem Versuch, die Klasseninstanz in der Session zu speichern.
          Da die Fehlermeldung wohl wirklich hiermit zusammenhing, lag da das Problem.

          http://php-de.github.io/jumpto/pdo/#recycle-conn
          -> Heißt das ich kann Objekte der Klasse User nicht als Session speichern? Kann man das umgehen?
          Hatte bisher exakt diesen Fall und habe ein User-Objekt in der Session gespeichert, das schien mir sehr komfortabel, da hab ich direkt alle Daten beieinander und kann einfach drauf zugreifen.

          edit: Man könnte direkt bevor man das Objekt in die Session schreibt die Variable "umbelegen" ($this->pdo = 0), oder gar mit unset($this->pdo) löschen, gibts noch einen eleganteren Weg?

          Kommentar


          • #6
            "PDOException: You cannot serialize or unserialize PDO instances "
            Die Fehlermeldung sagt nein. Ob es da noch "Tricks" gibt, weiß ich leider nicht. I.d.R. wird je Request alles von 0 weg wieder neu erzeugt.

            Kommentar


            • #7
              Alternativ zu Hausls vorschlag kannst Du Dir auch ein Singleton bauen was die PDO Klasse kapselt.

              Edit: Oder halt als Multiton (unterschied wäre der öffentliche Konstruktor). Damit kannst Du sogar direkt von PDO ableiten

              Damit entfällt dann auch die Notwendigkeit das irgendo als Parameter propagieren zu müssen.

              Gruß, Ulf

              Kommentar


              • #8
                Zitat von ChromOxid Beitrag anzeigen
                Heißt das ich kann Objekte der Klasse User nicht als Session speichern? Kann man das umgehen?
                Ja kann man umgehen. Mach ne Ableitung von der Klasse und implementiere PHP magische Methoden __sleep() und _wakeup() oder implementiere das Serializable interface.

                Aber beachten das Du keine Werte vom Typ resource serialisieren kannst. Du must dazu die zur Erstellung nötigen Parameter in __sleep speichern und mit denen dann die neue Instanz in __wakeupp wieder herstellen.

                Gruß, Ulf

                Kommentar


                • #9
                  Danke, ich habe gerade schon ein bisschen Singletons angeguckt und das sah ganz gut aus, denke damit werde ich das brauchbar hinbekommen.

                  Liebe Grüße
                  ChromOxid

                  Kommentar


                  • #10
                    Singletons werden häufig missbraucht und es gibt nur sehr wenige Einsatzbereiche, wo sie Sinn machen. Ich denken nicht, dass das bei dir der Fall ist.

                    Kommentar


                    • #11
                      Zitat von hellbringer Beitrag anzeigen
                      Singletons werden häufig missbraucht und es gibt nur sehr wenige Einsatzbereiche, wo sie Sinn machen. Ich denken nicht, dass das bei dir der Fall ist.
                      Hast Du dafür Beispiele? (Also für den Missbrauch)

                      Gruß, Ulf

                      Kommentar


                      • #12
                        Ja, zB. werden Datenbankverbindungen oft irrtümlich als Singleton ausgelegt. Dadurch verhindert man effektiv, dass es mehr als eine Datenbankverbindung geben kann, was aber ein Nachteil ist und wodurch die Anwendung unflexibel wird. Außerdem erschwert es die Testbarkeit und kann unerwünsche Nebeneffekte bringen.

                        Ein Singleton hat genau einen Zweck: Es darf (nicht kann) nur eine Instanz existieren. Und das seh ich zB. bei einer Datenbankverbindung überhaupt nicht gegeben. Es ist zwar in vielen Fällen so, dass es nur eine Datenbankverbindung pro Prozess gibt, aber das heißt noch lange nicht, dass das auch zum Gesetz wird.

                        Kommentar


                        • #13
                          Zitat von ChromOxid
                          Hatte bisher exakt diesen Fall und habe ein User-Objekt in der Session gespeichert, das schien mir sehr komfortabel, da hab ich direkt alle Daten beieinander und kann einfach drauf zugreifen.
                          Leg nur die User-ID in der Session ab und initialisiere das User-Objekt bei jedem Request neu. Damit sparst du dir einen Haufen Probleme. (Etwa die Synchronisierung, wenn ein User auf zwei Geräten eingeloggt ist und was an seinen Daten ändert.)

                          Ich bin mir auch nicht sicher, dass ein solches User-Objekt Zugriff auf die DB haben muss.

                          Kommentar


                          • #14
                            Zitat von hellbringer Beitrag anzeigen
                            Ja, zB. werden Datenbankverbindungen oft irrtümlich als Singleton ausgelegt. Dadurch verhindert man effektiv, dass es mehr als eine Datenbankverbindung geben kann, was aber ein Nachteil ist und wodurch die Anwendung unflexibel wird. Außerdem erschwert es die Testbarkeit und kann unerwünsche Nebeneffekte bringen.
                            Ja wenn man mehrere Verbindungen braucht ist das natürlich dumm das so zu machen. Aber was soll das für ein Argument bzgl. Mißbrauch sein? Das hat nix mit Mißbrauch zu tun sondern damit das sich einsatzzweck und Einsatzmöglichkeiten nicht decken. Mißbrauchen läst sich das nicht.

                            Zitat von hellbringer Beitrag anzeigen
                            Ein Singleton hat genau einen Zweck: Es darf (nicht kann) nur eine Instanz existieren.
                            Genau und damit ist der Mißbrauch für mehrere Instanzen ausgeschlossen.

                            Zitat von hellbringer Beitrag anzeigen
                            Und das seh ich zB. bei einer Datenbankverbindung überhaupt nicht gegeben. Es ist zwar in vielen Fällen so, dass es nur eine Datenbankverbindung pro Prozess gibt, aber das heißt noch lange nicht, dass das auch zum Gesetz wird.
                            Ich würde sagen das hängt vom Anwendungsfall ab, und zum Gesetz werden muss da nix. Man kann das Singleton ohnehin nur dort einsetzen wo man es auch nutzen kann. Mißbrauch diesbezüglich kann also ausgeschlöossen werden.

                            Kommentar


                            • #15
                              Zitat von Ulfikado Beitrag anzeigen
                              Ja wenn man mehrere Verbindungen braucht ist das natürlich dumm das so zu machen. Aber was soll das für ein Argument bzgl. Mißbrauch sein? Das hat nix mit Mißbrauch zu tun sondern damit das sich einsatzzweck und Einsatzmöglichkeiten nicht decken. Mißbrauchen läst sich das nicht
                              Der Missbrauch ist, dass es oft nur deswegen gemacht wird, weil man beqeuem statisch aufs Singleton zugreifen kann. Also quasi ein globaler Variablen Ersatz. Und warum sowas schlecht ist, muss ich doch hoffentlich nicht erklären?

                              Zitat von Ulfikado Beitrag anzeigen
                              Genau und damit ist der Mißbrauch für mehrere Instanzen ausgeschlossen.
                              Welcher Missbrauch?

                              Zitat von Ulfikado Beitrag anzeigen
                              Ich würde sagen das hängt vom Anwendungsfall ab, und zum Gesetz werden muss da nix.
                              Doch. Sobald du ein Singleton erstellst, erstellst du auch ein Gesetz, dass es nur eine Instanz geben darf. Wenn du das nicht willst, darfst du kein Singleton erstellen.

                              Zitat von Ulfikado Beitrag anzeigen
                              Man kann das Singleton ohnehin nur dort einsetzen wo man es auch nutzen kann. Mißbrauch diesbezüglich kann also ausgeschlöossen werden.
                              Genau das ist eben nicht der Fall. Singletons als Ersatz für globale Variablen ist zB. eindeutig ein Missbrauch. Wer objektorientiert programmiert, sollte sich von solchen Denkweisen verabschieden oder gleich bei der prozeduralen Programmierung bleiben.

                              Kommentar

                              Lädt...
                              X