Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] PDO Wrapper?

Einklappen

Neue Werbung 2019

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

  • [Erledigt] PDO Wrapper?

    Eine kleine Frage. Ich zerbreche mir gerade den Kopf über den (Un)Sinn meines Vorhabens. Und zwar. Ich habe eine PDO Klasse geschrieben:
    PHP-Code:
    <?php
        
    class db
        
    {
            protected 
    $con;
            public function 
    __construct($username$password$host$dbname){
                try {
                    
    $this->con = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8"$username$password);
                }
                catch(
    PDOException $e) {
                    throw new 
    Exception($e->getMessage());
                }
            }
            public function 
    Disconnect(){
                
    $this->con null;
            }
        }
    Somit kann ich bequemer Objekte erzeugen, anstatt blabla = new PDO(...) angeben zu müssen. Ist das in euren Augen vertretbarer Overhead, oder sollte ich doch jedes Mal = new PDO() schreiben.

    2. Zum Einsatz kommt das folgendermaßen:
    PHP-Code:
    <?php
    include('db.php');
    class 
    dbf{

        public static function 
    buildDB1(){
                return new 
    db(/* Settings db1*/);
        }

        public static function 
    buildDB2{
               return new 
    db(/*Settings db2*/);
        }

    }
    Ist das sinnvoll, oder kann man die Datenbank auch fest in den jeweilige Klasse übergeben. Bin noch totaler Noob und dachte, so kann man die sinnvoll verwalten. Bin aber gerne für alles offen. Somit nutze ich nur die methoden in dbf, um auf die datenbanken zuzugreifen. Sinnvoll oder schlecht?


  • #2
    ad 1.) Also alles was du dir da sparst ist eigentlich das charset anzugeben, richtig? Dafür machst du dich unflexibler, falls du tatsächlich doch mal etwas anderes als UTF-8 verwenden willst. Oder was anderes als MySQL.

    ad 2.) Mir ist nicht klar was du mit den 2 Datenbanken willst. Wozu brauchst du die zwei Verbindungen?

    Kommentar


    • #3
      @Tropi
      ad 1: Charset stimmt. Und ich kann disconnecten und exceptions. Dachte es wäre sinnvoll ne eigene Klasse zu machen, um besser zu abstrahieren, somit könnte man auch um getter setter für port,... ergänzen.
      ad 2.) Das war eher dazu gedacht, falls man in Zukunft mit 2 oder mehr Datenbanken arbeitet, diese dann in die Klasse einträgt und von verschiedenen Dateien auf die gewünschte Datenbank zugreifen kann.
      Wie löst man das sonst am geschicktesten.
      Danke für die Antwort!

      Kommentar


      • #4
        Hallöchen,

        Zitat von hartCoder Beitrag anzeigen
        Somit kann ich bequemer Objekte erzeugen, anstatt blabla = new PDO(...) angeben zu müssen. Ist das in euren Augen vertretbarer Overhead, oder sollte ich doch jedes Mal = new PDO() schreiben.
        Da man im Idealfall nur *eine* PDO-Instanz pro Request (und Datenbank) erzeugt, ist dein Wrapper nutzlos.

        Zitat von hartCoder Beitrag anzeigen
        Ist das sinnvoll, oder kann man die Datenbank auch fest in den jeweilige Klasse übergeben. Bin noch totaler Noob und dachte, so kann man die sinnvoll verwalten. Bin aber gerne für alles offen. Somit nutze ich nur die methoden in dbf, um auf die datenbanken zuzugreifen. Sinnvoll oder schlecht?
        Den Datenbankzugriff hinter einer Klasse zu verstecken bringt deiner Anwendung noch keinen wirklichen Mehrwert. Du solltest versuchen den Zugriff auf dein Domain-Model zu abstrahieren und Werkzeuge wie PDO erst in konkreten Implementierungen einsetzen.

        Viele Grüße,
        lotti

        Kommentar


        • #5
          Ok, also meinst du sollte ich via folgt arbeiten:
          PHP-Code:
          class Gaestebuch{
            public 
          $database  '';

            public 
          __construct(){
             
          $this->database = new PDO(/*hier dann Einstellungen*/);

          Habe ich das richtig verstanden so. Weil das mein Vorgehen iwie nix bringt war mir auch klar. Und was meinst du mit Domain-Model? Solche Begriffe kenn ich noch nicht. Meine Idee war, dass ich den Konstruktor vereinfache, anstatt jedes Mal charset unc co. mitgeben zu müssen. Aber ist das zu vermeiden?

          Kommentar


          • #6
            Zitat von hartCoder Beitrag anzeigen
            @Tropi
            ad 1: Charset stimmt. Und ich kann disconnecten und exceptions. Dachte es wäre sinnvoll ne eigene Klasse zu machen, um besser zu abstrahieren, somit könnte man auch um getter setter für port,... ergänzen.
            ad 2.) Das war eher dazu gedacht, falls man in Zukunft mit 2 oder mehr Datenbanken arbeitet, diese dann in die Klasse einträgt und von verschiedenen Dateien auf die gewünschte Datenbank zugreifen kann.
            Wie löst man das sonst am geschicktesten.
            Danke für die Antwort!
            1. Exceptions wirft PDO ja ohnehin, und zentral fangen kannst du sie mit: http://php.net/manual/en/function.se...on-handler.php
            2. Aber ich kann doch, falls ich das tatsächlich mal brauche, einfach ein neues PDO-Objekt mit einer anderen Konfiguration verwenden. Warum eine extra Klasse/Methode dafür?

            Kommentar


            • #7
              Ja du hast Recht. Vllt bin ich auch übers Ziel hinaus geschossen, aber ich hab mal was von Dont repeat yourself gelesen und dachte, eine Methode schreiben zu müssen, damit ich nicht jedes Mal die Konfiguration neu angeben muss.

              Kommentar


              • #8
                Hallöchen,

                fast.

                Deine PDO-Instanz sollte Teil der Konfiguration sein und nicht fest in deiner Klasse verankert werden:
                PHP-Code:
                // Konfiguration
                $app['pdo'] = new PDO(..);
                $app['pdo.2'] = new PDO(..);

                // Gästebuch-Klasse
                class Guestbook{
                    protected 
                $pdo null;
                    public function 
                __construct(PDO $pdo){
                        
                $this->pdo $pdo;
                    }
                }

                // Verwendung
                $guestbook = new Guestbook($app['pdo']);
                $secondGuestbook = new Guestbook($app['pdo.2']); 
                Noch einen Schritt flexibler wird das Ganze, wenn du den Funktionsumfang der Guestbook-Klasse in einem Interface definierst und dieses im Rest deiner Anwendung verwendest (*). Die konkrete Implementierung ist dann nur ein Konfigurations-Detail, welches für den Rest deiner Anwendung uninteressant ist.

                PHP-Code:
                // Schnittstelle
                interface IGuestbook{
                    function 
                addComment(..);
                }

                // Konkrete Implementierung
                class PDOGuestbook implements IGuestbook{
                    protected 
                $pdo null;
                    public function 
                __construct(PDO $pdo){
                        
                $this->pdo $pdo;
                    }
                    public function 
                addComment(..){
                        
                // ..
                    
                }
                }

                // Klasse, welche eine IGuestbook-Instanz braucht (*)
                class GuestbookController{
                    protected 
                $guestbook null;
                    public function 
                __construct(IGuestbook $guestbook){
                        
                $this->guestbook $guestbook;
                    }
                }

                // Konfiguration
                $app['pdo'] = new PDO(..);
                $app['IGuestbook'] = new Guestbook($app['pdo']);

                // Verwendung
                $guestbookController = new GuestbookController($app['IGuestbook']); 
                Das sollte für einen groben Anreiz ausreichen. Ein wichtiges Stichwort in diesem Zusammenhang ist Dependency Injection.

                Viele Grüße,
                lotti

                Kommentar


                • #9
                  Zwei Verbindungen zur Datenbank sind bei MasterSlave Konfigurationen notwendig. Da steckt aber noch ne Menge hinter (Slave=read only; Master read/write etc).

                  Etwas anderes als UTF8 muss man erst einmal begründen können.

                  Prepared Statements sind eine tolle Sache. Ich kann sie nicht gebrauchen.

                  Ich schreibe um fast alles, was PHP so anbietet einen Wrapper, um den Zugriff auf eben diese aus meiner Domänenumgebung heraus so ungeschwätzig wie möglich zu gestalten.
                  Standards - Best Practices - AwesomePHP - Guideline für WebApps

                  Kommentar


                  • #10
                    Eine Factory oder ein Adapter ( kein Wrapper ) für PDO wäre zumindest Sinnvoll um PDO in den Exception-Modus zu schalten und UTF-8 Interaktion anzumelden und die Instanz zu Konfigurieren.

                    Master/Slave Interaktionen können ( je nach dem wie sie Aufgebaut werden sollen ) hinter einen Proxy gekapselt werden.
                    [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


                    • #11
                      Was spricht dagegen, PDO zu erweitern?
                      PHP-Code:
                      class PDOdb extends PDO{

                          public function 
                      __construct($dsn=null$user=null$pass=null$options = array()){
                          
                                
                      parent::__construct($dsn$user$pass$options);
                           
                                
                      // : 
                      PHP-Klassen auf github

                      Kommentar


                      • #12
                        Und welche Funktionalität willst du hinzufügen ?
                        [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


                        • #13
                          @Lotti: Herzlichen Dank für deine Mühe, genau das, was ich brauchte. Meinen höchsten Respekt vor dir.
                          Jetzt hab ich zwangsläufig noch eine Zusatzfrage: Sollte ich dann die Gästebuch Klasse auch so gestalten, dass zwangsläufig alle Objekte, die sie benötigt, über den Konstruktor "reinkommen" nach deinem genannten Prinzip, weil somit sind die Klassen ja noch mehr voneinander entkoppelt. Weitere Klasse wäre z.B. dass ein Gästebuch zusätzlich ein Captchaobjekt benötigt.

                          Kommentar


                          • #14
                            Zitat von hartCoder Beitrag anzeigen
                            @Lotti: Herzlichen Dank für deine Mühe, genau das, was ich brauchte. Meinen höchsten Respekt vor dir.
                            Jetzt hab ich zwangsläufig noch eine Zusatzfrage: Sollte ich dann die Gästebuch Klasse auch so gestalten, dass zwangsläufig alle Objekte, die sie benötigt, über den Konstruktor "reinkommen" nach deinem genannten Prinzip, weil somit sind die Klassen ja noch mehr voneinander entkoppelt. Weitere Klasse wäre z.B. dass ein Gästebuch zusätzlich ein Captchaobjekt benötigt.
                            Korrekt. Alle genutzten Objekte werde von außen injiziert. Siehe dazu Dependency Injection!

                            Kommentar


                            • #15
                              Objekte/Klassen sind immer aneinander gekoppelt, die Frage ist nur wie fest. In der Regel versucht man diese lose aneinanderzukoppeln (loose coupling). Die Frage dabei ist immer nur auf welcher Ebene diese Kopplung stattfindet.
                              Soll dein Gästebuch wirklich entscheiden dürfen welches CAPTCHA es verwendet? Nein! Auf Gästebuchseite wäre es sinnvoller ein Captcha-Interface zu haben, das z.B. die Methode validateCaptcha($input) hat und dann entweder true oder false zurückgibt.

                              Der Vorteil dabei ist, du musst die Gästebuch-Klasse nicht ändern wenn du ein anderes Captcha verwenden willst, sofern das neue Captcha auch dein Captcha-Interface implementiert. Hier kurzer Beispielcode:

                              PHP-Code:
                              <?php
                              interface CaptchaInterface {
                                  public function 
                              validateCaptcha($input);
                              }

                              // ÜBerprüfungen sind hier stark vereinfacht
                              class CaptchaOne implements CaptchaInterface {
                                  public function 
                              validateCaptcha($input) {
                                      return 
                              $input === "eins";
                                  }
                              }

                              class 
                              CaptchaTwo implements CaptchaInterface {
                                  public function 
                              validateCaptcha($input) {
                                      return 
                              $input === "zwei";
                                  }
                              }

                              class 
                              GuestbookLoose {
                                  protected 
                              $captcha;
                                  
                                  public function 
                              __construct(CaptchaInterface $captcha) {
                                      
                              $this->captcha $captcha;
                                  }
                              }

                              class 
                              GuestbookTight {
                                  protected 
                              $captcha;
                                  
                                  public function 
                              __construct() {
                                      
                              $this->captcha = new CaptchaTwo;
                                  }
                              }

                              $c1 = new CaptchaOne();
                              $c2 = new CaptchaTwo();
                              $g1 = new GuestbookLoose($c2);
                              $g2 = new GuestbookTight();
                              Siehe das du bei $g1 erstens sofort siehst welches Captcha du verwendest, und das du das Captcha UNABHÄNGIG vom Gästebuch austauschen kannst. Dein Gästebuch ist also nicht an CaptchaTwo gebunden, sondern lediglich an etwas das CaptchaInterface implementiert - potentiell ist also jedes Captcha möglich.

                              Kommentar

                              Lädt...
                              X