Ankündigung

Einklappen
Keine Ankündigung bisher.

Serialisierte Objekte bei SSL Redirect übernehmen

Einklappen

Neue Werbung 2019

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

  • Serialisierte Objekte bei SSL Redirect übernehmen

    Hallo Ihr,

    ich möchte gerne folgende Sache in meinem Shop realisieren:
    Ich habe ein Warenkorb-Objekt. Diese wird in der Session geführt und mit hilfe der Autoload-Funktion wird die Klassen-Definition immer geladen:
    PHP-Code:
    function __autoload($ClassName) {
        
    $ClassName explode('_'$ClassName);
        
    $ClassName implode('/'$ClassName);
        require_once(
    'include/classes/'.$ClassName.'.php');

    Nun möchte ich dass sich beim "Gang zur Kasse" eine SSL-Verbindung öffnent. Dabei wird wohl eine neue Session aufgebaut (jedenfalls sind die Daten in der Session weg). Die normalen Variablen oder Arrays in der Session kann ich ja per serialize() in der URL übertragen.
    Nun ist die Frage: Wie komme ich an das serialisiert Objekt zurück.
    In der URL kann ich es nicht übertragen - auch nicht mit:
    PHP-Code:
    addslashes(serialize($_SESSION['basket'])) 
    Und wenn ich es in einer Datei speichere wie geht ich dann mit mehreren User gleichzeit um?



    Bitte gebt mir Denkanstösse... Danke

    S.

  • #2
    Hallo, statt explode/implode funktioniert auch str_replace('_', DIRECTORY_SEPARATOR, $ClassName) wunderbar.

    Ob diese Aussage stimmt kann ich nicht sagen:
    Nun möchte ich dass sich beim "Gang zur Kasse" eine SSL-Verbindung öffnent. Dabei wird wohl eine neue Session aufgebaut (jedenfalls sind die Daten in der Session weg)
    Obwohl - bei einem Protokollwechsel könnte das Sinn machen.

    Wenn ja speicher den Warenkorb-Zustand doch in der Datenbank zwischen. Eine Liste aller Artikel und seiner Menge sollte ausreichend sein.
    Abgesehen davon könnte serialize() eine ungültig-lange Zeichenkette erzeugen, per URL würde ich das ganze also nicht übertragen. Das wirkt unprofessionell, auch deshalb, weil man dadurch per Link einen komplett gefüllten Warenkorb erzeugen könnte. Das könnte ein Sicherheitsrisiko darstellen. Zumindest begünstigen.

    In einer Datei würde ich das ganze auf keinen Fall umsetzen, wie du es bereits sagst, bei mehreren Usern würde dieses System kapitulieren.

    Nun ist die Frage: Wie komme ich an das serialisiert Objekt zurück.
    Datenbank:
    Vor dem Protokollwechsel das Objekt in der Datenbank speichern, entweder im Klartext, also als normalisierte Datenbank-Tabelle mit shoppingcart_ssl_transfer (id, article_id, amount, user_id, added) oder über das serialisierte Objekt shoppingcart_ssl_transfer (id, user_id, added, php_serialized_object). Letzteres ist natürlich ziemlich flexibel und bietet kaum Nachteile. Pass aber auf, dass kein fremder Warenkorb übernommen werden kann.

    Kommentar


    • #3
      Zitat von Zergling
      Hallo, statt explode/implode funktioniert auch str_replace('_', DIRECTORY_SEPARATOR, $ClassName) wunderbar.
      Danke. Das kannte ich noch nicht.

      Zitat von Zergling
      Vor dem Protokollwechsel das Objekt in der Datenbank speichern, entweder im Klartext, also als normalisierte Datenbank-Tabelle mit shoppingcart_ssl_transfer (id, article_id, amount, user_id, added) oder über das serialisierte Objekt shoppingcart_ssl_transfer (id, user_id, added, php_serialized_object). Letzteres ist natürlich ziemlich flexibel und bietet kaum Nachteile. Pass aber auf, dass kein fremder Warenkorb übernommen werden kann.
      Ok das habe ich mir auch schon gedacht. Doch wie kann ich diese in eine DB gespeicherten Daten eindeutig identifizieren? Wenn ich den Protokollwechsel mache, habe ich ja keine UserID, weil sich der User ja erst anmelden bzw. registrieren muss und SessionID ist vielleicht anders (muss ich mal prüfen, aber sonst wären ja die Session-Daten nicht weg oder? )

      Kommentar


      • #4
        Kannst du die Session nicht per URL übergeben? Den Protokollwechsel sollte ja eigentlich nur das Cookie stören, aber nicht die URL-Weitergabe..

        http://de.php.net/manual/de/ref.session.php
        Vordefinierte Konstanten
        [..]
        SID (string)
        Konstante, die entweder den Namen und die ID der Session in der Form "name=ID" enthält oder eine leere Zeichenkette, falls die Session-ID in einem entsprechenden Cookie gesetzt wurde.
        einfach übergeben. Falls leer musst du es dir mit
        PHP-Code:
        <?php
        echo session_name() . "=" session_id();
        ?>
        selbst zusammenbasteln.

        Kommentar


        • #5
          Also ich habe nochmal geschaut. Beim Protokoll-Wechsel bekomme ich eine neue SessionID.
          Ich habe jetzt eine tabelle basket_transfert (id, sessionID, serializedBasket, entryDate) in der ich vorm Protokollwechsel das serialisiert Warenkorb-Objekt einfüge. Dabei wird der Warenkorb anhand der SessionID überschrieben, wenn ich erneut einen Protokollwechsel von HTTP zu HTTPS habe. Außerdem speichere ich auch für die andere Richtung den Warenkorb in dieser Tabelle, denn bei mir kann der Kunde Artikel während der Bestellung löschen. Falls er nun aber wieder den HTTP-Bereich verlässt, muss für diese Warenkorb gespeichert werden.

          Irgendwie functioniert aber das wiederherstellen nicht richtig.
          ich speichere das serialisierte Objekt wie folgt:
          PHP-Code:
          $trans addslashes(serialise($_SESSION['basket']));
          //die Funktion prüft Existenz in der DB und macht dann ggf. ein INSERT oder UPDATE
          storeBasketForTransfer(session_id(), $trans);
          ?> 
          und beim wiederherstellen mache ich es wie folgt:
          PHP-Code:
          //die Funktion holt den serialisierten Warenkorb per DB-SELECT
          $basket restoreBasketForTransfer(session_id());
          $_SESSION['basket'] = unserialize(stripslashes($basket));
          ?> 
          Doch irgendwie funktioniert die Sache nicht richtig. Der Warenkorb wird in der DB gespeichert, aber wenn ich ihn zurückholen will geht es nicht.
          Habt ihr ne Idee?

          ... über das serialisierte Objekt shoppingcart_ssl_transfer (id, user_id, added, php_serialized_object). Letzteres ist natürlich ziemlich flexibel und bietet kaum Nachteile. Pass aber auf, dass kein fremder Warenkorb übernommen werden kann.
          Wie kann ich denn verhindern, dass kein fremder Warenkorb übernommen wird?

          Kommentar


          • #6
            Du hast doch gerade geschrieben, dass die session_id() sich ändert, dann kannst du sie ja auch schlecht als Key für den Tabelleneintrag nehmen!

            Wie kann ich denn verhindern, dass kein fremder Warenkorb übernommen wird?
            Gute Frage, wenn die Session zerstört wird, check Browser und IP nach, wenn sich eins von beidem während dem Wechsel ändert, hat der Benutzer halt Pech.

            Kommentar


            • #7
              Zitat von Zergling
              Du hast doch gerade geschrieben, dass die session_id() sich ändert, dann kannst du sie ja auch schlecht als Key für den Tabelleneintrag nehmen!
              Sorry, war nen Schreibfehler. Ich schreibe die SessionID vor dem Protokollwechsel in die URI und Requeste dann diese SessionID im neuen Protokoll, um sie als Schlüssel zur Wiederherstellung des Warenkorbs zu nutzen. Also wie folgt:
              PHP-Code:
              $basket restoreBasketForTransfer($_REQEUST['sessid']);
              $_SESSION['basket'] = unserialize(stripslashes($basket));
              ?> 
              Zitat von Zergling
              Gute Frage, wenn die Session zerstört wird, check Browser und IP nach, wenn sich eins von beidem während dem Wechsel ändert, hat der Benutzer halt Pech.
              OK!

              Kommentar


              • #8
                Du hast aber Schreibfehler drauf.. serialise, $_REQEUST, ..
                Schalt auf jeden Fall mal error_reporting(E_ALL) an.

                Was steht denn dann in $_REQUEST['sessid'], $basket und $_SESSION['basket']. Benutz var_dump() zur Ermittlung.

                Kommentar


                • #9
                  Zitat von Zergling
                  Du hast aber Schreibfehler drauf.. serialise, $_REQEUST,
                  ok, das war nur nen Schreibfehler, das stand nicht im Code.

                  Zitat von Zergling
                  Schalt auf jeden Fall mal error_reporting(E_ALL) an.
                  Was steht denn dann in $_REQUEST['sessid'], $basket und $_SESSION['basket']. Benutz var_dump() zur Ermittlung.
                  error_reporting(E_ALL) habe ich an. Zeigt aber keinen Output.
                  $_REQUEST['sessid'] liefert die SessionID die ich vorher in der URL übertragen habe. Nun kommt aber das kuriose.
                  Doch bevor ich das Ergebnis der Variablen aufliste hier kurz der Code meiner beiden Funktionen:

                  PHP-Code:
                  function storeBasketForTransfer($idSession$basket){
                      
                  $query =    "SELECT basket ".
                                  
                  "FROM `".DB_TABLE_ORDER_BASKET_SSL_TRANSFER."` ".
                                  
                  "WHERE idSession = '".$idSession."'";
                      
                  $db mysql_query($query);
                      
                  $rows mysql_num_rows($db);
                      if (
                  $rows == 0) {
                          
                  $query =    "INSERT INTO `".DB_TABLE_ORDER_BASKET_SSL_TRANSFER."` (idSession, basket, entryDate) " .
                                      
                  "VALUES ('".$idSession."', " .
                                              
                  "'".addslashes(serialize($basket))."', " .
                                              
                  "'".date("Y-m-d H:i:s")."')";
                           
                  mysql_query($query);
                      } elseif (
                  $rows == 1) {
                          
                  $query =    "UPDATE `".DB_TABLE_ORDER_BASKET_SSL_TRANSFER."` ".
                                      
                  "SET basket = '".addslashes(serialize($basket))."', entryDate = '".date("Y-m-d H:i:s")."' ".
                                      
                  "WHERE idSession = '".$idSession."'";
                          
                  mysql_query($query);
                      }
                  }
                  ?> 
                  PHP-Code:
                  function restoreBasketFromTransfer($idSession){
                      
                  $query =    "SELECT basket ".
                                  
                  "FROM `".DB_TABLE_ORDER_BASKET_SSL_TRANSFER."` ".
                                  
                  "WHERE idSession = '".$idSession."'";
                      
                  $result mysql_fetch_array(mysql_query($query));
                      
                  $basket unserialize(stripslashes($result['basket']));
                      echo 
                  '<pre>'print_r($baskettrue), '</pre>';
                      return 
                  basket;
                  }
                  ?> 
                  wenn ich per print_r() vor dem Return in der Funktion restoreBasketFromTransfer() (Zeile 7) den aus der DB ausgelesenen Warenkorb ausgeben lasse kommt folgendes Ergebnis:

                  Code:
                  basket Object
                  (
                      [productList:private] => Array
                          (
                              [47] => Array
                                  (
                                      [1] => Array
                                          (
                                              [1] => 1
                                          )
                  
                                  )
                  
                          )
                  
                      [totalValue:private] => 134.95
                      [totalWeight:private] => 1300
                  )
                  Also so wie es sein sollte.
                  Wenn ich aber das Objekt nach dem Return ausgebe kommt, folgende Ausgaben:

                  Code:
                  basket
                  Was habe ich falsh gemacht, bzw. wo liegt der Fehler?
                  Ich blickt nicht durch!

                  Kommentar


                  • #10
                    Ich habe mal per gettype($basket) mal geschaut, was es für ein Typ ist.

                    Bei der ersten Ausgabe ist es noch ein Objekt und nach dem Return ist es nur noch ein String. Muss man das den extra zum Type "basket" casten?

                    Kommentar


                    • #11
                      Du hast error_reporting nicht auf E_ALL, sonst wäre der Notice hierfür geworfen worden:
                      PHP-Code:
                      <?php
                      return basket
                      ?>
                      Macht keine Spass hier zu rätseln, wenn du nicht die Wahrheit sagst.

                      Kommentar


                      • #12
                        Zitat von Zergling
                        Du hast error_reporting nicht auf E_ALL, sonst wäre der Notice hierfür geworfen worden:
                        Doch hatte ich, doch anscheind hatte ich es nicht ganz am Anfang der Seite.
                        Wenn man es ordentlich macht, dann hätte man wirklich eine Notice bekommen:
                        Code:
                        Notice: Use of undefined constant basket - assumed 'basket' in <PATH>\include\functions\order.inc.php on line 30
                        Also einfach basket in $basket ändern und schon klappts....

                        Vielen Dank für Deine Geduld Zergling.
                        Gruße,
                        S.

                        Kommentar


                        • #13
                          Scho recht
                          Nun klappt alles?

                          Übrigens bietet dir PHP 5 die magischen Methoden __sleep() und __wakeup() an. Sind diese definiert, kann dein Objekt selbst entscheiden, wie es serialized() bzw. unserialized() werden soll.
                          http://de3.php.net/oop.magic-functions

                          Weiß aber nicht ob du das brauchst.

                          Kommentar


                          • #14
                            Das habe ich schon mal gelesen, habe es aber nicht genaue angeschaut.
                            Vielleicht sollte ich dies mal tun.

                            Ansonsten funktioniert nun alles (jedefalls was ich ursprünglich adressiert habe :wink: )
                            Also nochmal Danke. Bis zum nächsten Problem.

                            Kommentar

                            Lädt...
                            X