cruelsmith2012: Objekte: Löschfkt. mit vorlöschen

Hi Leute,

habe mal nen Problem.

Habe ne Art Gästebuch wo ich die Datenbank und Objekte nutze.

Das ist meine Löschfunktion, welche entscheidet ob nur zum Löschen vorgemerkt wird oder ob sie aus der Datenbank verschwindet.

//Fkt. zum vormerken  
public function delete() {  
	return $this->query("UPDATE `HP_Blackboard` SET `delete_UserID` = '".$this->getCurrentUser()."', `delete_date` = '".time()."' WHERE `NoteID` = '".$this->id."'");  
}  
  
//Fkt. zum löschen  
public function purge() {  
	return $this->query("DELETE FROM `HP_Blackboard` WHERE `NoteID` = '".$this->id."'");  
}  
  
//Fkt. die Prüft ob gelöscht oder vorgemerkt werden soll  
public function goDelete() {  
	if (!$this->ddate == '0') {  
		$this->purge();  
		return 'purge';  
	} else {  
		$this->delete();  
		return 'delete';  
	}  
}

So das Problem ist jetzt genau, das wenn die Fkt. goDelete() aufgerufen wird, sieht er das (!$this->ddate == '0') = FALSE ist und führt $this->delete(); aus.

!?! Und da ist das Problem, die Fkt. wird ausgeführt und das Objekt KOMISCHERWEISE neu geladen, wobei dann goDelete() bzw die Fallunterscheidung nochmal neu aufgerufen wird.

Also wird am Ende immer $this->delete(); ausgeführt und der Eintrag verschwindet aus der Datenbank.

Hat einer ne Idee wie ich das Lösen kann?

MfG cruelsmith2012

  1. Hi!

    return $this->query("UPDATE HP\_Blackboard SET delete\_UserID = '".$this->getCurrentUser()."', delete\_date = '".time()."' WHERE NoteID = '".$this->id."'");
    return $this->query("DELETE FROM HP\_Blackboard WHERE NoteID = '".$this->id."'");

    Wie schaut es denn mit der Beachtung des Kontextwechsels aus?

    if (!$this->ddate == '0') {

    Ein Operator reicht: $this->ddate != '0'

    !?! Und da ist das Problem, die Fkt. wird ausgeführt und das Objekt KOMISCHERWEISE neu geladen, wobei dann goDelete() bzw die Fallunterscheidung nochmal neu aufgerufen wird.

    Auch wenn du "komischerweise" in Großbuchstaben schreibst, passiert das ja nicht einfach so. Es gibt eine Ursache, dass der Code mit anderen Parametern noch einmal aufgerufen wird.

    Hat einer ne Idee wie ich das Lösen kann?

    Zunächst musst du die Ursache finden, bevor du über eine geeignete Lösung nachdenken kannst. Und diese Ursache lässt sich dem gezeigten Ausschnitt nicht entnehmen.

    Wenn sich alles innerhalb eines Requests abspielt (kontrollieren mit den Server-Logfiles), dann ist der Programmfluss irgendwo anders als angenommen. Wenn du den nicht per einfachem Lesen nachvollziehen und den Fehler finden kannst, helfen Tools wie das debug_[print_]backtrace() die Aufrufreihenfolge inklusive aller übergebenen Parameterwerte festzustellen.

    Lo!

    1. Hi,

      Wie schaut es denn mit der Beachtung des Kontextwechsels aus?

      Habe nochmal drüber gekuckt daran kanns nicht liegen.

      if (!$this->ddate == '0') {  
      

      Ein Operator reicht: $this->ddate != '0'

      ja hatte mal gelesen das !$var == 'wert' schneller sein soll als != aber das ist leider auch nicht der fehler

      !?! Und da ist das Problem, die Fkt. wird ausgeführt und das Objekt KOMISCHERWEISE neu geladen, wobei dann goDelete() bzw die Fallunterscheidung nochmal neu aufgerufen wird.

      Auch wenn du "komischerweise" in Großbuchstaben schreibst, passiert das ja nicht einfach so. Es gibt eine Ursache, dass der Code mit anderen Parametern noch einmal aufgerufen wird.

      Hat einer ne Idee wie ich das Lösen kann?

      Zunächst musst du die Ursache finden, bevor du über eine geeignete Lösung nachdenken kannst. Und diese Ursache lässt sich dem gezeigten Ausschnitt nicht entnehmen.

      Wenn sich alles innerhalb eines Requests abspielt (kontrollieren mit den Server-Logfiles), dann ist der Programmfluss irgendwo anders als angenommen. Wenn du den nicht per einfachem Lesen nachvollziehen und den Fehler finden kannst, helfen Tools wie das debug_[print_backtrace()] die Aufrufreihenfolge inklusive aller übergebenen Parameterwerte festzustellen.

      »»

      Habe jetzt mal mit debug_[print_backtrace()] probiert und folgendes bekommen, als ich es zu in die Fkt. goDelete() geschrieben habe:

      #0  Blackboard->goDelete() called at [/var/www/web272/html/community/blackboard.php:207]  
      #1  include(/var/www/web272/html/community/blackboard.php) called at [/var/www/web272/html/index.php:81]  
      
      

      So warum wird die Fkt. jetzt einmal in meiner blackboard.php ausgeführt und dann nochmal bei der index.php wenn ich die blackboard.php include?

      Da habe ich noch nen Problem im Kopf :(

      MfG cruelsmith2012

      1. habe gerade mit print_r( debug_backtrace (  ) ); in der Fkt. nochmal probiert das kamm raus:

        Array  
        (  
            [0] => Array  
                (  
                    [file] => /var/www/web272/html/community/blackboard.php  
                    [line] => 207  
                    [function] => goDelete  
                    [class] => Blackboard  
                    [type] => ->  
                    [object] => Blackboard Object  
                        (  
                            [id:private] => 5  
                            [author:private] => s0378  
                            [editor:private] =>  
                            [deleter:private] => s0378  
                            [bdate:private] => 1298022277  
                            [edate:private] => 0  
                            [ddate:private] => 1298064235  
                            [type:private] => 0  
                            [title:private] => adad  
                            [text:private] => adad  
                        )  
          
                    [args] => Array  
                        (  
                        )  
          
                )  
          
            [1] => Array  
                (  
                    [file] => /var/www/web272/html/index.php  
                    [line] => 81  
                    [args] => Array  
                        (  
                            [0] => /var/www/web272/html/community/blackboard.php  
                        )  
          
                    [function] => include  
                )  
          
        )
        

        Hier frage ich mich dann, warum [ddate:private] nicht "0" ist weil so stehts in der datenbank und wenn ich die $this->purge(); und $this->delete(); auskommentiere, dann werden mir die richtigen texte angezeit, sofern aber eine der class fkt. aufgerufen wurde, passiert alles nochmal :(

        MfG cruelsmith2012

        1. Hi!

          Hier frage ich mich dann, warum [ddate:private] nicht "0" ist weil so stehts in der datenbank

          Untersuche diese Vermutung mit Kontrollausgaben an den Stellen, an denen dieser Wert geändert wird.

          Lo!

          1. Hier frage ich mich dann, warum [ddate:private] nicht "0" ist weil so stehts in der datenbank

            Untersuche diese Vermutung mit Kontrollausgaben an den Stellen, an denen dieser Wert geändert wird.

            Dies hatte ich schon kontrolliert^^

            Alles ist richtig wenn ich die Funktions aufrufungen in der Funktion goDelete() weg lasse. Dann kommt wenn das Objekt [ddate:private] == 0 hat, so wie es vorgesehen ist, return 'delete'; also "delete" raus.

            So fern ich aber $this->delete() aufrufen lasse, dann passiert anscheinend ein neuladen der Seite, da "delete" nicht mehr raus kommt sondern  return 'purge'; bzw  "purge" deswegen muss also $this->delete() schon ausgeführt worden sein. Aber warum wird dann nicht "delete" und "purge" ausgegeben? Es wurden ja beide Fallunterscheidungsteile ausgeführt, sonst könnte ja [ddate:private] != 0 sein. :(

            Webserver-Logfiles

            Wie komme ich denn an die Logfiles des Servers ran wenn ich nur Nutzer eines Webservers bin?

            vielen Dank schon mal an dich dedlfix

            MfG cruelsmith2012

            1. Hi!

              Hier frage ich mich dann, warum [ddate:private] nicht "0" ist weil so stehts in der datenbank
              Untersuche diese Vermutung mit Kontrollausgaben an den Stellen, an denen dieser Wert geändert wird.
              Dies hatte ich schon kontrolliert^^

              Und an welcher Stelle wurde es ungleich 0? Hast du überall, wo diese Eigenschaft beschrieben wird mal eine Kontrollausgabe eingefügt, so dass du sehen kannst, wann welche Stalle Aufgerufen und wie der Wert geändert wurde?

              So fern ich aber $this->delete() aufrufen lasse, dann passiert anscheinend ein neuladen der Seite, da "delete" nicht mehr raus kommt sondern  return 'purge'; bzw  "purge" deswegen muss also $this->delete() schon ausgeführt worden sein. Aber warum wird dann nicht "delete" und "purge" ausgegeben? Es wurden ja beide Fallunterscheidungsteile ausgeführt, sonst könnte ja [ddate:private] != 0 sein. :(

              Davon ist im gezeigten Code nichts zu sehen. Wenn ->query() das nicht macht, vermutest du vielleicht was falsches.

              Webserver-Logfiles
              Wie komme ich denn an die Logfiles des Servers ran wenn ich nur Nutzer eines Webservers bin?

              Frag deinen Hoster. Üblicherweise bekommst du die deinen Webauftritt betreffenden irgendwo zur Verfügung gestellt.

              Lo!

              1. Hier frage ich mich dann, warum [ddate:private] nicht "0" ist weil so stehts in der datenbank
                Untersuche diese Vermutung mit Kontrollausgaben an den Stellen, an denen dieser Wert geändert wird.
                Dies hatte ich schon kontrolliert^^

                Und an welcher Stelle wurde es ungleich 0? Hast du überall, wo diese Eigenschaft beschrieben wird mal eine Kontrollausgabe eingefügt, so dass du sehen kannst, wann welche Stalle Aufgerufen und wie der Wert geändert wurde?

                Na nur wenn die Fkt. $this->delete() aufgerufen wird, kann sich der Wert von [ddate:private] ändern, aber wenn ich da ne kontroll ausgabe hinpacke kommt diese nicht, da anscheinend der echo Teil übersprungen oder überschrieben oder sowas wird. :(

                Wie gesagt ohne $this->delete() ist alles schick, also richtige ausgaben.
                Wenn $this->delete() dann wird alles noch mal gemacht und die Kontrolle überschrieben

                So fern ich aber $this->delete() aufrufen lasse, dann passiert anscheinend ein neuladen der Seite, da "delete" nicht mehr raus kommt sondern  return 'purge'; bzw  "purge" deswegen muss also $this->delete() schon ausgeführt worden sein. Aber warum wird dann nicht "delete" und "purge" ausgegeben? Es wurden ja beide Fallunterscheidungsteile ausgeführt, sonst könnte ja [ddate:private] != 0 sein. :(

                Davon ist im gezeigten Code nichts zu sehen. Wenn ->query() das nicht macht, vermutest du vielleicht was falsches.

                Ne ->query($wert) ist nur return mysql_query($wert) mehr nicht.

                Webserver-Logfiles
                Wie komme ich denn an die Logfiles des Servers ran wenn ich nur Nutzer eines Webservers bin?

                Frag deinen Hoster. Üblicherweise bekommst du die deinen Webauftritt betreffenden irgendwo zur Verfügung gestellt.

                ok muss ich mal fragen

                MfG cruelsmith2012

                1. Hi!

                  Na nur wenn die Fkt. $this->delete() aufgerufen wird, kann sich der Wert von [ddate:private] ändern, aber wenn ich da ne kontroll ausgabe hinpacke kommt diese nicht, da anscheinend der echo Teil übersprungen oder überschrieben oder sowas wird. :(

                  Davon ist in deinem Code nichts zu sehen. Ich kann nicht nachvollziehen, was genau abläuft, und kann dir deswegen nur allgemeine Hinweise zum Fehlersuchen geben.

                  Kontrolausgaben macht man am besten mit var_dump(), denn das zeigt einerseits den Typ des Wertes und andererseits garantiert etwas an. Einige Werte erzeugen mit echo nur einen Leerstring, beispielsweise false oder null. Wichtig zum Fehlersuchen ist auch das auf E_ALL gestellte error_reporting (nebst einem display_errors, das auf on steht).

                  Wenn etwas "anscheinend" so ist, dann prüf das mit einer Ausgabe. Wenn diese nicht kommt, dann ist vermutlich anders abgezweigt worden, prüfe auch diesen Zweig und die Bedingung ebenso.

                  Wie gesagt ohne $this->delete() ist alles schick, also richtige ausgaben.
                  Wenn $this->delete() dann wird alles noch mal gemacht und die Kontrolle überschrieben

                  Es nochmal zu wiederholen bringt nichts. Du musst einfach hartnäckig Debugging betreiben, sonst wirst du den Fehler nicht finden. Zur Not musst du an alle möglichen und unmöglichen Stellen eine Ausgabe einbauen, so dass du nachvollziehen kannst, in welcher Reihenfolge deine Codeteile ausgeführt werden.

                  Lo!

                  1. So hi,

                    habe jetzt durch die Webserver-Logfiles herhraus gefunden, dann die seite nochmal geladen wurde.

                    IP_ADRESSE - - [23/Feb/2011:22:01:49 +0100] "GET /community,blackboard_loeschen,12,0.html HTTP/1.1" 200 3851 "http://www.einstein-gymnasium-neuenhagen.de/community,blackboard.html" "Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13"
                    IP_ADRESSE - - [23/Feb/2011:22:01:51 +0100] "GET /community,blackboard_loeschen,12,1.html HTTP/1.1" 200 3865 "http://www.einstein-gymnasium-neuenhagen.de/community,blackboard_loeschen,12,0.html" "Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13"
                    92.227.114.247 - - [23/Feb/2011:22:01:51 +0100] "GET /community,blackboard_loeschen,12,1.html HTTP/1.1" 200 3881 "http://www.einstein-gymnasium-neuenhagen.de/community,blackboard_loeschen,12,0.html" "Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13"

                    Das erklärt auch, warum die Kontroll ausgaben nichts sagen konnten.

                    Jetzt muss ich nur noch die stelle finden^^.

                    Danke schon mal dedlfix, für den Webserver-Logfile tipp.

                    MfG cruelsmith2012

                    1. Hi!

                      habe jetzt durch die Webserver-Logfiles herhraus gefunden, dann die seite nochmal geladen wurde.
                      Jetzt muss ich nur noch die stelle finden^^.

                      Vielleicht ist es ein fehlerhafter Verweis in einer einzubindenden Ressource, beispielsweise ein CSS-File oder ein Bild, bei dem die URL versehentlich leer ist. Sowas findet man, indem man schrittweise alles Überflüssige rausnimmt.

                      Lo!

                      1. Hi,

                        Vielleicht ist es ein fehlerhafter Verweis in einer einzubindenden Ressource, beispielsweise ein CSS-File oder ein Bild, bei dem die URL versehentlich leer ist. Sowas findet man, indem man schrittweise alles Überflüssige rausnimmt.

                        »»

                        Ne das ist es anscheinend nicht, da was interessantes passiert:

                        UNTER FIREFOX

                        [24/Feb/2011:18:30:02 +0100] "GET /community,blackboard_loeschen,12,0.html HTTP/1.1" 200 3862 "http://www.einstein-gymnasium-neuenhagen.de/community,blackboard.html" "Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13"

                        Seite zum bestätigen des löschens.(oben)

                        So jetzt noch mal erklärt:

                        Uhrzeit: [24/Feb/2011:18:30:03 +0100]
                        Anfrage: "GET /community,blackboard_loeschen,12,1.html HTTP/1.1"
                        Unbekannte Zahle: 200
                        Unbekannte Zahle: 3884
                        Seite von der Anfragt wird: "http://www.einstein-gymnasium-neuenhagen.de/community,blackboard_loeschen,12,0.html"
                        Browser + System: "Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13"

                        Und das ganze komischer Weise zweimal gleich zeitig. (Siehe Zeit)

                        [24/Feb/2011:18:30:03 +0100] "GET /community,blackboard_loeschen,12,1.html HTTP/1.1" 200 3884 "http://www.einstein-gymnasium-neuenhagen.de/community,blackboard_loeschen,12,0.html" "Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13"

                        ANDERS bei Opera

                        [24/Feb/2011:18:28:40 +0100] "GET /community,blackboard_loeschen,12,0.html HTTP/1.1" 200 3850 "http://www.einstein-gymnasium-neuenhagen.de/community,blackboard.html" "Opera/9.80 (Windows NT 6.1; U; de) Presto/2.7.62 Version/11.00"

                        Seite zum bestätigen des löschens.(oben)

                        [24/Feb/2011:18:28:41 +0100] "GET /community,blackboard_loeschen,12,1.html HTTP/1.1" 200 3877 "http://www.einstein-gymnasium-neuenhagen.de/community,blackboard_loeschen,12,0.html" "Opera/9.80 (Windows NT 6.1; U; de) Presto/2.7.62 Version/11.00"

                        Ja komisch was Firefox macht. Finde ihn sonst eigentlich perfekt :(

                        Löse jetzt das Problem einfach, dass ich nen Timer setze, dass erst der Eintrag nachdem er 3min im Papierkorb war gelöscht werden kann.

                        Muss aber generell nochmal gucken da unter ie8 zum beispiel die löschung sich nicht bestädigen lässt.

                        Ok dan nochmal vielen dank an dedlfix!

                        MfG cruelsmith2012

                        1. Hi!

                          Vielleicht ist es ein fehlerhafter Verweis in einer einzubindenden Ressource, beispielsweise ein CSS-File oder ein Bild, bei dem die URL versehentlich leer ist. Sowas findet man, indem man schrittweise alles Überflüssige rausnimmt.
                          Ne das ist es anscheinend nicht, da was interessantes passiert:

                          Beim Computer gibt es kein "anscheinend", es ist alles nachprüfbar. Ist da also eine Resourceneinbindung mit leerer URL oder nicht? Hast du alles entfernt, so dass nur der eine Lösch-Link enthalten ist und nichts anderes, das diese Nebenwirkung haben kann?

                          Unbekannte Zahle: 200
                          Unbekannte Zahle: 3884

                          Das (Default-)Format der Logfiles ist bekannt und dokumentiert. 200 ist der HTTP-Statuscode (200=OK) und 3884 ist die Anzahl der ausgelieferten Daten in Bytes.

                          Seite von der Anfragt wird: "http://www.einstein-gymnasium-neuenhagen.de/community,blackboard_loeschen,12,0.html"

                          Das ist der Referer, da steht manchmal die URL drin, in der der Verweis drinsteht.

                          Und das ganze komischer Weise zweimal gleich zeitig. (Siehe Zeit)

                          Auch nach neuer Rechtschreibung ist ein komischer Weise was anderes als das Abverb komischerweise. Abgesehen davon ist eine Sekunde recht lang. Es kann durchaus sein, dass Request, Response und noch ein Request es in der einen Sekunde schaffen.

                          ANDERS bei Opera

                          Bei der Ressource mit der leeren URL ist es so, dass der Firefox zwei Rquests sendet, der Opera nur einen. Allerdings wären beim FF die Referrer unterschiedlich. Insofern muss meine Theorie mit dem leeren Verweis nicht stimmen.

                          Löse jetzt das Problem einfach, dass ich nen Timer setze, dass erst der Eintrag nachdem er 3min im Papierkorb war gelöscht werden kann.

                          Such lieber die Ursache anstatt zu versuchen mit irgendwelchen Mitteln das Problem zu umgehen.

                          Lo!

                          1. Ja hi sry,

                            habe den dämlichen Fehler gefunden.

                            Kommt davon wenn man Kopiert und nicht drauf achtet was.

                              
                            echo '<a href="community,blackboard_loeschen,'.$note->getID().',1.html"><input value="Ja" type="button" /></a>';
                            

                            Zur erklärung was Firefox macht:

                            Der Link wird ausgeführt, dabei sieht er den Button und sendet gleich nochmal eine Anfrage an den Server.

                            Ergebnis:
                            Seite wird zweimal von Firefox angefordert, wodurch PHP zweimal ausgeführt wird, ...(siehe oben).

                            So dann Danke dedlfix für die umfangreiche Hilfe.

                            MfG cruelsmith2012

                            P.S.: Lösung ist dann einfach nen <form> oder halt nur nen Link ohne Button^^

      2. Hi!

        Wie schaut es denn mit der Beachtung des Kontextwechsels aus?
        Habe nochmal drüber gekuckt daran kanns nicht liegen.

        Nein, aber das ist ein Programmierfehler, der sicherheitskritisch ist. Das hat mit deinem Problem nichts zu tun, trotzdem erwähne ich auch solche mir auffallenden Fehler.

        if (!$this->ddate == '0') {  
        

        Ein Operator reicht: $this->ddate != '0'
        ja hatte mal gelesen das !$var == 'wert' schneller sein soll als != aber das ist leider auch nicht der fehler

        Sowas kostet maximal eine unerhebliche Zeiteinheit und geht üblicherweise im Grundrauschen unter. Wenn du mit solcher Mikrooptimierung etwas gewinnen willst, braucht es meist eine sehr hohe Anzahl an Operationen, bevor man etwas zu spüren bekommt.

        Habe jetzt mal mit debug_[print_backtrace()] probiert und folgendes bekommen, als ich es zu in die Fkt. goDelete() geschrieben habe:
        #0  Blackboard->goDelete() called at [/var/www/web272/html/community/blackboard.php:207]
        #1  include(/var/www/web272/html/community/blackboard.php) called at [/var/www/web272/html/index.php:81]

        Das ist kein PHP-Code, also bringt es auch nichts, es für dieses Forum als solchen zu kennzeichnen.

        So warum wird die Fkt. jetzt einmal in meiner blackboard.php ausgeführt und dann nochmal bei der index.php wenn ich die blackboard.php include?

        Das ist der aktuelle Aufruf-Stack und keine History über vergangene Aufrufe. Es wurde also zunächst in index.php ein include blackboard.php ausgeführt und dort drin stand der goDelete()-Aufruf. Zu sehen sind auch die Zeilennummern, in denen die Aufrufe stehen. Noch deutlich mehr Information liefert debug_backtrace(), dessen Rückgabe du mit print_r() anzeigen lassen kannst.

        Wenn du auch mit diesem keine verdächtigen Parameterwerte siehst, dann ist der zweite Aufruf nicht in diesem Scriptaufruf erfolgt. Kontrollausgaben der strategisch wichtigen Variableninhalte und Funktionsergebnisse (mit var_dump()) können ebenfalls noch Auskunft über die Richtigkeit der Verarbeitung geben. Sollte sich herausstellen, dass alles ordnungsgemäß durchgelaufen ist, kann es nur an einem zweiten Script-Aufruf liegen, den du so nicht siehst. Deswegen erwähnte ich die Webserver-Logfiles, die die Aufrufe dokumentieren.

        Lo!