Artikel in Warenkorb nach 14 Tagen löschen

js82

Grünschnabel
Hallo,

ich hoffe, irgendjemand kann mir weiterhelfen. Ich muss mir eine Aufgabe für einen Lehrgang erarbeiten und stecke fest. Da ich in diesem Forum bereits so viel gelesen und gelernt habe und extrem glücklich bin, dass es euch Profis gibt, hoffe ich, mir kann jemand einen Tipp geben.

Ich möchte Artikel, die sich nach 14 Tagen noch im Warenkorb meiner MySQL Datenbank befinden löschen.

Dafür habe ich bislang diese private function geschrieben:

PHP:
private function loescheWarenkorb($datum)
  {
    if(!empty($datum))
     {
     try
    {
  
    $sql = "DELETE FROM ws_warenkorb WHERE DATEDIFF(dd, w_timestamp = :datum, NOW()) > 14";
    $result = $this->dbh->prepare($sql);
    $result->bindParam(':datum', $datum, PDO::pARAM_INT);
    $result->execute();
      
    }


Leider funktioniert es nicht. Kann mir jemand sagen, was ich falsch mache? Ich freue mich wirklich sehr über eine Antwort!!

Viele Grüße

Jeanie
 
Zuletzt bearbeitet von einem Moderator:
Hallo js,

1. Bitte schreibe Code in den Code-Tag
2. Wie wird in deiner Datenbank das Datum gespeichert (Timestamp oder als DateTime)?
3. Die Sql-Funktion DateDiff erwartet 2 Parameter und nicht wie du hast 3.

Lass dir mal auf deiner Seite den SQL-Query ausgeben und teste ihn mal in einer Mysql-Console oder in Phpmyadmin oder etwas vergleichbaren.
Würde aber darauf Tippen, das es an deinen Query liegt.
Du verwendest zwar die Mysql-Funktion now() übergibst aber trotzdem noch ein Datum.
Dies müsstest du eigentlich nicht, da now() das momentane Datum und Uhrzeit zurück gibt.
 
Hallo merzi86,

vielen Dank für die Antwort!

Hier nochmal ordentlich im Code-Tag, entschuldigung!

PHP:
private function loescheWarenkorb($datum)
  {
    if(!empty($datum))
     {
     try
    {
  
    $sql = "DELETE FROM ws_warenkorb WHERE DATEDIFF( w_timestamp = :datum, NOW()) > 14";
    $result = $this->dbh->prepare($sql);
    $result->bindParam(':datum', $datum, PDO::PARAM_INT);
    $result->execute();
      
    }
  
  catch(PDOException $e)
    {
      echo $e->getMessage();
    }
} 
}


Das Datum ist als timestamp gespeichert.

Alles klar, dann nehme ich das "dd" raus? Habe zuerst auch ohne es gearbeitet, aber dann irgendwo gelesen, das solle man einbauen... puh...das war wohl Fehlinformation.

Vielleicht hört sich das jetzt blöd an, aber wie kann ich den SQL Query ausgeben? Verstehe leider nicht genau, was das bedeutet.

Zum Datum: Das Feld w_timestamp steht für mein Datum, an dem der Artikel gespeichert wurde. Ist es denn nicht richtig, das aktuelle Datum, also NOW vom Speicherdatum abzuziehen?

Vielen Dank schon mal!!
 
Zuletzt bearbeitet von einem Moderator:
Den Query ausgeben kannst du so:
PHP:
echo $sql;

Hast du in deiner Datenbankenklasse einen Error-Mode definiert?
Ich empfehle die den Error-Mode auf Exception zu stellen, da wird bei einen Fehlerhaften Query eine Exception geschmiessen.
PHP:
$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Zum Thema DateDiff.
Im Offiziellen Handbuch von Mysql kannst du Nachlesen, wie die Funktionen arbeiten.
So kannst du z.B. hier etwas über DateDiff lesen.

DateDiff arbeitet primär mit Date und DateTime formaten, ob es mit Timestamp arbeiten kann weiß ich gerade leider nicht.
Now() gibt ein DateTime im Format "2008-11-11 12:45:34" zurück.

Eine andere Möglichkeit wäre die Abfrage so zu ändern.
PHP:
$sql= "DELETE FROM 'ws_warenkorb' WHERE ('w_timestamp' + 14*86400) <  UNIX_TIMESTAMP(NOW())";
 
Danke! Habe das jetzt alles mal ausprobiert, geb ich echo $sql; ein, dann erscheint in der Ausgabe nichts Woran könnte das denn liegen? Den Error-Mode habe ich bereits aktiviert...

Mit der anderen vorgeschlagenen Abfrage funktioniert es trotzdem nicht. Kann es sein, dass mein Fehler wo anders in der private function liegt?
 
Es kann dann nur noch an deiner If-Anweisung liegen.
Lass mal in dem Else-Zweig der If-Anweisung eine Ausgabe machen wie z.B. Datum ist leer.

Eine andere Möglichkeit ist, dass es zwar eine Exception geworfen wird, diese aber keine PDOException ist.
Ändere mal dein Catch so ab
PHP:
catch(Exception $e)
 
mhh, habe deinen Rat befolgt und beides ausprobiert, bei der else Abfrage erscheint nichts, wenn ich nur Exception eingebe auch nicht.

Kann es sein, dass ich die Methode einfach falsch eingebunden habe?

Meine public function waehlen:

Code:
public function waehlen($artikelnummer, $kunde)
  {
  if(!empty($artikelnummer) && !empty($kunde))
  {
     try
    {
      $sql = "SELECT a_name, a_artikelnr FROM ws_artikel WHERE a_menge - 1";
      $result = $this->dbh->query($sql);
      $tmp = $result->fetchAll(PDO::FETCH_ASSOC);
     
      foreach($tmp as $key => $value)
      $sql = "UPDATE ws_warenkorb
                 SET w_menge = w_menge + 1
               WHERE w_artikelnr = :nummer
                 AND w_kunde = :kunde";
      $result = $this->dbh->prepare($sql);
      $result->bindParam(':nummer', $artikelnummer, PDO::PARAM_INT);
      $result->bindParam(':kunde', $kunde, PDO::PARAM_INT);
      $result->execute();
      if ($result->rowCount() == 1)
        return true;

      $sql ="INSERT INTO ws_warenkorb (w_artikelnr, w_kunde, w_menge)
                  VALUES (:nummer, :kunde, 1)";
      $result = $this->dbh->prepare($sql);
      $result->bindParam(':nummer', $artikelnummer, PDO::PARAM_INT);
      $result->bindParam(':kunde', $kunde, PDO::PARAM_INT);
      $result->execute();
      if($result->rowCount()== 1)
      {
        $this->loescheWarenkorb($this->datum);
        print "Datensatz wurde eingetragen.";
          return true; 
      }
      return false;
    
    }
    catch(PDOException $e)
    {
      echo $e->getMessage();
    }
  }
}

ich dachte, es macht Sinn, es dort einzubauen.. also nachdem der Datensatz in den Warenkorb eingetragen wurde...

Danke im Voraus!!
 
Trägt er denn überhaupt Artikel ein?

Wenn ich den Quellcode sehe würde ich Tippen, das er nicht einmal bis zum Funktionsaufruf kommt.
Eine Foreach-Schleife wird normalerweise so aufgebaut
PHP:
foreach($array as $value) {
      // Schleifencode
}

Diese Schreibweise ist nur zulässig, wenn es eine Zeile/Anweisung innerhalb der Schleife gibt.
PHP:
foreach($array as $value)
      // Schleifencode

In deinen Code wird allerdings, bzw. würde ich sagen sollen, mehrere Zeilen in der Schleife stehen.
Auch wegen der Lesbarkeit ist die 1. Variante teils schöner.

Ansonsten würde ich dir Empfehlen mal diverse Punkte (Kontroll Ausgaben) zwischen drin auszugeben zur Überprüfung, ob alles so läuft wie du es vor hast.
 
In deinen Code wird allerdings, bzw. würde ich sagen sollen, mehrere Zeilen in der Schleife stehen.
Der Interpreter (oder Compiler bei anderen Sprachen) nimmt sich die erste Anweisung, die er finden kann. In seinem Fall ist das die Zuweisung an $tmp;
Ich stimme dir aber völlig zu, die Variante mit den Klammern würde ich immer bevorzugen.

Da die Variablen der foreach-Schleife allerdings sowieso nicht genutzt werden, frage ich mich, was diese Schleife überhaupt bringen soll.

Ich empfehle einen Debugger zum Kontrollieren der Werte während des Ausführens des Skriptes. (Die Einarbeitungszeit im Gegensatz zu echo/var_dump ist natürlich größer, aber die Effektivität beim Debuggen umso gigantischer :cool:)
 
Hallo,

oh ja, danke, der Befehl war dort natürlich falsch... das hatte ich übersehen...:-( danke!

soll natürlich heißen

Code:
public function waehlen($artikelnummer, $kunde)
  {
  if(!empty($artikelnummer) && !empty($kunde))
  {
     try
    {
      $sql = "UPDATE ws_warenkorb
                 SET w_menge = w_menge + 1
               WHERE w_artikelnr = :nummer
                 AND w_kunde = :kunde";
      $result = $this->dbh->prepare($sql);
      $result->bindParam(':nummer', $artikelnummer, PDO::PARAM_INT);
      $result->bindParam(':kunde', $kunde, PDO::PARAM_INT);
      $result->execute();
      if ($result->rowCount() == 1)
        return true;

      $sql ="INSERT INTO ws_warenkorb (w_artikelnr, w_kunde, w_menge)
                  VALUES (:nummer, :kunde, 1)";
      $result = $this->dbh->prepare($sql);
      $result->bindParam(':nummer', $artikelnummer, PDO::PARAM_INT);
      $result->bindParam(':kunde', $kunde, PDO::PARAM_INT);
      $result->execute();
      if($result->rowCount()== 1)
      {
        $this->loescheWarenkorb($this->datum);
        print "Datensatz wurde eingetragen.";
          return true; 
      }
      return false;
    
    }
    catch(PDOException $e)
    {
      echo $e->getMessage();
    }
  }
}

löschen tut er die Artikel dennoch nicht, in den Warenkorb werden sie übrigens eingetragen, das funktioniert alles. Das Debuggen werde ich später in Ruhe ausprobieren, danke!!
 
Zurück