Ankündigung

Einklappen
Keine Ankündigung bisher.

Session-Klasse

Einklappen

Neue Werbung 2019

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

  • Session-Klasse

    Guten Abend, Leute!

    Ich habe mich heute mal an eine Session-Klasse gesetzt. Davon gibt es ja die verschiedensten Variationen... Nur komme ich noch nicht wirklich damit klar. Wie Sessions funktionieren, klar, das weiß ich. Aber das in eine Klasse umzusetzen, ist wirklich ziemlich kompliziert! Zumindest für mich.

    Ich habe mir auch schon einige Klassen im Internet angeguckt. Aber ich bin nunmal dickköpfig und möchte meine eigene Klasse zum Laufen bringen, und ich würde mich freuen, wenn ihr mir da ein paar Tipps geben könntet!

    Den ganzen Code schreibe ich dann unten zusammenhängend, damit es leichter zu lesen ist.

    Meine Grundüberlegung ist, bei jeder neuen Instanz eine neue Session zu starten. Deshalb wird im Konstruktor irgendein Name für die Session angegeben. Wie schaut es aus, kann ich hier einfach problemlos eine neue Session starten?
    Außerdem wird hier überprüft, ob evtl. durch Cookies der User bereits ermittelt werden kann.

    Danach kommt eine Login-Methode. Bei dieser werden Username und -passwort auf ihre Gültigkeit überprüft. Ich speichere dann ggf. die Usernamen in einer Session-Variable mit dem Sessionnamen in der 1. und den Userangaben in der 2. Dimension.
    Falls $permanent true ist, wird der User dauerhaft eingeloggt, bzw. zwei Cookies gesetzt.

    In der Logout-Methode werden die Cookies zerstört und auf die Destroy-Methode zurückgegriffen, welche die Session zertört.

    PHP-Code:
    <?php
    class session {
        var 
    $name;

        
    // Der Konstruktor gibt der Session einen eindeutigen Namen
        
    function session($name '') {
            
    session_start();
            
    $this->name $name;

            
    // Wenn Cookies vorhanden, Inhalte in Session speichern
            
    if (isset($_COOKIE['username']) && isset($_COOKIE['userpwd'])) {
                
    $_SESSION[$this->name]['name'] = $_COOKIE['username'];
                
    $_SESSION[$this->name]['pwd'] = $_COOKIE['userpwd'];
            }
        }

        
    // User wird eingeloggt
        
    function login($user_name ''$user_pwd ''$permanent 0) {
            global 
    $db$cookie_timeout;

            
    $result $db->query("SELECT `name`, `pwd` FROM `users` WHERE `name` = '"$user_name ."' AND `pwd` = '"$user_pwd ."'");
            if (!
    $db->num_rows($result)) {
                return 
    false;
            } else {
                
    $array $db->fetch_array($result);
                
    $_SESSION[$this->name]['name'] = $array['name'];
                
    $_SESSION[$this->name]['pwd'] = $array['pwd'];

                
    // Wenn $permanent true, dann Cookies speichern
                
    if ($permanent) {
                    
    setcookie('username'$cookie_timeout$_SESSION['$this->name']);
                    
    setcookie('userpwd'$cookie_timeout$_SESSION['$this->pwd']);
                }

                return 
    true;
            }
        }

        
    // Loggt einen User aus
        
    function logout() {
            
    // Die Cookies werden entfernt
            
    if (isset($_COOKIE['username'])) {
                
    setcookie('username'0'');
            }

            if (isset(
    $_COOKIE['userpwd'])) {
                
    setcookie('userpwd'0'');
            }

            
    // Die Session wird zerstört
            
    $this->destroy();

            
    // Wenn alles gelöscht wurde, true zurückgeben. Ansonsten false
            
    if (!isset($_COOKIE['uername']) && !isset($_COOKIE['userpwd']) && !isset($_SESSION[$this->name])) {
                return 
    true;
    } else {
                return 
    false;
    }
        }

        
    // Die Session wird zerstört
        
    function destroy() {
            
    session_destroy();
        }
    }
    ?>
    Was haltet ihr von der Klasse? Wo gibt es Stärken, wo Schwächen? Wo könnte es gar zu Fehlern oder Risiken kommen?
    Über konstruktive Antworten würde ich mich freuen!

    Liebe Grüße
    Matze


  • #2
    Was passiert, wenn ich meinen Browser einen Keks mit username=admin;userpwd=xyz senden lasse? Ich sehe da keine Kontrolle. Wird einfach nach $_SESSION übernommen.

    if (isset($_COOKIE['username'])) {
    setcookie('username', 0, '');
    }
    danach ist $_COOKIE['username'] im aktuellen Skript immer noch gesetzt. Deshalb gibt logout() immmer false zurück.

    Der bisherigen Funktionalität nach ist das keine Klasse session sondern eher user+session

    Kommentar


    • #3
      Zitat von Schnulli
      Der bisherigen Funktionalität nach ist das keine Klasse session sondern eher user+session
      Hmm, und was würdest du da verbessern?

      Kommentar


      • #4
        user wäre bei mir ein Objekt innerhalb der Session.
        Als Beispiel (ohne weitere Klasse um $_SESSION herum)
        PHP-Code:
        <?php
        $_SESSION
        ['currentUser'] = new User;
        ?>

        Kommentar


        • #5
          Hallo Matze,

          Klassen dienen häufig der Abstraktion eines "Problems" oder einer Aufgaben-Stellung. Was du hier machst ist zwei Dinge gewaltig vermischen. Session haben erst mal nichts mit Cookies zu tun. Programmatisch gesehen kann man diese sicher für ähnliche Dinge nutzen, aber das wars auch schon. Was ich erwarte wäre folgendes:

          - Man kann die Session-Klasse mit einem Namespace instanziieren. So können verschiedene Programme mit der Session-Klasse arbeiten, ohne sich zu blockieren.
          - Es gibt Methoden wie getDataFromSession(), writeDataToSession() um Daten zu manipulieren.
          - Eine Methode clearSession() löscht die Session eines Namespaces.

          Damit hast du das Handling abstrahiert und kannst mit Sessions, wie auch mit anderen Services (MySQL-Klasse, ...) arbeiten. Für Cookies würde ich eine eigene nach dem genannten Interface erstellen. Wenn du ein Beispiel von mir haben möchtest, dann schau mal in den Threat http://www.phpfriend.de/forum/ftopic61760.html. Das Package beinhaltet eine solche Klasse.
          Viele Grüße,
          Dr.E.

          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          1. Think about software design before you start to write code!
          2. Discuss and review it together with experts!
          3. Choose good tools (-> Adventure PHP Framework (APF))!
          4. Write clean and reusable software only!
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

          Kommentar


          • #6
            Zitat von dr.e.
            Hallo Matze,

            Klassen dienen häufig der Abstraktion eines "Problems" oder einer Aufgaben-Stellung. Was du hier machst ist zwei Dinge gewaltig vermischen. Session haben erst mal nichts mit Cookies zu tun. Programmatisch gesehen kann man diese sicher für ähnliche Dinge nutzen, aber das wars auch schon. Was ich erwarte wäre folgendes:

            - Man kann die Session-Klasse mit einem Namespace instanziieren. So können verschiedene Programme mit der Session-Klasse arbeiten, ohne sich zu blockieren.
            - Es gibt Methoden wie getDataFromSession(), writeDataToSession() um Daten zu manipulieren.
            - Eine Methode clearSession() löscht die Session eines Namespaces.

            Damit hast du das Handling abstrahiert und kannst mit Sessions, wie auch mit anderen Services (MySQL-Klasse, ...) arbeiten. Für Cookies würde ich eine eigene nach dem genannten Interface erstellen. Wenn du ein Beispiel von mir haben möchtest, dann schau mal in den Threat http://www.phpfriend.de/forum/ftopic61760.html. Das Package beinhaltet eine solche Klasse.
            Danke, die Klasse hat mir auf die Sprünge geholfen!

            Kommentar


            • #7
              Danke, die Klasse hat mir auf die Sprünge geholfen!
              Gerne. Solltest du noch Anwendungsbeispiele brauchen (Login), sag Bescheid, ich hab da auch was auf Basis dieser Klasse...
              Viele Grüße,
              Dr.E.

              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              1. Think about software design before you start to write code!
              2. Discuss and review it together with experts!
              3. Choose good tools (-> Adventure PHP Framework (APF))!
              4. Write clean and reusable software only!
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

              Kommentar


              • #8
                Hmm, also ich hab das ganze jetzt letztendlich in 3 Klassen aufgeteilt: Session, Cookie und UserLogin.

                Die Session Klasse erstellt eine Session, löscht sie und verwaltet die Attribute.
                Die Cookie Klasse erstelle mit einer neuen Instanz einen neuen Cookie, der gelöscht oder geändert werden kann.

                Nur beim User-Login hack ich momentan etwas. Ich hab eine Methode "saveUserData()", mit der die Daten in eine Session und ggf. in zwei Cookies gespeichert werden.

                PHP-Code:
                <?php
                    
                function SaveUserData() {
                        global 
                $cfg;

                        
                // Sessions
                        
                $loginSession = new Session('login');
                        
                $loginSession->saveSessionData('username'$this->Username);
                        
                $loginSession->saveSessionData('pwd'$this->Pwd);

                        
                // Cookies
                        
                if ($this->Permanent) {
                            
                $cookieUsername = new Cookie('login_Username'
                                
                $this->Username$cfg['cookieTimeout']);
                            
                $cookiePwd = new Cookie('login_Pwd',
                                
                $this->Pwd$cfg['cookieTimeout']);
                        }
                    }
                ?>
                Soweit, so gut. Eigentlich kein Problem (hoffe ich... ).
                Aber nun habe ich auch eine Methode "logout()", in welcher ich die Session löschen will. Dafür muss ich aber eigentlich eine neue Instanz aufrufen, mit welcher die Session ja ohnehin überschrieben wird.

                PHP-Code:
                <?php
                            
                // $loginSession = new Session('login'); mit Informationen über Login


                    
                function logout() {
                                
                // Hier wird die eigentliche Session doch ohnehin überschrieben, der zweite Schritt ist eigentlich unnötig
                                
                $logoutSession = new Session('login');
                                
                $logoutSession->destroySession('login');

                                
                // Oder einfach so? Also ohne eine Instanz zu erstellen.
                                
                Session::destroySession('login');
                    }
                ?>
                Oder ganz anders?

                Kommentar


                • #9
                  Hallo Matze,

                  dein Ansatz war schon richtig. Solltest du dich an meinem Code orientiert und die Implementierung übernommen haben (verwend' die Klasse doch einfach ohne umbenennen :wink: ), so muss es

                  PHP-Code:
                  <?php
                     $logoutSession 
                  = new Session('login');
                     
                  $logoutSession->destroySession('login');
                  ?>
                  heißen. Intern bewirkt das das löschen des assoziativen Arrays $_SESSION['login'] und beim nächsten prüfen eines Wertes wirst du "null" zurückbekommen.

                  Ob ein

                  PHP-Code:
                  <?php
                  Session
                  ::destroySession('login'); 
                  ?>
                  funktioniert, kann ich dir nur beantworten, wenn ich weiß, wie deine (oder meine :wink: ) Implementierung der Klasse lautet.
                  Viele Grüße,
                  Dr.E.

                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  1. Think about software design before you start to write code!
                  2. Discuss and review it together with experts!
                  3. Choose good tools (-> Adventure PHP Framework (APF))!
                  4. Write clean and reusable software only!
                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                  Kommentar


                  • #10
                    Welche Implementierung meinst du jetzt genau?

                    Die Klassen habe ich erstmal einfach so geschrieben, zum Testen bin ich noch nicht gekommen.
                    Ich wollte die Klassen lediglich per Include einfügen und dann beim Login eine neue Instanz der UserLogin-Klasse erstellen, falls du das meinst...

                    Ansonsten habe ich dir die 3 Klassen einfach mal hochgeladen... http://www.speedshare.org/g5SQEWszvX

                    Kommentar


                    • #11
                      Hallo Matze,

                      Welche Implementierung meinst du jetzt genau?
                      Die Implementierung deiner destroySession()-Methode. Diese lautet bei dir

                      PHP-Code:
                      <?php
                      $_SESSION
                      [$Name] = array();
                      ?>
                      und da du in der Funktion getSessionData()


                      PHP-Code:
                      <?php
                              
                      if (isset($_SESSION[$this->Name][$Attribute])) {
                                  return 
                      $_SESSION[$this->Name][$Attribute];
                              } else {
                                  return 
                      false;
                              }
                      ?>
                      geschrieben hast ist das ok so. Die Instanz dr Session-Klasse muss auch nicht singleton sein, da dort ein


                      PHP-Code:
                      <?php
                                 session_register
                      ($Name);
                      ?>
                      inkludiert ist. Wichtig ist nur, dass deine Seiten so aufgebaut ist, dass die Ausgabe der kompletten Seite erst zum Schluss passiert, denn sonst bekommst du (zu Recht) Fehler.


                      Ansonsten habe ich dir die 3 Klassen einfach mal hochgeladen... http://www.speedshare.org/g5SQEWszvX
                      Hab ich mir angesegen. Die Session-Klasse ist ok, bei der Cookie-Klasse ist mir noch nicht ganz klar, wie ich ein bereits gesetztes Cookie nochmals ändern kann (falls das überhaupt (sinnvoll ist oder) geht. Die Login-Klasse ist zwar ganz nett, aber nicht wiederverwendbar. Erstens sind dort in den Stataments dedizierte Tabellen genannt, zweitens sind die Fälle

                      - Formular wird leer abgeschickt
                      - User ist auf einer Seite bereits eingeloggt

                      für mich nicht ersichtlich abgedeckt. Ein Login sollte entweder absolut konkret im Anwendungsfall stecken (mit seinen pres-, biz- und data-Komponenten) oder komplett generisch sein. Würdest du das Thema in 3 Schichten splitten, könntest du z.B. in einer Konfigurations-Datei je nach Anwendungsfall eine andere Datenschicht einbinden und so die Generik erreichen.
                      Viele Grüße,
                      Dr.E.

                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                      1. Think about software design before you start to write code!
                      2. Discuss and review it together with experts!
                      3. Choose good tools (-> Adventure PHP Framework (APF))!
                      4. Write clean and reusable software only!
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                      Kommentar

                      Lädt...
                      X