Tom: Sequentielle Weiterleitung (a, b, c, a, b, c, a, b, c, ...)

Beitrag lesen

Hello,

Der nächste Besucher bekommt die nächste Zahl.

$file = "./counter.txt";

list( $counter ) = @file( $file );
  $counter++;

if ( $counter > 3 ) $counter = 0;

$out = fopen( $file, "w" ); // w = write (zum Schreiben oeffnen
  if ( $out ) {
    fwrite( $out, $counter );
    fclose( $out );
  }

  
Es ist ganz ungünstig, füe einen Prozess, der als atomarer Prozess gebunden werden müsste, zwei unabhängige Handles zu benutzen. Und an das handle von file() kommt man noch nicht einnmal heran, da file() nach außen als namensbasierte Funktion arbeitet.  
  
Dieser Code schafft ein TOCTOU-Problem (Race-Condition nicht abgefangen) und ist daher unbrauchbar.  
<http://en.wikipedia.org/wiki/Time-of-check-to-time-of-use>  
<http://www.owasp.org/index.php/File_Access_Race_Condition:_TOCTOU>  
<http://en.wikipedia.org/wiki/Race_condition>  
  
~~~php
  
  $file = "./counter.txt";    ## muss vorhanden sein!  
  
function counter($file)  
{  
  $fh = fopen($file, 'rb+');  
  if (!$fh) return false;     ## Datei konnte nicht geöffnet werden, -> Ende im Gelände  
  if (!flock($fh, LOCK_EX)    ## Datei konnte nicht exclusiv gesperrt werden  
  {  
      fclose($fh);            ## Datei schließen  
      return false;           ## -> Ende im Gelände  
  }  
  
  $line = fgets($fh);         ## eine _Textzeile_ aus der Datei holen mit Default-Länge  
  $count = intval($line);     ## wir wandeln das Gelesene in eine numerische Größe (ganez Zahl) um  
  $count++;                   ## und erhöhen den Wert um 1  
  
  if ( $count > 3 ) $count = 0;  ## Wenn 0,1,2,3 abgearbeitet wurden, kommt wieder 0  
  
  fseek($fh, 0, SEEK_SET);    ## Dateizeiger wieder auf Anfang zurück  
  
  fwrite($fh, $count);        ## Den Counterwert in die Datei zurückschreiben  
  ftruncate($fh, ftell($fh)); ## Die Datei an der Stelle abschneiden, an der der  
                              ## Dateizeiger gerade steht (er steht auf der nächsten Byteposition,  
                              ## daher ist die Länge gerade der Byteposition. Die Positionszählung  
                              ## beginnt bei 0)  
  fclose($fh);                ## Datei schließen und Lock freigeben  
  
  return $count;              ## Den Counterwert zurückgeben  
}  

Die Anzahl, wann rückzusetzen wäre, könntest Du der Funktion ebenfalls als Argument übergeben

Liebe Grüße aus dem schönen Oberharz

Tom vom Berg

--
Nur selber lernen macht schlau
http://bergpost.annerschbarrich.de
Den obligatorischen (Ab-)Satz mit Uschi und Wolle verkneife ich mir diesmal