Steffen: Verrechnet

Hallo Forum,

Ab und zu verrechnet sich mein Programm dabei, ob ein User sein timout erreicht hat und wirft ihn einfach raus, ohne das er länger als $max_pause im Programm ist.
Ich habe keinen Schimmer, warum das so ist. Hat einer eine Idee?

  
$query = "update user set  
last_update = "".time()."",  
where  
Session = "".session_id()."" AND  
time_to_sec(timediff(now(), FROM_UNIXTIME(last_update)) < $maxpause) AND  
user_gesperrt = "0"  
";  
$result=mysql_query($query);  
if (($result == FALSE) || (mysql_affected_rows() < 1) )  
{  
header("Location: logout.php);  
exit;  
}  

$maxpause ist dem Programmschnipsel bekannt, daran liegts also nicht.

Grüße, Steffen

  1. Hallo Steffen,

    es ist eine gute Idee, relevanten Code zu kopieren, statt abzuschreiben.
    Ich gehe davon aus, dass Dein Produktivcode anders aussieht.

    Das da enthält viele Fehler:

    $query = "update user set
    last_update = "".time()."",
    where
    Session = "".session_id()."" AND
    time_to_sec(timediff(now(), FROM_UNIXTIME(last_update)) < $maxpause) AND
    user_gesperrt = "0"
    ";

      
    Ich korrigiere als erstes die Anführungszeichen:  
      
    ~~~php
      
    $query = "  
        UPDATE user SET  
            last_update = '" . time() . "', -- hier ist ein Komma zuviel  
        WHERE  
            Session = '" . session_id() . "'  
            AND time_to_sec(timediff(now(), FROM_UNIXTIME(last_update)) < $maxpause)  
            AND user_gesperrt = "0"  
    ";  
    
    

    Nach dieser Korrektur haben wir immer noch ein ungültiges SQL-Statement, was dazu führt, dass $result *immer* false enthalten wird.

    $result=mysql_query($query);

    Nehme ich jetzt an, dass der Komma-Fehler in Deinem Produktivcode nicht enthalten ist, so kommen wir an Deine logischen Fehler. Der folgende Code besagt:

    if (($result == FALSE) || (mysql_affected_rows() < 1) )
    {
    header("Location: logout.php);
    exit;
    }

    Wenn aus irgendeinem Grund mysql_query() fehlschlägt, was immer mal passieren kann, wird der User rausgeschmissen. Wenn keine Datensätze geändert werden, was immer mal passieren kann, wird der User rausgeschmissen. Beachte dazu den zweiten Hinweis im Handbuch zu mysql_affected_rows(), ich zitiere:

    <zitat>
        Hinweis: Benutzen Sie UPDATE wird MySQL keine Spalten aktualisieren,
        bei denen der neue dem alten Wert entpspricht. Das kann dazu führen,
        dass mysql_affected_rows()  nicht die tatsächliche Anzahl der betroffenen
        Zeilen liefert, sondern nur die, die wörtlich durch die Anfrage betroffen
        sind.
    </zitat>

    Wird das Skript zweimal innerhalb der gleichen Sekunde aufgerufen und erfolgreich abgearbeitet, so wird der Benutzer herausgeworfen.

    Freundliche Grüße

    Vinzenz

    1. Hallo Vinzenz,

      vorab vielen Dank dafür, dass Du Dich mit meinem Problem auseinandersetzt.

      Nun zu den einzelnen Punkten:

      Ich gehe davon aus, dass Dein Produktivcode anders aussieht.

      Sicher sieht er das. Ich fand es eine gute Idee, eine Essenz aus dem Code zu zitieren, gebe aber zu, dass mir dabei kleine Fehler unterlaufen sind.

      Ich korrigiere als erstes die Anführungszeichen:

      Die sind im Produktivcode einmal escaped, insofern quasi identisch zu Deiner Korrektur.

      last_update = '" . time() . "', -- hier ist ein Komma zuviel

      Klar. Hab ich vergessen, wegzunehmen. Im Produktivcode werden mehrere Spalten upgedatet, daher kommt das Komma.

      Wenn aus irgendeinem Grund mysql_query() fehlschlägt, was immer mal passieren kann,

      Ist das wahr? Ok, das hätte ich einfach nicht gedacht. Was ist hieraus die sinnvolle Konsequenz für meinen Code?

      Beachte dazu den zweiten Hinweis im Handbuch zu mysql_affected_rows(), ich zitiere:

      <zitat>
          Hinweis: Benutzen Sie UPDATE wird MySQL keine Spalten aktualisieren,
          bei denen der neue dem alten Wert entpspricht. Das kann dazu führen,
          dass mysql_affected_rows()  nicht die tatsächliche Anzahl der betroffenen
          Zeilen liefert, sondern nur die, die wörtlich durch die Anfrage betroffen
          sind.
      </zitat>

      Wird das Skript zweimal innerhalb der gleichen Sekunde aufgerufen und erfolgreich abgearbeitet, so wird der Benutzer herausgeworfen.

      Ohne den Hinweis aus der Doku gekannt zu haben, war ich mir dieser Tatsache schon bewußt. Deshalb habe ich eine Spalte mit einem unique Zufallswert, der ebenfalls innerhalb obiger Query upgedatet wird, sodaß ich dieses Problem behoben haben sollte.

      Heißt im Umkehrschluss, dass gem. Deiner Hinweise eingentlich nur noch ein Fehlschlagen der Query für einen ungewollten User-Logout in Frage kommt?

      Viele Grüße, Steffen

      1. Ich gehe davon aus, dass Dein Produktivcode anders aussieht.

        Produktivcode (gekürzt):

          
        update user set  
        last_update = "1267780817",  
        node_uz = "0.7555432001268790817"  
        where  
        Session = "46a56754..." AND  
        time_to_sec(timediff(now(), FROM_UNIXTIME(last)) < 1800) AND  
        user_gesperrt = "0"  
        
        

        Grüße, Steffen

      2. Hallo,

        Ich gehe davon aus, dass Dein Produktivcode anders aussieht.

        Sicher sieht er das. Ich fand es eine gute Idee, eine Essenz aus dem Code zu zitieren, gebe aber zu, dass mir dabei kleine Fehler unterlaufen sind.

        Es ist keine gute Idee, Code zu posten, der fehlerhaft ist.
        Es ist keine gute Idee, Code zu posten, der bereits auf den ersten Blick Möglichkeiten für das beschriebene Problem aufweist, die im Produktionscode nicht vorhanden sind.

        Ich korrigiere als erstes die Anführungszeichen:
        Die sind im Produktivcode einmal escaped, insofern quasi identisch zu Deiner Korrektur.

        Doppelte Anführungszeichen für Zeichenkettenliterale in SQL-Anweisungen sind in aller Regel keine gute Idee. Einfache Anführungszeichen werden immer akzeptiert, doppelte nur von wenigen DBMS und auch nur in bestimmter Konfiguration. Zusätzlich ist es viel angenehmer, keine Escape-Orgien feiern zu müssen.

        Eine gute Idee ist es, sprintf() zu verwenden, um sich die ständigen Zeichenkettenunterbrechungen und -verkettungen zu ersparen. Ich persönlich benötige Leerzeichen vor und nach den Operatoren, sonst kann ich Code nicht lesen.

        last_update = '" . time() . "', -- hier ist ein Komma zuviel
        Klar. Hab ich vergessen, wegzunehmen. Im Produktivcode werden mehrere Spalten upgedatet, daher kommt das Komma.

        Ja eben. Der gepostete Code führt garantiert zu einem Fehlschlagen von mysql_query() wegen eines SQL-Syntaxfehlers. Auf diesen muss ich hinweisen - *ich* weiß schließlich nicht, wie der Code im Original aussieht. Wenn man kürzt, dann muss man sorgfältig kürzen.

        Wenn aus irgendeinem Grund mysql_query() fehlschlägt, was immer mal passieren kann,
        Ist das wahr? Ok, das hätte ich einfach nicht gedacht. Was ist hieraus die sinnvolle Konsequenz für meinen Code?

        das, was man nach mysql_query() *immer* tun sollte: eine Fehlerbehandlung durchführen. Nachschauen, was schiefgegangen ist und auf jeden Fall ins Anwendungsfehlerprotokoll schreiben. mysql_error() hilft dabei. Beim Entwickeln kannst Du die Fehlermeldung ausgeben - in der Produktion hat die Browserausgabe von mysql_error()-Meldungen nichts verloren (auch wenn man's häufig sieht).

        Ohne den Hinweis aus der Doku gekannt zu haben, war ich mir dieser Tatsache schon bewußt. Deshalb habe ich eine Spalte mit einem unique Zufallswert, der ebenfalls innerhalb obiger Query upgedatet wird, sodaß ich dieses Problem behoben haben sollte.

        Was heißt unique-Zufallswert? Wie sieht das aus? Kann es nicht sein, dass das UPDATE-Statement zufällig den gleichen Wert liefert?

        Woher soll ich wissen, dass Du das weißt? Es ist ein offensichtlicher Fehler, ein Fehler, den ich schon oft gesehen habe.

        Heißt im Umkehrschluss, dass gem. Deiner Hinweise eingentlich nur noch ein Fehlschlagen der Query für einen ungewollten User-Logout in Frage kommt?

        Protokolliere die SQL-Statements und protokolliere die MySQL-Fehlermeldungen

        Ach so: Selbstverständlich halte ich es für einen Designfehler, in einer DB-Tabelle für Zeitstempel Integerwerte zu verwenden statt des angemessenen Datentyps TIMESTAMP. Du hast es viel leichter beim Vergleich und kannst die eingebaute Magie dieses Datentyps nutzen.

        Was könnte noch schiefgehen: die Session könnte beendet werden, weil in einer Shared-Hosting-Umgebung ein Fremdaufräumen passieren kann, siehe dazu </archiv/2010/2/t195076/#m1305347>ff.

        Freundliche Grüße

        Vinzenz

        1. Hi!

          Ich korrigiere als erstes die Anführungszeichen:
          Die sind im Produktivcode einmal escaped, insofern quasi identisch zu Deiner Korrektur.
          Doppelte Anführungszeichen für Zeichenkettenliterale in SQL-Anweisungen sind in aller Regel keine gute Idee.

          Kleine Anmerkung. Das sind keine doppelten Anführungszeichen im SQL-Sinne sondern ein im Original wohl maskiertes " und ein Zeichenkettenende-" von PHP.

          Ach so: Selbstverständlich halte ich es für einen Designfehler, in einer DB-Tabelle für Zeitstempel Integerwerte zu verwenden statt des angemessenen Datentyps TIMESTAMP. Du hast es viel leichter beim Vergleich und kannst die eingebaute Magie dieses Datentyps nutzen.

          Genau, dann kämen nämlich auch solche Konstrukte mit weniger Code aus:

          time_to_sec(timediff(now(), FROM_UNIXTIME(last_update)) < $maxpause)

          Es ist außerdem immer eine gute Idee, den Vergleichswert auszurechnen und diesen mit einem Spaltenwert zu vergleichen, denn dann kann das DBMS einen eventuell vorhandenen Index auf der Spalte verwenden, als aus einem Spaltenwert etwas zu berechnen und das zu vergleichen, denn diese Berechnung muss für jeden Wert der Spalte einzeln durchgeführt werden.

          In dem Fall wäre also aus NOW() - $maxpause ein neuer Zeitpunkt zu ermitteln, und last_update (das als echter TIMESTAMP oder DATETIME vorliegt) damit zu vergleichen: last_update > NOW() - INTERVAL $maxpause SECOND

          Lo!

          1. Hi dedlfix,

            Kleine Anmerkung. Das sind keine doppelten Anführungszeichen im SQL-Sinne sondern ein im Original wohl maskiertes " und ein Zeichenkettenende-" von PHP.

            Jipo. So ist es.

            Ach so: Selbstverständlich halte ich es für einen Designfehler...

            Ihr habt ja Recht. Also habe ich es auch inzwischen so umgesetzt.

              
            update user set  
            last = now(),  
            node_uz = "0.82034500 1267803801"  
            where  
            Session = "7e16..." AND  
            last > NOW() - INTERVAL 3600 SECOND AND  
            user_gesperrt = "0";  
              
            $result=mysql_query($query);  
            if ($result==FALSE)  
                     {  
            	die("Fehler");  
            	 }  
              
            if  (mysql_affected_rows() < 1)  
            {  
            header("Location: logout.php");  
            exit;  
            }  
            
            

            Ich hoffe, die Halbwertszeit dieses Codes ist etwas höher als die des Vorangegangenen. ;-)

            Und ich bedanke mich bei Euch Beiden und hoffe auf eine Antwort der beiden übrigen Fragen in meiner Antwort an Vinzenz.

            Klasse Forum und Ihr Beiden helft wirklich enorm weiter. Und das, obwohl Du mir ja den Code quasi 1:1 gegeben hast. Das hat im Nachgang der Geschichte aber die Konsequenz, dass ich mich im Anschluss an dieses Post sehr intensiv mit den Datum/Zeit-Funktionen von mysql befassen werde. Einmal umgestellt, ist umgestellt. Jetzt hat mich das Thema auch ergriffen, bis dato stand es immer nur auf meiner ToDo-Liste. Danke!

            Grüße, Steffen

            1. Hallo Steffen,

              Ihr habt ja Recht. Also habe ich es auch inzwischen so umgesetzt.
              Ich hoffe, die Halbwertszeit dieses Codes ist etwas höher als die des Vorangegangenen. ;-)

              mal schauen: die Spalte last ist diejenige, die von der möglichen Magie des TIMESTAMP-Datentyps am besten profitiere kann, ich rede von

              DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

              Eigenschaften, die die Spalte vielleicht sogar schon hat (durch eingebaute Magie, die dort ebenfalls erläutert ist).

              update user set
              last = now(),
              node_uz = "0.82034500 1267803801"
              where
              Session = "7e16..." AND
              last > NOW() - INTERVAL 3600 SECOND AND
              user_gesperrt = "0";

              Du kannst Dir somit das explizite Updaten der Spalte sparen. Mit meinem anderen Vorschlag wären wir bei

              [code lang=sql]UPDATE user SET
                  node_uz = NOT node_uz
              WHERE
                  Session = '7e16...' AND
                  last > NOW() - INTERVAL 3600 SECOND AND
                  user_gesperrt = '0';

                
              
              > $result=mysql\_query($query);  
              > if ($result==FALSE)  
              >          {  
              > 	die("Fehler");  
                
              Wie war's noch. die() ist keine Fehlerbehandlung, siehe auch [Zitat 1282](http://community.de.selfhtml.org/zitatesammlung/zitat1282).  
                
              Protokolliere Fehler und MySQL-Fehlermeldung, etwa in der Art  
                  add\_protocol($query, mysql\_error());  
                  // und einer selbstgeschriebenen Protokollierfunktion  
                
                  // Überlege, was Du weiter tun willst.  
              
              > 	 }  
              >   
              > if  (mysql\_affected\_rows() < 1)  
              > {  
                
              // Anmerkung: Auch wenn man das sehr häufig sieht, ist es fehlerbehaftet:  
              
              > header("Location: logout.php");  
                
              // [der Location-Header möchte eine absolute URI haben](/archiv/2009/1/t182063/#m1204546).  
              // Mach's richtig. Ist ja kein Problem.  
                
              
              > exit;  
              > }  
              > [/code]  
                
              
              > Und ich bedanke mich bei Euch Beiden  
                
              Sowas kommt immer gut an.  
                
                
              Freundliche Grüße  
                
              Vinzenz
              
              1. Hallo Vinzenz,

                ich rede von

                DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

                Danach hatte ich auch schon gesucht, aber im Zusammenhang mit DateTime hätte ich da wohl lange suchen können. Mit "timestamp" wird ein Schuh draus.
                Was ist denn eigentlich der Vorteil, außer dass ich es nicht mehr manuell eintragen muß? Das könnte ja auch mal so gewollt sein?

                Du kannst Dir somit das explizite Updaten der Spalte sparen. Mit meinem anderen Vorschlag wären wir bei...

                Bin Dir gefolgt. ;-)

                Protokolliere Fehler und MySQL-Fehlermeldung, etwa in der Art
                    add_protocol($query, mysql_error());
                    // und einer selbstgeschriebenen Protokollierfunktion

                Kein Problem...wenn da nicht die Query wäre. Aber ich hab ne Idee, ich behandel die Query vor dem Eintrag in die db einfach mit rawurlencode, dann sollte es passen.

                // Anmerkung: Auch wenn man das sehr häufig sieht, ist es fehlerbehaftet:

                header("Location: logout.php");

                Ich weiß, dass ich das nicht ganz richtig verwende. Einzig, ich weiß nicht, ob ich als (oder in der) absolute(n) URL auch die php Umgebungsvariablen verwenden darf?

                Und ich bedanke mich bei Euch Beiden

                Sowas kommt immer gut an.

                Ist doch das Mindeste, was ein Fragender für den Erhalt so viel Wissens und für die Mühe bei der Vermittlung Selbigens mal sagen darf.

                Also immer wieder gerne: Danke!

                Gruß, Steffen

                1. Hi,

                  // Anmerkung: Auch wenn man das sehr häufig sieht, ist es fehlerbehaftet:

                  header("Location: logout.php");

                  Ich weiß, dass ich das nicht ganz richtig verwende. Einzig, ich weiß nicht, ob ich als (oder in der) absolute(n) URL auch die php Umgebungsvariablen verwenden darf?

                  Du darfst alles das verwenden, was garantiert einen an dieser Stelle erlaubten Wert ergibt.

                  MfG ChrisB

                  --
                  “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
                  1. Du darfst alles das verwenden, was garantiert einen an dieser Stelle erlaubten Wert ergibt.

                    Hi Chris,

                    ah, prima. Na dann ist es wirklich problemlos, absolute URLs zu verwenden.

                    Danke für den Hinweis, Steffen

        2. Hallo,

          Hallo,

          Doppelte Anführungszeichen für Zeichenkettenliterale in SQL-Anweisungen sind in aller Regel keine gute Idee. Einfache Anführungszeichen werden immer akzeptiert, doppelte nur von wenigen DBMS und auch nur in bestimmter Konfiguration. Zusätzlich ist es viel angenehmer, keine Escape-Orgien feiern zu müssen.

          Wieder was gelernt.

          Eine gute Idee ist es, sprintf() zu verwenden, um sich die ständigen Zeichenkettenunterbrechungen und -verkettungen zu ersparen.

          Verstehe nicht ganz, was Du meinst. Erklärst Du mir das mal?

          Ich persönlich benötige Leerzeichen vor und nach den Operatoren, sonst kann ich Code nicht lesen.

          das, was man nach mysql_query() *immer* tun sollte: eine Fehlerbehandlung durchführen. Nachschauen, was schiefgegangen ist und auf jeden Fall ins Anwendungsfehlerprotokoll schreiben.

          Genau das mache ich auch. Aber ich werde nicht immer schlau daraus. Ich schreibe ins Fehlerprotokoll, bei welchem Seitenaufruf ein Fehler passiert ist. Leider fehlt mir dann aber die Query, bei der es passierte. Bisher ist es mir nicht gelungen, die Query an die Funktion zu übergeben, damit auch die eingetragen wird. Jeder Versuch endete damit, dass die Eintrag-Query einen Fehler verursachte, wenn sie die "Fehlerquery" einzutragen versucht hat.

          mysql_error() hilft dabei. Beim Entwickeln kannst Du die Fehlermeldung ausgeben - in der Produktion hat die Browserausgabe von mysql_error()-Meldungen nichts verloren (auch wenn man's häufig sieht).

          Auch so eine Geschichte. Ich mache das weitestgehend so, wie Du schreibst. Im Produktivbetrieb gebe ich keine mysql_error()-Fehlermeldungen, sondern nur eigene fehlermeldungen aus.
          Leider habe ich noch keine gute Möglichkeit des schnellen Umschaltens zwischen Testbetrieb und Produktionsbetrieb gefunden (aber auch noch nicht wirklich danach gesucht).

          Was heißt unique-Zufallswert? Wie sieht das aus? Kann es nicht sein, dass das UPDATE-Statement zufällig den gleichen Wert liefert?

          Ich glaube, nicht.
          unique-Zufallswert heißt, dass ich eigens einen Wert bestimme, der ganz sicher ein anderer ist, als der bereits in der Spalte eingetragene.
          Klar, ich könnte die von php mitgelieferte Unique-ID nehmen, aber ich hatte hierfür schon eine Funktion, nämlich microtime().

          Woher soll ich wissen, dass Du das weißt? Es ist ein offensichtlicher Fehler, ein Fehler, den ich schon oft gesehen habe.

          Ich bin Dir doch auch dankbar für den hinweis, aber es muss doch erlaubt sein, darauf hinzuweisen, dass man dieses Problem schon eliminiert hat?

          Protokolliere die SQL-Statements und protokolliere die MySQL-Fehlermeldungen

          Wenn Du mir hierfür eine gute Arbeitsanleitung selber oder verlinkst geben kannst, wäre ich super dankbar! Das wäre wirklich ein Quantensprung für mich, denn bisher mache ich das zwar, aber es hilft mir nur bedingt, weil nur der Seitenaufruf mit Parametern gespeichert wird und das reicht nicht immer, um auch den Fehler zu finden.

          Ach so: Selbstverständlich halte ich es für einen Designfehler, in einer DB-Tabelle für Zeitstempel Integerwerte zu verwenden statt des angemessenen Datentyps TIMESTAMP. Du hast es viel leichter beim Vergleich und kannst die eingebaute Magie dieses Datentyps nutzen.

          Natürlich. Steht schon auf meiner ToDo-Liste.

          Was könnte noch schiefgehen: die Session könnte beendet werden, weil in einer Shared-Hosting-Umgebung ein Fremdaufräumen passieren kann, siehe dazu </archiv/2010/2/t195076/#m1305347>ff.

          Ok. Habe ich bisher keine Probleme mit gehabt. Werde ich aber mal im Hinterkopf behalten.

          Grüße, Steffen

          1. Hallo,

            Eine gute Idee ist es, sprintf() zu verwenden, um sich die ständigen Zeichenkettenunterbrechungen und -verkettungen zu ersparen.

            Verstehe nicht ganz, was Du meinst. Erklärst Du mir das mal?

            dedlfix hat geahnt, dass Du das fragst und deswegen das hübsch aufbereitet zusammengefasst ;-)

            das, was man nach mysql_query() *immer* tun sollte: eine Fehlerbehandlung durchführen. Nachschauen, was schiefgegangen ist und auf jeden Fall ins Anwendungsfehlerprotokoll schreiben.

            Genau das mache ich auch. Aber ich werde nicht immer schlau daraus. Ich schreibe ins Fehlerprotokoll, bei welchem Seitenaufruf ein Fehler passiert ist. Leider fehlt mir dann aber die Query, bei der es passierte. Bisher ist es mir nicht gelungen, die Query an die Funktion zu übergeben, damit auch die eingetragen wird. Jeder Versuch endete damit, dass die Eintrag-Query einen Fehler verursachte, wenn sie die "Fehlerquery" einzutragen versucht hat.

            Das hört sich danach an, dass Du Dein Fehlerprotokoll in der DB abspeicherst. Ich dachte an ein normales Protokoll in Textdateiform, dass auch dann zur Verfügung steht, wenn DB-Zugriffe gerade nicht möglich sind.

            Auch so eine Geschichte. Ich mache das weitestgehend so, wie Du schreibst. Im Produktivbetrieb gebe ich keine mysql_error()-Fehlermeldungen, sondern nur eigene fehlermeldungen aus.
            Leider habe ich noch keine gute Möglichkeit des schnellen Umschaltens zwischen Testbetrieb und Produktionsbetrieb gefunden (aber auch noch nicht wirklich danach gesucht).

            im Testbetrieb die Ausgaben wirklich nur für Debug-Zwecke nutzen. Du solltest Dir ohnehin eine sinnvolle Fehlerbehandlungsstrategie überlegen und nicht - wie oft gesehen - einfach mit

            or die(mysql_error());

            das Skript sterben lassen. Überlege Dir, was Du an der betreffenden Stelle tun kannst. In vielen Fällen wirst Du dem Benutzer eine Trostnachricht ausgeben wollen. In manchen Fällen könnte es sinnvoll sein, nach einer gewissen Wartezeit das Statement erneut zu senden ...

            Was heißt unique-Zufallswert? Wie sieht das aus? Kann es nicht sein, dass das UPDATE-Statement zufällig den gleichen Wert liefert?

            Ich glaube, nicht.

            Glauben heißt nicht wissen.

            unique-Zufallswert heißt, dass ich eigens einen Wert bestimme, der ganz sicher ein anderer ist, als der bereits in der Spalte eingetragene.
            Klar, ich könnte die von php mitgelieferte Unique-ID nehmen, aber ich hatte hierfür schon eine Funktion, nämlich microtime().

            liefert einen deterministischen Wert, der durchaus mal gleich sein könnte :-) Wenn das Feld jedoch wirklich nur dazu dient, auf jeden Fall eine UPDATE-Operation zu erzwingen (und sonst keine Bedeutung hat), nähme ich

            SET spezialspalte = NOT spezialspalte

            für eine Spalte mit einem boolschen Wert und der Eigenschaft NOT NULL.

            Woher soll ich wissen, dass Du das weißt? Es ist ein offensichtlicher Fehler, ein Fehler, den ich schon oft gesehen habe.

            Ich bin Dir doch auch dankbar für den hinweis, aber es muss doch erlaubt sein, darauf hinzuweisen, dass man dieses Problem schon eliminiert hat?

            Ich wollte Dir damit klarmachen, dass der potentielle Helfer nicht über *Dein* Wissen verfügt, sondern sich nur auf das beziehen kann, was in Deiner Fragestellung steht. In vielen Fällen ergänzt durch Erfahrungswerte, ja und manchmal auch durch Intuition, wir bezeichnen dies auch gern als "Glaskugel benutzen".

            Deswegen ist es für beide Seiten gut, wenn der Fragesteller das Problem auf das richtige Maß reduziert und lieber etwas zu wenig als etwas zu viel kürzt. Und natürlich etwas zum Umfeld schreibt und das, was er bereits versucht hat - eben das, was in den Tipps für Fragende der Charta dieses Forums steht. Tipps für Antwortende gibt's übrigens auch. Ja, manchmal wünsche ich mir nach einer (nicht gerade gelungenen) Antwort, ich hätte diese beherzigt :-)

            Steht schon auf meiner ToDo-Liste.

            Zu Deiner Todo-Liste möchte ich noch etwas hinzufügen:
            Für neue PHP-Skripte mit MySQL-Zugriff empfehle ich Dir die Verwendung der leistungsfähigeren und von MySQL empfohlenen mysqli-Erweiterung, siehe dazu auch die Feature-Vergleichstabelle am Ende der Handbuchseite Überblick über die mysqli-Erweiterung.

            Freundliche Grüße

            Vinzenz

            1. Hallo Vinzenz,

              dedlfix hat geahnt, dass Du das fragst und deswegen das hübsch aufbereitet zusammengefasst ;-)

              Ich sach ja, Ihr Beide helft enorm (vgl. meine Antwort an dedlfix) ;-)

              Das hört sich danach an, dass Du Dein Fehlerprotokoll in der DB abspeicherst. Ich dachte an ein normales Protokoll in Textdateiform, dass auch dann zur Verfügung steht, wenn DB-Zugriffe gerade nicht möglich sind.

              Ach? Ich hätte jetzt wirklich gedacht, dass das Speichern in eine Datei bei jedem mysql-Statement viel zu performancelastig ist?

              Überlege Dir, was Du an der betreffenden Stelle tun kannst. In vielen Fällen wirst Du dem Benutzer eine Trostnachricht ausgeben wollen. In manchen Fällen könnte es sinnvoll sein, nach einer gewissen Wartezeit das Statement erneut zu senden ...

              Ich gebe Trostmeldungen aus. Und zwar solche, die für eventuelle Hacker, wie für meine User und leider auch mich selber eher nichtssagend sind.

              Wenn das Feld jedoch wirklich nur dazu dient, auf jeden Fall eine UPDATE-Operation zu erzwingen (und sonst keine Bedeutung hat), nähme ich

              SET spezialspalte = NOT spezialspalte

              für eine Spalte mit einem boolschen Wert und der Eigenschaft NOT NULL.

              Klasse Idee! (wieder was gelernt) Hab ich in Ermangelung wirklicher mysql-Boolwerte mit tinyint Länge 1 umgesetzt. Und mysql ist tatsächlich (anscheinend) bequem genug, wirklich zwischen 0 und 1 zu variieren, obwohl es ja weitere werte zur Verfügung hätte.

              Ich wollte Dir damit klarmachen, dass der potentielle Helfer nicht über *Dein* Wissen verfügt, sondern ...

              Schon klar. Vermutlich wollte ich auch nur darauf hinweisen, an welch tolle Dinge ich dann auch selber schon gedacht hatte. War wohl ein klein wenig Eigenlob meinserseits.

              Steht schon auf meiner ToDo-Liste.

              Zu Deiner Todo-Liste möchte ich noch etwas hinzufügen:
              Für neue PHP-Skripte mit MySQL-Zugriff empfehle ich Dir die Verwendung der leistungsfähigeren und von MySQL empfohlenen mysqli-Erweiterung,

              Oje, jetzt entlavrst Du mich auch noch als Doppeluser, denn das hier hat "ein guter Kumpel" für mich gepostet *hust* ;-)

              So schließt sich dann wohl der Kreis. Hoffe, das verstößt nicht komplett gegen die Nettiquette hier?

              Jedenfalls vielen Dank für Deine sinnvolle Hilfe, bin ich wirklich froh und dankbar für!

              Grüße, Steffen

              1. Hi!

                Überlege Dir, was Du an der betreffenden Stelle tun kannst. In vielen Fällen wirst Du dem Benutzer eine Trostnachricht ausgeben wollen. In manchen Fällen könnte es sinnvoll sein, nach einer gewissen Wartezeit das Statement erneut zu senden ...
                Ich gebe Trostmeldungen aus. Und zwar solche, die für eventuelle Hacker, wie für meine User und leider auch mich selber eher nichtssagend sind.

                Geh mal zwei Schritte vor und dreh dich dann um. Nun müsstest du eine Sicht haben, wie sie deine Benutzer/Kunden haben. :-) Und nun kommst du vermutlich besser auf Ideen, was für die Anwender nützlich sein könnte. Ein Kunde beispielsweise will vielleicht was bestellen - Datenbank grad kaputt - Bestellvorgang abgebrochen - Konkurrenz besucht - dort gekauft. Das muss ja nicht sein. Wie kann der Bestellvorgang doch noch erfolgreich abgewickelt werden? Per E-Mail vielleicht?

                Auf jeden Fall ist es nützlich, als Administrator eines Systems über Fehler informiert zu werden. In eine Logdatei zu schreiben ist eine Sache, sie regelmäßig aufzusuchen, besonders wenn sie langweiligerweise über längere Zeit keine neuen Einträge erhält, eine andere. E-Mail liest man sicherlich sowieso jeden Tag mindestens einmal, also bietet sich an, sich darüber über Fehler zu informieren zu lassen.

                Lo!

  2. Hello,

    Ab und zu verrechnet sich mein Programm dabei, ob ein User sein timout erreicht hat und wirft ihn einfach raus, ohne das er länger als $max_pause im Programm ist.
    Ich habe keinen Schimmer, warum das so ist. Hat einer eine Idee?

    Existiert denn die Sessiondatei überhaupt noch, wenn dein Programm darauf zugreifen will bzw. daraus etwas ableiten will?

    Die physikalische Sessiondatei muss selbstverstänlich länger leben, als dies im Programm maximal logisch genutzt werden soll.

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. Existiert denn die Sessiondatei überhaupt noch, wenn dein Programm darauf zugreifen will bzw. daraus etwas ableiten will?

      Die physikalische Sessiondatei muss selbstverstänlich länger leben, als dies im Programm maximal logisch genutzt werden soll.

      Hallo Tom,

      guter Hinweis. Werde ich im Hinterkopf behalten. Vinzenz hatte ja auch einen Link für mich mit ähnlichem Inhalt.

      Doofe Frage, aber wo wird die Sessiondatei eigentlich genau gespeichert?

      Grüße, Steffen

      1. Hi,

        Doofe Frage, aber wo wird die Sessiondatei eigentlich genau gespeichert?

        http://www.php.net/manual/en/session.configuration.php#ini.session.save-path

        MfG ChrisB

        --
        “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
        1. http://www.php.net/manual/en/session.configuration.php#ini.session.save-path

          Ok. Hab mir schon gedacht. Da, wo der Provider es lt. php.ini eingestellt hat.

          Danke, Steffen