dedlfix: race-condition-Nachfrage

Beitrag lesen

echo $begrüßung;

$fp = fopen ('counter.txt', 'r+');

if (!is_resource ($fp)) {
  die ('Konnte die Datei nicht öffnen!');
}
if (!flock ($fp, LOCK_EX)) {
  die ('Sperren der Datei fehlgeschlagen!');
}


>   
> Wie kann ich die Fehlerausgaben vermeiden?  
  
Zum einen solltest du die Fehlerbehandlung nicht wie im Beispiel mit dem quick'n'dirty-die() durchführen.  
  

> Damit kann ein Benutzer sowieso nichts anfangen und für ihn soll das Script ja weiterlaufen.  
  
Genau aus dem Grund. Überlege dir stets, welche Ursachen ein Fehler habe kann und was man dagegen unternehmen kann, um ihn zu vermeiden. Da das nicht immer geht, überleg dir, was für deinen Anwendungsfall die beste Reaktion ist - und zwar aus Systemverwaltersicht als auch aus Anwendersicht.  
  
Wenn das Öffnen nicht klappt, hast du ein grundsätzliches Problem, das du mit Programmierung kaum behoben bekommst. Wenn deine Login-Datei nicht verfügbar ist, ist das einem Totalausfall deines Angebots gleichzusetzen. Können die Anwenderinformationen an anderer Stelle abgeglichen werden? Gibt es eine Sicherungskopie, die man wenigstens lesend auswerten kann? In selbige zu schreiben halte ich für keine gute Idee, denn dann läuft die Datenhaltung auseinander.  
  
Informiere dich, wie die Sperre funktioniert. Was passiert mit einem Zugriffsversuch, wenn gerade eine andere Sperre aktiv ist? (Ich weiß das nicht, diese Problematik war bei mir noch nicht relevant.) Wartet flock() ewig oder bis zu einem Timeout oder kommt es sofort zurück? Wenn es sofort zurückkommt, kannst du warten und es noch einmal (oder öfter) probieren. Das hat den Nachteil, dass du jedes Mal wieder auf eine neue Sperre stoßen kannst, wenn das System entsprechend ausgelastet ist. (Ohne (u)sleep() solltest du die Warteschleife nicht betreiben, das belastet nur unnötig den Prozessor.) Besser ist Anfordern mit Warten auf die Freigabe (was wohl das normale Verhalten ist). Welche Ursachen kann es dann haben, dass flock() unverrichteter Dinge zurückkommt? Ich finde keine Erwähnung eines konfigurierbaren Timeouts im PHP-Handbuch.  
  
Soweit meine Gedanken zu dem Thema. Nimm sie als Denkanstöße und versuche die Antworten zu ermitteln.  
  

> Dann benutze ich ja fopen() gar nicht zum lesen. Wie schon gesagt, hatte ich das eigentlich mit include() gemacht. Jetzt lade ich eine reine XML-Datei mit simplexml\_load\_file(). Muss ich also fopen() davor setzen und funktioniert simplexml\_load\_file() dann überhaupt noch?  
  
SimpleXML bietet nichts zum Locking an. Ob es sich an eine anderswo mit flock() gesetzte Sperre hält, ist dem Handbuch nicht zu entnehmen. Wenn du eigenes Locking verwenden willst, kannst du anschließend simplexml\_load\_string() nehmen. Du kannst dann aber die Datei im Ganzen lesen. file\_get\_contents() kennt Locking.  
  
  
Eine Benutzerverwaltung mit XML würde ich auch bei wenigen Benutzern nur sehr ungern verwenden. Kannst du nicht SQLite oder ein anderes DBMS verwenden? Oder willst du unbedingt mit der Dateisperrproblematik Erfahrung sammeln? :-)  
  
  
echo "$verabschiedung $name";